动态代理
目前遇到的就是jdk动态代理和gclib动态代理
两种代理具体实现:传送门
两种代理区别:传送门
spring都有支持,默认是jdk代理,想使用gclib代理,需要配置<aop:config proxy-target-class=“true”>,
springboot 2.1.7.RELEASE使用的是gclib代理,其他版本不是很清楚,可以在配置文件中查看spring.aop.proxy-target-class默认值,true则为gclib代理,false为jdk代理
一个面试常问的实例
一个被代理类A
public class A {
public void method01(){
method02();
}
@Transactional(rollbackFor = Exception.class)
public void method02(){
// 插入一条数据
}
}
一个调用类B
public class B {
@Resource
private A a;
public void test(){
// 事务管理不生效
a.method01();
// 事务管理生效
a.method02();
}
}
分析事务生效问题
spring生成的A的代理类伪代码
public class AProxy {
A a = new A ();
public void method01(){
a.method01();
}
public void method02(){
// 开启数据库事务
Connection.start();
// 插入一条数据
a.method02();
// 数据库事务提交或者回滚
Connection.commit();
}
}
明确B类中字段a指向的实际是AProxy类的实例地址
1)当B调用a.method01() -> AProxy.method01() -> A.method01() -> this.method02(),这条链路上没有事务管理,所以事务不生效。
2)当B调用a.method02() -> AProxy.method02() -> A.method02(),spring对AProxy.method02()做事务管理,所以事务会生效
如果想使其生效,A类method01可改为如下方式
public class A {
public void method01(){
A aProxy = (A) AopProxyUtils.getSingletonTarget(A.class);
aProxy.method02();
}
}
顺带说一下框架里一般功能性注解的实现,基本都和BeanPostProcessor接口拖不了干系,具体大家可以百度、谷歌一下,有误也请大家指正,毕竟我也没看多少。。。