专栏名称: java一日一条
主要是讲解编程语言java,并且每天都推送一条关于java编程语言的信息
目录
相关文章推荐
51好读  ›  专栏  ›  java一日一条

Spring AOP是什么?你都拿它做什么?

java一日一条  · 公众号  · Java  · 2019-04-30 23:10

正文

请到「今天看啥」查看全文




使用 JDK 生成的动态代理的前提是目标类必须有实现的接口 。但这里又引入一个问题,如果某个类没有实现接口,就不能使用 JDK 动态代理。所以 CGLIB 代理就是解决这个问题的。

CGLIB 是以动态生成的子类继承目标的方式实现,在运行期动态的在内存中构建一个子类,如下:

public class UserDao{}
// CGLIB 是以动态生成的子类继承目标的方式实现,程序执行时,隐藏了下面的过程
public class $Cglib_Proxy_class extends UserDao{}


CGLIB 使用的前提是目标类不能为 final 修饰 。因为 final 修饰的类不能被继承。

现在,我们可以看看 AOP 的定义:面向切面编程,核心原理是 使用动态代理模式在方法执行前后或出现异常时加入相关逻辑

通过定义和前面代码我们可以发现3点:

  • AOP 是基于动态代理模式。

  • AOP 是方法级别的。

  • AOP 可以分离业务代码和关注点代码(重复代码),在执行业务代码时,动态的注入关注点代码。切面就是关注点代码形成的类。


4. Spring AOP

前文提到 JDK 代理和 CGLIB 代理两种动态代理。优秀的 Spring 框架把两种方式在底层都集成了进去,我们无需担心自己去实现动态生成代理。那么,Spring是如何生成代理对象的?

  1. 创建容器对象的时候,根据切入点表达式拦截的类,生成代理对象。

  2. 如果目标对象有实现接口,使用 JDK 代理。如果目标对象没有实现接口,则使用 CGLIB 代理。然后从容器获取代理后的对象,在运行期植入“切面”类的方法。通过查看 Spring 源码,我们在 DefaultAopProxyFactory 类中,找到这样一段话。

简单的从字面意思看出:如果有接口,则使用 JDK 代理,反之使用 CGLIB ,这刚好印证了前文所阐述的内容。Spring AOP 综合两种代理方式的使用前提有会如下结论:如果目标类没有实现接口,且 class 为 final 修饰的,则不能进行 Spring AOP 编程!

知道了原理,现在我们将自己手动实现 Spring 的 AOP:

package test.spring_aop_anno;
import org.aspectj.lang.ProceedingJoinPoint;
public interface IUserDao {






请到「今天看啥」查看全文