Java aop面向切面编程(aspectJweaver)案例详解

Java AOP面向切面编程(AspectJ Weaver)案例详解

什么是AOP?

AOP全称Aspect-Oriented Programming,即面向切面编程。它是一种基于OOP(Object-Oriented Programming,面向对象编程)的编程思想,用于解决模块化开发中横切关注点的问题,以通过对横切关注点进行抽象,实现系统各模块之间的解耦。

AOP中的概念

  • 切面(Aspect):一个关注点的模块化,这个关注点可能会横切多个对象,切面可以应用到多个对象上。
  • 连接点(Joinpoint):程序执行过程中明确的点,通常是方法的调用。
  • 通知(Advice):在特定的连接点上执行的增强处理,有before、after、around等不同类型。
  • 切入点(Pointcut):用于定义通知(Advice)被触发的连接点。
  • 引入(Introduction):在不修改类代码的前提下,引入新的接口。

AspectJ Weaver

AspectJ是AOP思想的实现框架之一,它提供了很多AOP的解决方案,并且使用起来比较方便。AspectJ Weaver是AspectJ工具集中的一个编译器,可以将AspectJ语言编写的切面加入到Java字节码文件中,AspectJ编译器会根据AspectJ语言编写的切面来增强Java字节码文件中的目标对象。

AspectJ Weaver案例详解

下面通过两个案例来详细讲解AspectJ Weaver的使用。

示例1:记录方法执行时间

我们通过AOP来记录方法的执行时间,以方便进行性能调优。我们可以使用AspectJ Weaver来实现,代码如下:

我们首先需要导入AspectJ Weaver依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
</dependency>

然后定义一个切面(Aspect)类,用于在方法调用前和调用后记录时间:

@Aspect
@Component
public class TimeAspect {

    private static final Logger LOGGER = LoggerFactory.getLogger(TimeAspect.class);

    @Around("execution(* com.example.demo.*.*(..))")
    public Object timeAround(ProceedingJoinPoint joinPoint) throws Throwable {
        long startTime = System.currentTimeMillis();
        Object result = joinPoint.proceed();
        long endTime = System.currentTimeMillis();
        LOGGER.info("Method {} cost {}ms.", joinPoint.getSignature().getName(), endTime - startTime);
        return result;
    }
}

在上述代码中,@Aspect注解表明该类是一个切面类,@Around注解表示在目标方法执行前和执行后会执行这个方法,execution表达式代表切入点,即要拦截哪些方法。

最后,在应用程序启动时,Spring会自动将切面注入到目标对象中,最终程序执行时会在记录方法执行时间。

示例2:缓存数据

我们通过AOP来实现数据的缓存,以提升程序的执行效率。代码实现如下:

在pom.xml文件中添加如下依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
</dependency>
<dependency>
    <groupId>com.github.ben-manes.caffeine</groupId>
    <artifactId>caffeine</artifactId>
    <version>2.8.8</version>
</dependency>

然后我们定义一个缓存切面类,用于缓存数据:

@Aspect
@Component
public class CacheAspect {

    private static final Logger LOGGER = LoggerFactory.getLogger(CacheAspect.class);

    // 创建Caffeine缓存对象
    private static final Cache<String, Object> CACHE = Caffeine.newBuilder()
            .expireAfterWrite(30, TimeUnit.SECONDS)
            .maximumSize(1000)
            .build();

    @Around("execution(* com.example.demo.UserServiceImpl.find*(..))")
    public Object findUserCache(ProceedingJoinPoint joinPoint) {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String methodName = signature.getName();
        Object[] args = joinPoint.getArgs();

        // 根据方法名和参数拼接Key
        StringBuilder sb = new StringBuilder();
        sb.append(methodName);
        for (Object arg : args) {
            sb.append(arg);
        }
        String key = sb.toString();

        // 判断缓存中是否存在
        Object result = CACHE.getIfPresent(key);
        if (result != null) {
            LOGGER.info("Method from cache, method:{} key:{}", methodName, key);
            return result;
        }

        try {
            LOGGER.info("Method from db, method:{} key:{}", methodName, key);
            // 缓存中不存在,从数据库查询
            result = joinPoint.proceed();

            // 将查询结果添加到缓存中
            CACHE.put(key, result);
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }

        return result;
    }

}

在上述代码中,我们使用Caffeine缓存库创建了一个缓存对象,然后在@Around注解中定义了拦截的方法,通过方法名和参数拼接Key,判断是否存在缓存,如果存在直接返回缓存结果。如果缓存中不存在对应数据,则查询数据库并将结果添加到缓存中。

总结

通过上述示例,我们可以看到使用AspectJ Weaver进行AOP编程比较简单,可以方便地在Java类中增强逻辑。我们在实际项目中也可以灵活地应用AOP技术,提升程序效率和可维护性。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java aop面向切面编程(aspectJweaver)案例详解 - Python技术站

(0)
上一篇 2023年5月19日
下一篇 2023年5月19日

相关文章

  • Java Web中解决路径(绝对路径与相对路径)问题

    下面将详细讲解Java Web中如何解决路径问题。 什么是路径问题 Java Web开发中常常会出现路径问题,通常包括两种类型:绝对路径和相对路径。 绝对路径是指从根目录开始,一直到需要的文件或目录的路径,例如:C:\my_project\resources\file.txt。 相对路径是指相对于当前文件或项目的路径,例如:./resources/file.…

    Java 2023年5月20日
    00
  • Spring Native打包本地镜像的操作方法(无需通过Graal的maven插件buildtools)

    Spring Native是近期才发布的一个新特性,它的主要功能就是将Spring应用程序打包为本地镜像,打包完成后,我们就可以将这个本地镜像部署到不同的环境上,比如Docker、Kubernetes等。 下面是使用Spring Native打包本地镜像的具体步骤: 配置Java环境 首先需要确保已经安装了JDK11版本及以上,然后安装GraalVM相关组件…

    Java 2023年5月19日
    00
  • Java项目开发中实现分页的三种方式总结

    Java项目开发中实现分页的三种方式总结 在Java项目的开发过程中,经常需要对列表数据进行分页显示。本篇文章将总结Java项目开发中实现分页的三种方式,以供参考。 第一种方式:使用分页插件 分页插件是一种在MyBatis框架中常用的解决方案,它可以方便地实现分页功能。下面是使用MyBatis的一个示例: <!– 配置分页插件 –> <…

    Java 2023年6月16日
    00
  • Java 如何快速实现一个连接池

    实现一个连接池是一个非常基础的场景,Java中已经有很多开源框架提供了连接池的实现,比如Druid、HikariCP、C3P0等。其中,HikariCP是目前性能最快的连接池,下面我们以HikariCP为例讲解如何快速实现一个连接池。 1. 添加Maven依赖 首先,在项目的Maven pom.xml文件中添加HikariCP的依赖: <depende…

    Java 2023年5月19日
    00
  • 一文详解Java etcd的应用场景及编码实战

    一文详解Java etcd的应用场景及编码实战 什么是etcd? Etcd是一个高可用的分布式键值存储系统,由CoreOS团队开发,用于共享配置和服务发现。它的API是面向HTTP设计的,是一个强一致性和高可用的键值数据库。etcd具有以下优势: 监听功能,一旦键值发生了变化,就会被立即通知。 支持分布式部署 支持复制协议,可以自动检测和恢复失败的节点 et…

    Java 2023年5月20日
    00
  • 浅谈java对象转json,数字精确出现丢失问题

    浅谈Java对象转JSON, 数字精确出现丢失问题 在Java中,JSON序列化是一项常见的处理任务。通过将对象序列化成JSON,使得数据更容易传递和存储。但是在转换基本数据类型时,小数点精确度丢失的问题也经常出现。本文将深入探讨Java对象转JSON时数字精确出现丢失的问题,并提供解决方案。 问题描述 在Java中进行JSON序列化时,会将Java中的数字…

    Java 2023年5月26日
    00
  • 基于javaweb+jsp实现企业车辆管理系统

    下面来分享一下实现企业车辆管理系统的攻略。 1.准备工作 在开始实现之前,必须要了解相关技术和工具。具体包括: JavaSE知识:掌握JavaSE基础知识和编程技巧。 JavaWeb知识:掌握Servlet、JSP、JDBC、Tomcat 服务器等Web开发技术。 数据库技术:熟练掌握SQL语言、Oracle和MySQL等数据库的使用。 开发工具:Eclip…

    Java 2023年5月24日
    00
  • 详解Java中-classpath和路径的使用

    详解Java中-classpath和路径的使用 在Java开发中,我们经常会用到classpath和路径,本篇攻略将详细讲解这两个概念的使用方法,以及它们之间的关系。 classpath的作用 classpath是Java虚拟机(JVM)在搜索class文件时所使用的路径,它可以设置为环境变量,也可以在运行时指定。 设置classpath的环境变量 在Win…

    Java 2023年5月26日
    00
合作推广
合作推广
分享本页
返回顶部