Spring Aop的原理

  1. SpringAOP就是通过动态代理实现的。当为某个Bean或者某些Bean配置切面时,Spring会为其创建代理对象,当调用该对象的某个方法时,实际是调用生成的代理类的对象方法。SpringAop主要是使用了两个动态代理,分别是JDK的动态代理和CGLIB动态代理。

1. JDK动态代理

  1. 如果代理类实现了接口,Spring默认会使用JDK动态代理。JDK的动态代理是基于反射实现。JDK通过反射,生成一个代理类,这个代理类实现了原来那个类的全部接口,并对接口中定义的所有方法进行了代理。当我们通过代理对象执行原来那个类的方法时,代理类底层会通过反射机制,调用我们实现的InvocationHandler接口的invoke方法。
点击查看代码
  1. /*
  2. * 接口类
  3. */
  4. public interface Person {
  5. void say();
  6. }
  7. /*
  8. * 接口实现类
  9. */
  10. public class Man implements Person {
  11. private String word;
  12. public Man(String word){
  13. this.word = word;
  14. }
  15. public Man(){
  16. }
  17. public void say(){
  18. System.out.println("Man Can Say " + word);
  19. }
  20. }
  21. public class ManJDKProxy implements InvocationHandler {
  22. /**
  23. * 需要的代理对象
  24. */
  25. private Object o;
  26. public Object bind(Object o){
  27. this.o = o;
  28. return Proxy.newProxyInstance(o.getClass().getClassLoader(), o.getClass().getInterfaces(), this);
  29. }
  30. @Override
  31. public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
  32. System.out.println("JDK Proxy Design");
  33. return method.invoke(o, args);
  34. }
  35. }
  36. /**
  37. * JDK动态代理
  38. */
  39. public class ProxyDesign_2 {
  40. public static void main(String[] args) {
  41. Man man = new Man("Hello");
  42. Person p = (Person)new ManJDKProxy().bind(man);
  43. p.say();
  44. }
  45. }

* JDK动态代理的优缺点

  1. 优点:
  2. 1. JDK动态代理是JDK原生的,不需要任何依赖即可使用
  3. 2. 通过反射机制生成代理类的速度要比CGLib操作字节码生成代理类的速度更快
  4. 缺点:
  5. 1. 如果要使用JDK动态代理,被代理的类必须实现了接口,否则无法代理(InvocationHandler)
  6. 2. JDK动态代理无法为没有在接口中定义的方法实现代理
  7. 3. JDK动态代理执行代理方法时,需要通过反射机制进行回调,此时方法执行的效率比较低

2. CGLIB动态代理

  1. 若需要代理的类没有实现接口,JDK的动态代理就无法使用,Spring会使用CGLiB动态代理来生成代理对象。CGLiB直接操作字节码,生成类的子类,重写类的方法完成代理。
点击查看代码
  1. /*
  2. * 接口类
  3. */
  4. public interface Person {
  5. void say();
  6. }
  7. /*
  8. * 接口实现类
  9. */
  10. public class Man implements Person {
  11. private String word;
  12. public Man(String word){
  13. this.word = word;
  14. }
  15. public Man(){
  16. }
  17. public void say(){
  18. System.out.println("Man Can Say " + word);
  19. }
  20. }
  21. public class ManCGLIBProxy {
  22. public Object bind(Object target){
  23. Enhancer enhancer = new Enhancer();
  24. enhancer.setSuperclass(target.getClass());
  25. enhancer.setCallback(new MethodInterceptor() {
  26. @Override
  27. public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
  28. System.out.println("CGLIB Proxy Design");
  29. return method.invoke(target, objects);
  30. }
  31. });
  32. return enhancer.create();
  33. }
  34. }
  35. /**
  36. * CGLIB动态代理
  37. */
  38. public class ProxyDesign_3 {
  39. public static void main(String[] args) {
  40. Man man = new Man("Hello");
  41. Person p = (Person)new ManCGLIBProxy().bind(man);
  42. p.say();
  43. }
  44. }

* CGLiB动态代理的优缺点

  1. 优点:
  2. 1. 使用CGLiB代理的类,不需要实现接口,因为CGLib生成的代理类是直接继承自需要被代理的类
  3. 2. 因为CGLiB实现方式是重写父类的方法,所以对final方法,或者private方法是没有办法代理的
  4. 3. CGLiB是通过修改字节码生成的代理类,所以CGLib执行代理方法的效率要高于JDK的动态代理
  5. 缺点:
  6. 1. 因为CGLiB实现方式是重写父类的方法,所以对final方法,或者private方法是没有办法代理的
  7. 2. 因为CGLiB生成代理类的方式是通过操作字节码(asm工具包),这种生成的代理类的方式比JDK通过反射生成代理类的方式的效率低

3. Spring项目中如何强制使用CGLIB代理方式

* xml方式

  1. <!-- aop:config用来在xml中配置切面,指定proxy-target-class="true" -->
  2. <aop:config proxy-target-class="true">
  3. <!-- AOP相关配置 -->
  4. </aop:config>

* @Aspect注解方式

  1. <!-- 将proxy-target-class配置设置为true -->
  2. <aop:aspectj-autoproxy proxy-target-class="true"/>

* 配置类注解方式

  1. 添加@EnableAspectJAutoProxy(proxyTargetClass = true)

SpringAop实现原理及代理模式的更多相关文章

  1. 大话设计模式C++实现-文章7章-代理模式

    一个.UML画画 二.概念 代理模式:为其它对象提供一种代理以控制对这个对象的訪问. 三.应用场景 (1)远程代理.也就是为一个对象在不同的地址空间提供局部代表.这样能够隐藏一个对象存在于不同地址空间 ...

  2. 代理模式(静态代理、JDK动态代理原理分析、CGLIB动态代理)

    代理模式 代理模式是设计模式之一,为一个对象提供一个替身或者占位符以控制对这个对象的访问,它给目标对象提供一个代理对象,由代理对象控制对目标对象的访问. 那么为什么要使用代理模式呢? 1.隔离,客户端 ...

  3. AOP 技术原理——代理模式全面总结

    前言 非常重要的一个设计模式,也很常见,很多框架都有它的影子.定义就不多说了.两点: 1.为其它对象提供一个代理服务,间接控制对这个对象的访问,联想 Spring 事务机制,在合适的方法上加个 tra ...

  4. springAOP之代理模式

    springAOP指的是在spring中的AOP,什么是AOP,相对于java中的面向对象(oop),在面向对象中一些公共的行为,像日志记录,权限验证等如果都使用面向对象来做,会在每个业务方法中都写上 ...

  5. 带你入门代理模式/SpringAop的运行机制

    SpringAop 是spring框架中最重要的一项功能之一,同时也是企业级开发记录事物日志等不可或缺的一部分,如果说你的系统需要记录用户访问接口的操作,那SpringAop是很完美的了,当然,拦截器 ...

  6. Java设计模式——代理模式实现及原理

    简介 Java编程的目标是实现现实不能完成的,优化现实能够完成的,是一种虚拟技术.生活中的方方面面都可以虚拟到代码中.代理模式所讲的就是现实生活中的这么一个概念:中介. 代理模式的定义:给某一个对象提 ...

  7. 重学 Java 设计模式:实战代理模式「模拟mybatis-spring中定义DAO接口,使用代理类方式操作数据库原理实现场景」

    作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 难以跨越的瓶颈期,把你拿捏滴死死的! 编程开发学习过程中遇到的瓶颈期,往往是由于看不 ...

  8. 从代理模式 到 SpringAOP

    前言 Spring AOP 就是通过代理模式来实现切面编程的.代理模式用来为其他对象提供一种代理,以控制对这个对象的访问. 代理对象在客户端和目标对象之间起到中介的作用.通过控制对这个对象的访问,可以 ...

  9. JAVA动态代理模式(从现实生活角度理解代码原理)

    所谓动态代理,即通过代理类:Proxy的代理,接口和实现类之间可以不直接发生联系,而可以在运行期(Runtime)实现动态关联. java动态代理主要是使用java.lang.reflect包中的两个 ...

随机推荐

  1. textbox 实现跨操作系统换行的两种写法

    每个操作系统对换坏的解释都不一样.所以写代码的时候要注意这个细节: 要基于.net跨环境的基类去写,才能跨平台. Unix系统里,每行结尾只有"<换行>",即" ...

  2. 哈工大 计算机网络 实验一 HTTP 代理服务器的设计与实现

    计算机网络实验代码与文件可见github:计算机网络实验整理 实验名称 HTTP 代理服务器的设计与实现 实验目的: 熟悉并掌握 Socket 网络编程的过程与技术:深入理解 HTTP 协议, 掌握 ...

  3. 进程&线程(三):外部子进程subprocess、异步IO、协程、分布式进程

    1.外部子进程subprocess python之subprocess模块详解--小白博客 - 夜风2019 - 博客园 python subprocess模块 - lincappu - 博客园 之前 ...

  4. Pycharm:集体缩进、注释、折叠

    1.集体缩进 选中代码块,按TAB 2.集体前移 选中代码块,Shift TAB 3.集体注释 选中代码块,CTRL + / 4.取消集体注释 再按一下CTRL+/ 5.集体折叠 CTRL+SHIFT ...

  5. laravel 登录+中间件拦截+红柚小说网小说采集+图片本地化

    .......................登录界面 <!doctype html> <html lang="en"> <head> < ...

  6. Nginx多个域名配置ssl证书出错解决方案

    解决方案一: 验证通配符 SSL 证书 当涉及通配符 SSL 证书时,NET::ERR_CERT_COMMON_NAME_INVALID 错误会变得稍微复杂一些. 这种类型的证书旨在加密多个子域的数据 ...

  7. LGP2891题解

    题目大意 有 \(n\) 只奶牛,\(q\) 种食物和 \(p\) 种饮料,每只奶牛喜欢一些饮料和食物,但只能那一种,求最小配对数量. 首先来看一下这道题的简化版:没有饮料,该怎么做呢? 我会!裸的二 ...

  8. ASP.NET Core 6框架揭秘实例演示[24]:中间件的多种定义方式

    ASP.NET Core的请求处理管道由一个服务器和一组中间件组成,位于 "龙头" 的服务器负责请求的监听.接收.分发和最终的响应,针对请求的处理由后续的中间件来完成.中间件最终体 ...

  9. spring事务详解(基于注解和声明的两种实现方式)

    Spring事务( Transaction ) 事务的概念 事务是一些sql语句的集合,作为一个整体执行,一起成功或者一起失败. 使用事务的时机 一个操作需要多天sql语句一起完成才能成功 程序中事务 ...

  10. 配置 PackMan 镜像

    一.参考链接 阿里云镜像站 二.PackMan 镜像介绍 Packman 是 OpenSUSE 最大的第三方软件源,主要为 OpenSUSE 提供额外的软件包,包括音视频解码器.多媒体应用.游戏等. ...