Java Spring AOP 实现原理

本文深入探讨了SpringAOP与AspectJ这两种流行的面向切面编程技术的实现原理。详细介绍了AspectJ如何通过编译时增强实现静态代理,以及SpringAOP如何利用动态代理(包括JDK动态代理和CGLIB)为方法生成增强对象。

Spring Aop的实现原理

AOP(Aspect Orient Programming),我们一般称为面向方面(切面)编程,作为面向对象的一种补充,用于处理系统中分布于各个模块的横切关注点,比如事务管理、日志、缓存等等。AOP实现的关键在于AOP框架自动创建的AOP代理,AOP代理主要分为静态代理和动态代理,静态代理的代表为AspectJ;而动态代理则以Spring AOP为代表。本文会分别对AspectJ和Spring AOP的实现进行分析和介绍。****

使用AspectJ的编译时增强实现AOP

之前提到,AspectJ是静态代理的增强,所谓的静态代理就是AOP框架会在编译阶段生成AOP代理类,因此也称为编译时增强。

举个实例的例子来说。首先我们有一个普通的Hello类

public class Hello {
   
   
   public void sayHello() {
   
   
       System.out.println("hello");
   }

   public static void main(String[] args) {
   
   
       Hello h = new Hello();
       h.sayHello();
   }
}

使用AspectJ编写一个Aspect

public aspect TxAspect {
   
   
   void around():call(void Hello.sayHello()){
   
   
       System.out.println("开始事务 ...");
       proceed();
       System.out.println("事务结束 ...");
   }
}

这里模拟了一个事务的场景,类似于Spring的声明式事务。使用AspectJ的编译器编译

ajc -d . Hello.java TxAspect.aj

### Java Spring AOP原理详解 #### 1. AOP 核心概念 AOP(Aspect-Oriented Programming,面向切面编程)是Spring框架中的核心之一,用于在应用中实现横切关注点的分离[^1]。它补充和完善了OOP(Object-Oriented Programming,面向对象编程),允许开发者定义横向的关系,例如日志记录、事务管理等。 - **Joinpoint(连接点)**:程序执行过程中的明确点,通常是方法的调用。Spring AOP仅支持方法类型的连接点。 - **Pointcut(切入点)**:定义哪些Joinpoint将被拦截,并且可以包含条件表达式以匹配特定的方法。 - **Advice(通知)**:在特定的Joinpoint执行的动作。Spring AOP支持五种类型的通知:`Before`、`After Returning`、`After Throwing`、`After (finally)`和`Around`[^2]。 - **Aspect(切面)**:切点和通知的结合体,通常通过注解或XML配置来定义。 - **Introduction(引入)**:允许向现有的类添加新的方法或属性。 #### 2. Spring AOP实现机制 Spring AOP主要基于动态代理机制实现。根据目标类是否实现了接口,Spring会选择不同的代理方式: - 如果目标类实现了接口,则使用JDK动态代理。 - 如果目标类没有实现接口,则使用CGLIB代理。 ##### 2.1 JDK 动态代理 JDK动态代理通过`java.lang.reflect.Proxy`类实现,创建一个实现了与目标类相同接口的代理对象。代理对象会在调用目标方法时插入额外的逻辑。 ```java public class LoggingProxy implements InvocationHandler { private final Object target; public LoggingProxy(Object target) { this.target = target; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("Method " + method.getName() + " is called."); Object result = method.invoke(target, args); System.out.println("Method " + method.getName() + " has finished."); return result; } } ``` ##### 2.2 CGLIB 代理 CGLIB代理通过继承目标类并重写其方法来实现Spring在内部会自动选择合适的代理方式。 ```java public class UserServiceImpl { public void addUser(String username, String password) { System.out.println("addUser"); } } ``` 当目标类未实现接口时,Spring会使用CGLIB生成子类来代理目标类[^3]。 #### 3. AOP 的工作流程 Spring AOP的工作流程主要包括以下几个阶段: - **解析切点**:Spring容器启动时,解析XML配置或注解中的切点定义。 - **创建代理对象**:根据目标类和切点信息,动态生成代理对象。 - **织入增强**:在运行时将通知逻辑织入到目标对象的方法中。 ```xml <aop:config> <aop:aspect id="logAspect" ref="loggingService"> <aop:pointcut id="businessServiceMethods" expression="execution(* com.example.service.*.*(..))"/> <aop:before pointcut-ref="businessServiceMethods" method="beforeAdvice"/> </aop:aspect> </aop:config> ``` 上述XML配置定义了一个切面,其中`execution`表达式指定了切点,而`beforeAdvice`方法将在匹配的方法执行前被调用[^4]。 #### 4. AOP 的优势与限制 - **优势**: - 提高代码复用性,减少重复代码。 - 将横切关注点从业务逻辑中分离出来,提高模块化程度。 - **限制**: - 性能开销:由于代理对象的存在,可能会带来一定的性能损耗。 - 可读性降低:过多的AOP逻辑可能使代码难以理解和维护。 ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值