深圳交易网站建设,wordpress tag优化,php如何做音乐网站,wordpress能给手机发短信吗这是博主在使用dubbo实现远程过程调用的时候遇到的问题#xff1a;
我们如果在服务提供者类上加入Transactional事务控制注解后#xff0c;服务就发布不成功了。原因是事务控制的底层原理是为服务提供者类创建代理对象#xff0c;而默认情况下Spring是基于JDK动态代理方式创…这是博主在使用dubbo实现远程过程调用的时候遇到的问题
我们如果在服务提供者类上加入Transactional事务控制注解后服务就发布不成功了。原因是事务控制的底层原理是为服务提供者类创建代理对象而默认情况下Spring是基于JDK动态代理方式创建代理对象而此代理对象的完整类名为com.sun.proxy.$Proxy42最后两位数字不是固定的导致Dubbo在发布服务前进行包匹配时无法完成匹配进而没有进行服务的发布。 1. 疑问
大家都知道 Spring5 之前的版本 AOP 在默认情况下是使用 JDK 动态代理的那 Spring5 版本是不是真的做了修改呢于是我打开 Spring Framework 5.x 文档再次进行了确认 文档地址https://docs.spring.io/spring/docs/5.2.0.RELEASE/spring-framework-reference/core.html#aop Spring Framework 5.x 文档
简单翻译一下。Spring AOP 默认使用 JDK 动态代理如果对象没有实现接口则使用 CGLIB 代理。 默认情况下如果业务对象没有实现接口则使用CGLIB。由于面向接口而不是类进行编程是一个最佳实践所以业务类通常实现一个或多个业务接口。当然也可以强制使用 CGLIB 代理,在那些(希望很少)情况下您需要通知[advise]一个没有在接口上声明的方法或者需要将经过代理的对象作为具体类型传递给方法。
2. 真相大白
在 SpringBoot2.x 版本中通过AopAutoConfiguration来自动装配 AOP。
默认情况下是肯定没有spring.aop.proxy-target-class这个配置项的。而此时在 SpringBoot 2.x 版本中会默认使用 CGLIB 来实现。
SpringBoot 2.x 中如何修改 AOP 实现
通过源码我们也就可以知道在 SpringBoot 2.x 中如果需要修改 AOP 的实现需要通过spring.aop.proxy-target-class这个配置项来修改。
#在application.properties文件中通过spring.aop.proxy-target-class来配置
spring.aop.proxy-target-classfalse JDK 动态代理是基于接口的代理生成的对象只能赋值给接口变量。
而 CGLIB 就不存在这个问题。因为 CGLIB 是通过动态生成的子类继承目标类的方式来实现的代理对象无论是赋值给接口还是实现类这两者都是代理对象的父类。 CGLIB的限制/问题目标类不能使用final修饰。因为final修饰的类是不能被继承的。
SpringBoot 正是出于这种考虑于是在 2.x 版本中将 AOP 默认实现改为了 CGLIB。 总结
1. Spring 5.x 中 AOP 默认依旧使用 JDK 动态代理。
2. SpringBoot 2.x 开始为了解决使用 JDK 动态代理可能导致的类型转化异常而默认使用 CGLIB。
3. 在 SpringBoot 2.x 中如果需要默认使用 JDK 动态代理可以通过配置项spring.aop.proxy-target-classfalse来进行修改proxyTargetClass配置已无效。