事务原理概述
- 注册自动创建代理类:InfrastructureAdvisorAutoProxyCreator
1.1 通过@Import导入注册类列表,关注AutoProxyRegistrar
1.2 遍历注册类,调用其registerBeanDefinitions方法
1.3 通过AutoProxyRegistrar创建自动代理类:InfrastructureAdvisorAutoProxyCreator
- 通过InfrastructureAdvisorAutoProxyCreator创建代理类
2.1 InfrastructureAdvisorAutoProxyCreator继承BeanPostProcessor
2.2 在其postProcessAfterInitialization方法中,通过代理工厂创建代理:ObjenesisCglibAopProxy
- 从容器中获取代理,并调用目的方法
3.1 关注Enhancer的callbacks属性,例如:DynamicAdvisedInterceptor
3.2 调用目的类方法时,会被DynamicAdvisedInterceptor#intercept拦截住
3.3 在DynamicAdvisedInterceptor#intercept中,会获取方法的拦截器链,并封装在CglibMethodInvocation属性中,调用其proceed方法
(1)与事务有关的拦截器:TransactionInterceptor(事务实现)
3.4 通过ExposeInvocationInterceptor实现其方法拦截器链的链式调用
分析问题@Transactional不生效的原因
- 分析InfrastructureAdvisorAutoProxyCreator是否为其目标类创建代理
1.1 在其postProcessAfterInitialization打上断点,并设置断点条件
1.2 如果执行了createProxy方法,则说明为目标类创建了代理
- 分析代理类的DynamicAdvisedInterceptor#intercept方法
2.1 断点观察其目标方法的拦截器,观察是否有事务拦截器:TransactionInterceptor(调式发现并没有)
在启动类上加@EnableTransactionManagement解决上述问题
- @EnableTransactionManagement注解导入了TransactionManagementConfigurationSelector
- @EnableTransactionManagement默认adviceMode=proxy,导入事务管理配置ProxyTransactionManagementConfiguration
- 在ProxyTransactionManagementConfiguration中注册事务拦截器
3.1 向容器中注册advisor:BeanFactoryTransactionAttributeSourceAdvisor
3.2 遍历容器中所有的bean,通过类型(org.springframework.aop.Advisor)匹配,添加到advisors集合中
补充
- 分析获取bean相关的advices(AbstractAdvisorAutoProxyCreator#getAdvicesAndAdvisorsForBean)
1.1 步骤:(1)获取容器所有的advice (2)找到其中符合bean的advice
1.2 AbstractAdvisorAutoProxyCreator#findAdvisorsThatCanApply(步骤2的分析)
1.2.1 获取advice的pointcut:BeanFactoryTransactionAttributeSourceAdvisor#getPointcut
1.2.2 获取类及其接口的所有方法,遍历方法,并调用TransactionAttributeSourcePointcut#matches进行匹配
(1)判断方法是否有事务注解
(2)判断方法所在类是否有事务注解
- 关于Enhancer的测试代码(从spring事务源码中抽取)
public class ProxyTest {
public String testProxy(String name){
return name;
}
@Test
public void test(){
ProxyTest proxyTest = (ProxyTest) getProxy();
proxyTest.testProxy("zhangjie");
}
private Object getProxy(){
ProxyTest proxyTest = new ProxyTest();
AdvisedSupport advisedSupport = new AdvisedSupport(proxyTest);
ClassLoader classLoader = ClassUtils.getDefaultClassLoader();
Enhancer enhancer = new Enhancer();
enhancer.setClassLoader(classLoader);
enhancer.setSuperclass(ProxyTest.class);
Class<?>[] proxiedInterfaces = new Class<?>[2];
proxiedInterfaces[0] = SpringProxy.class;
proxiedInterfaces[1] = Advised.class;
enhancer.setInterfaces(proxiedInterfaces);
enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
enhancer.setStrategy(new ClassLoaderAwareUndeclaredThrowableStrategy(classLoader));
Callback[] callbacks = getCallbacks(advisedSupport);
Class<?>[] types = new Class<?>[callbacks.length];
for (int x = 0; x < types.length; x++) {
types[x] = callbacks[x].getClass();
}
enhancer.setCallbackFilter(new ProxyCallbackFilter());
enhancer.setCallbackTypes(types);
Class<?> proxyClass = enhancer.createClass();
SpringObjenesis objenesis = new SpringObjenesis();
Object proxyInstance = objenesis.newInstance(proxyClass, enhancer.getUseCache());
((Factory) proxyInstance).setCallbacks(callbacks);
return proxyInstance;
}
private Callback[] getCallbacks(AdvisedSupport advisedSupport){
Callback aopInterceptor = new DynamicAdvisedInterceptor(advisedSupport);
Callback targetInterceptor = new StaticUnadvisedInterceptor();
Callback targetDispatcher = new StaticDispatcher();
Callback advisedDispatcher = new AdvisedDispatcher();
Callback[] callbacks = new Callback[] {
aopInterceptor,
targetInterceptor,
new SerializableNoOp(),
targetDispatcher,
advisedDispatcher,
new EqualsInterceptor(),
new HashCodeInterceptor()
};
return callbacks;
}
@Data
@AllArgsConstructor
class AdvisedSupport{
private Object target;
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(){
List<Object> list = new ArrayList<>();
return list;
}
}
class ProxyCallbackFilter implements CallbackFilter{
@Override
public int accept(Method method) {
System.out.println("执行ProxyCallbackFilter....");
return 0;
}
}
class ClassLoaderAwareUndeclaredThrowableStrategy extends UndeclaredThrowableStrategy{
private final ClassLoader classLoader;
public ClassLoaderAwareUndeclaredThrowableStrategy(@Nullable ClassLoader classLoader) {
super(UndeclaredThrowableException.class);
this.classLoader = classLoader;
}
}
class CglibMethodInvocation extends ReflectiveMethodInvocation {
private final MethodProxy methodProxy;
protected CglibMethodInvocation(Object proxy, Object target, Method method, Object[] arguments, Class<?> targetClass, List<Object> interceptorsAndDynamicMethodMatchers, MethodProxy methodProxy) {
super(proxy, target, method, arguments, targetClass, interceptorsAndDynamicMethodMatchers);
this.methodProxy = (Modifier.isPublic(method.getModifiers()) &&
method.getDeclaringClass() != Object.class && !AopUtils.isEqualsMethod(method) &&
!AopUtils.isHashCodeMethod(method) && !AopUtils.isToStringMethod(method) ?
methodProxy : null);
}
}
class DynamicAdvisedInterceptor implements MethodInterceptor{
AdvisedSupport advisedSupport;
public DynamicAdvisedInterceptor(AdvisedSupport advisedSupport) {
this.advisedSupport = advisedSupport;
}
@Override
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
System.out.println("执行DynamicAdvisedInterceptor......");
Object target = advisedSupport.getTarget();
Class<?> targetClass = target.getClass();
List<Object> chain = advisedSupport.getInterceptorsAndDynamicInterceptionAdvice();
Object retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
return retVal;
}
}
class StaticUnadvisedInterceptor implements MethodInterceptor{
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("执行StaticUnadvisedInterceptor......");
return null;
}
}
class EqualsInterceptor implements MethodInterceptor{
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("执行StaticUnadvisedInterceptor......");
return null;
}
}
class HashCodeInterceptor implements MethodInterceptor{
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("执行StaticUnadvisedInterceptor......");
return null;
}
}
class StaticDispatcher implements Dispatcher{
@Override
public Object loadObject() throws Exception {
System.out.println("执行StaticUnadvisedInterceptor......");
return null;
}
}
class AdvisedDispatcher implements Dispatcher{
@Override
public Object loadObject() throws Exception {
System.out.println("执行StaticUnadvisedInterceptor......");
return null;
}
}
class SerializableNoOp implements NoOp{
}
}