Spring AOP动态代理实现,解决Spring Boot中无法正常启用JDK动态代理的问题
Spring AOP底层的动态代理实现有两种方式:一种是JDK动态代理,另一种是CGLib动态代理。
JDK动态代理
JDK 1.3版本以后提供了动态代理,允许开发者在运行期创建接口的代理实例,而且只能为接口创建代理实例。
如果被代理目标没有接口那么Spring也无能为力,Spring通过Java的反射机制生成被代理接口的新的匿名实现类。
JDK动态代理具体实现原理:
通过实现
InvocationHandlet接口创建自己的调用处理器;通过为Proxy类指定ClassLoader对象和一组interface来创建动态代理;
通过反射机制获取动态代理类的构造函数,其唯一参数类型就是调用处理器接口类型;
通过构造函数创建动态代理类实例,构造时调用处理器对象作为参数参入;
CGLib动态代理
CGLib 全称 Code Generation Library,是一个强大的高性能字节码生成类库,可以实现运行期动态扩展Java类。
Spring在运行期采用CGLib的字节码技术为类创建一个子类,并在子类中拦截所有父类方法的调用,织入横切逻辑实现AOP面向切面编程。
注意事项
如果被代理的对象实现了接口,那么Spring默认会使用JDK动态代理,否则会强制使用CGLib实现动态代理(如果被代理的类被final关键字所修饰,那么代理会失败)
关于两者的性能,JDK动态代理所创建的代理对象,在1.8以前的版本中性能并不高,最新版本中性能得到了很大的提升,和CGLib相差不大。
Spring Boot中无法正常启用JDK动态代理的问题
关于Spring的默认动态代理模式,官方文档中显示是JDK动态代理,但Spring Boot 2.2中发现即使强制指定@EnableAspectJAutoProxy(proxyTargetClass = false) ,生成的代理类依然显示$EnhancerBySpringCGLIB。
在DefaultAopProxyFactory中发现isProxyTargetClass被指定为强制代理目标类,所以会采用ObjenesisCglibAopProxy创建代理。
最后跟踪到ValidationAutoConfiguration中的一个Bean方法中,主动读取了环境变量spring.aop.proxy-target-class,而且默认值是true。
问题点算是找到了,不过这里只是一个函数校验的处理器,竟然会强制读取魔法配置,有些莫名其妙...手工添加配置后JDK代理恢复正常。
@Bean
@ConditionalOnMissingBean
public static MethodValidationPostProcessor methodValidationPostProcessor(Environment environment, @Lazy Validator validator) {
MethodValidationPostProcessor processor = new MethodValidationPostProcessor();
boolean proxyTargetClass = environment.getProperty("spring.aop.proxy-target-class", Boolean.class, true);
processor.setProxyTargetClass(proxyTargetClass);
processor.setValidator(validator);
return processor;
}
Spring AOP动态代理实现,解决Spring Boot中无法正常启用JDK动态代理的问题的更多相关文章
- [Spring框架]Spring AOP基础入门总结二:Spring基于AspectJ的AOP的开发.
前言: 在上一篇中: [Spring框架]Spring AOP基础入门总结一. 中 我们已经知道了一个Spring AOP程序是如何开发的, 在这里呢我们将基于AspectJ来进行AOP 的总结和学习 ...
- 重学 Java 设计模式:实战代理模式「模拟mybatis-spring中定义DAO接口,使用代理类方式操作数据库原理实现场景」
作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 难以跨越的瓶颈期,把你拿捏滴死死的! 编程开发学习过程中遇到的瓶颈期,往往是由于看不 ...
- 解决 Maven 项目中找不到 jdk 的 tools.jar 文件的办法(多数情况下适用)
<dependency> <groupId>jdk.tools</groupId> <artifactId>jdk.tools</artifact ...
- Spring系列(四):Spring AOP详解
一.AOP是什么 AOP(面向切面编程),可以说是一种编程思想,其中的Spring AOP和AspectJ都是现实了这种编程思想.相对OOP(面向过程编程)来说,提供了另外一种编程方式,对于OOP过程 ...
- Spring Aop(一)——Aop简介
转发地址:https://www.iteye.com/blog/elim-2394629 1 Aop简介 AOP的全称是Aspect Oriented Programming,翻译成中文是面向切面编程 ...
- 【总结】spring aop
1.aop简介 AOP的全称是Aspect Oriented Programming,面向切面编程.它的主要思想是在程序正常执行的某一个点切进去加入特定的逻辑.AOP框架中对AOP支持最完整的是Asp ...
- Spring AOP详解 、 JDK动态代理、CGLib动态代理
AOP是Aspect Oriented Programing的简称,面向切面编程.AOP适合于那些具有横切逻辑的应用:如性能监测,访问控制,事务管理以及日志记录.AOP将这些分散在各个业务逻辑中的代码 ...
- Spring AOP中的动态代理
0 前言 1 动态代理 1.1 JDK动态代理 1.2 CGLIB动态代理 1.2.1 CGLIB的代理用法 1.2.2 CGLIB的过滤功能 2 Spring AOP中的动态代理机制 2.1 ...
- 【转载】Spring AOP详解 、 JDK动态代理、CGLib动态代理
Spring AOP详解 . JDK动态代理.CGLib动态代理 原文地址:https://www.cnblogs.com/kukudelaomao/p/5897893.html AOP是Aspec ...
随机推荐
- CRM产品主数据在行业解决方案industry solution中的应用
AG3, choose this role: Create a new Acquisition Contracts: Here our product advances search will be ...
- 一个标准sql语句模板
select distinct top n * from t1 inner join t2 on ... join t3 on ... where ... group by ... having .. ...
- Odoo中的env详解
转载请注明原文地址:https://www.cnblogs.com/ygj0930/p/10826382.html 一:environment environment类提供了对ORM对象的封装,同时提 ...
- React源码 memo Fragment StrictMode cloneElement createFactory
1.memo react 16.6 推出的 api ,他的用意是给 function component 也有 PureComponent 这样一个类似的功能,因为我们知道 PureComponent ...
- nginx访问jupyter
现在jupyter已通过k8s安装完成,并通过nodeport暴露出来. 如果不能直接访问这个nodeport(像我在的公司)或是希望能组织好jupyter实例, 那应该如何调通呢? 这里包括两个技术 ...
- 使用WIFI网卡的AP功能
前几篇博客中,wifi无线网卡都工作于STA模式,那么它能否工作于AP模式.本篇博客就研究使wifi 无线网卡工作于AP模式.使用一个应用程序hostapd,关于它的介绍可以去此网站https://w ...
- java.sql.SQLException: Access denied for user 'root'@'10.1.0.2' (using password: YES)
java.sql.SQLException: Access denied for user 'root'@'10.1.0.2' (using password: YES) at com.mysql.c ...
- python中列表(list)函数及使用
序列是Python中最基本的数据结构.序列中的每个元素都分配一个数字 - 它的位置,或索引,第一个索引是0,第二个索引是1,依此类推. Python有6个序列的内置类型,但最常见的是列表和元组. 序列 ...
- destoon搜索伪静态失败解决办法
今天给一个朋友调试DT6.0内核的站点,搜索中文出现http 403 forbidden,找了半天,很纳闷,最后一个一个查看源代码总算找到,在此分享给大家! 解决的方法: 1.找到include/sa ...
- 【Js】创建对象的6种方式总结、(底部包含属性名为动态的形式)
一.new 操作符 + Object 创建对象 1 var person = new Object(); 2 person.name = "lisi"; 3 person.age ...