AOP

AOP与OOP

  • OOP:面向对象编程。关注于数据和行为的封装,通过类和对象来组织代码。用于构建系统的主体结构,定义数据结构和操作这些数据的方法。

  • AOP:面向切面编程。专注于将横切关注点(如日志记录、事务管理、安全性等)与业务逻辑分离,从而提高模块化和代码重用。通常用于处理那些在多个对象或类中重复出现的逻辑,如日志记录、性能统计、事务管理等。

代理模式回顾

编写代码的原则之二:
职责清晰:一个类只负责一件事;
易于测试:一次只测一个功能。

代理(Proxy)通过封装一个已有接口,并向调用方返回相同的接口类型,能让调用方在不改变任何代码的前提下增强某些功能(例如,鉴权、延迟加载、连接池复用等)。AOP本质上只是一种代理模式的实现方式

代理示例代码
public class AProxy implements A {
    private A a;
    public AProxy(A a) {
        this.a = a;
    }
    public void a() {
    if (getCurrentUser().isRoot()) {
        this.a.a();
    } else {
        throw new SecurityException("Forbidden");
    }
}
}

通过代理可以获得更清晰,更简洁的代码

  • A接口:只定义接口;

  • ABusiness类:只实现A接口的业务逻辑;

  • APermissionProxy类:只实现A接口的权限检查代理。

Java中的AOP织入方式

  • 编译期:在编译时,由编译器把切面调用编译进字节码,这种方式需要定义新的关键字并扩展编译器,AspectJ就扩展了Java编译器,使用关键字aspect来实现织入;

  • 类加载器:在目标类被装载到JVM时,通过一个特殊的类加载器,对目标类的字节码重新“增强”;

  • 运行期:目标对象和切面都是普通Java类,通过JVM的动态代理功能或者第三方库实现运行期动态织入。(Spring的AOP实现就是基于JVM的动态代理)

AOP常见概念

  • Aspect:切面,即一个横跨多个核心逻辑的功能,或者称之为系统关注点;

  • Joinpoint:连接点,即定义在应用程序流程的何处插入切面的执行;

  • Pointcut:切入点,即一组连接点的集合;

  • Advice:增强,指特定连接点上执行的动作;

  • Introduction:引介,指为一个已有的Java对象动态地增加新的接口;

  • Weaving:织入,指将切面整合到程序的执行流程中;

  • Interceptor:拦截器,是一种实现增强的方式;

  • Target Object:目标对象,即真正执行业务的核心逻辑对象;

  • AOP Proxy:AOP代理,是客户端持有的增强后的对象引用。

使用AspectJ实现AOP

引入依赖

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
            <version>6.1.9</version>
        </dependency>

创建一个类并定义执行方法

@Aspect
@Component
public class LoggingAspect {
    @Before("execution(public * com.zyj.service.UserService.*(..))")
    public void doAccessCheck() {
        System.err.println("[Before] do access check...");
    }

    // 在执行MailService的每个方法前后执行:
    @Around("execution(public * com.zyj.service.MailService.*(..))")
    public Object doLogging(ProceedingJoinPoint pjp) throws Throwable {
        System.err.println("[Around] start " + pjp.getSignature());
        Object retVal = pjp.proceed();
        System.err.println("[Around] done " + pjp.getSignature());
        return retVal;
    }
}

给配置类加上@EnableAspectJAutoProxy注解

通过这个注解,Spring的IoC容器会自动查找带有@Aspect的Bean,然后根据每个方法的@Before、@Around等注解把AOP注入到特定的Bean中。

使用注解装配AOP

使用AspectJ实现AOP存在无区别覆盖,容易导致不恰当的覆盖范围,新增的Bean若不清楚当前装配规则容易被强迫装配
通过注解实现AOP,可以清楚的看到Bean中的哪些方法被装配了

posted @ 2024-06-23 14:37  狠狠赚一笔  阅读(107)  评论(0)    收藏  举报