spring boot aop/transational
2020-06-01 11:40:50 67 举报
登录查看完整内容
spring aop/transational
作者其他创作
大纲/内容
aop advisor匹配方法findAdvisorsThatCanApply()
JpaBaseConfiguration
@Configuration
提交事务
包装cglib动态代理对象实现类
调用shouldSkip()
JdbcTemplateAutoConfiguration
TransactionalEventListenerFactory
实现1
目的是让dsii这个bean早点初始化
这一步比较重要
创建代理工厂ProxyFactory包装DefaultAopProxyFactory
将需要代理的bean包装到SingletonTargetSource
HibernateJpaAutoConfiguration
是为了解决在mvc的controller中使用了hibernate的lazy load的属性时没有session抛出的LazyInitializationException异常
DataSourceInitializerInvoker
JdbcTemplate
AnnotationTransactionAttributeSource
选择2
DataSourceTransactionManager
持有
@AutoConfigureAfter
创建增强者Enhancer
继承自
NamedParameterJdbcTemplateConfiguration
JdbcTemplateConfiguration
进入advisorFactory.getAdvisors()通过排除@PointCut注解找到切入点包装advisor并排序,然后缓存起来
开始调用createProxy()创建代理对象
@Configuration@Bean
DataSourceAutoConfiguration
@Bean
matchers()
遍历匹配器匹配
这个类主要做了几件事情:1、从beanFactory拿出所有的bean依次遍历是否有@Aspect注解,没有则抛弃,有则继续2、找到带@Aspect的类后,再找类里面方法是否包含@PointCut注解3、有则new一个InstantiationModelAwarePointcutAdvisorImpl类型的advisor4、然后将advisor缓存起来
TransactionManagementConfigurationSelector
选择1
调用DynamicAdvisedInterceptor的intercept()方法,
调用aopProxyFactory.createAopProxy()
findAdvisorBeans()方法查找实现了Advisor接口的bean
jdk动态代理
这里分为几种类型:1、通过@Aspect注解找到的类,并且不是PointcutAdvisor或者IntroductionAdvisor直接返回true2、IntroductionAdvisor会调用ClassFilter的matches方法匹配bean的类型是否需要过滤掉。3、PointcutAdvisor会拿到Pointcut的方法匹配器MethodMatcher,通过target类找到所有方法,一个一个匹配。@Transational注解就是在这里匹配出来的。
WebSphere用的,不管。
因为@Aspect或者@Transational等注解标记的方法或者类都是使用的代理类,是通过spring context管理的,@Autowired注入的时候使用的是代理对象,并不是真正的注入类型的bean,所以需要注意以下场景使用的问题:1、实际类之间方法调用,并不会触发aop,因为他们使用的是this指针调用的,而this指针指向的是实际的类,并不是代理类。2、实际类方法里面异步调用了另一个方法,而该方法有@Transational或者@Async注解,则该方法不会触发代理,也就是不会触发事务或者异步,这个需要异常小心。3、需要代理的类,调用方法时最好都能触发代理。
主要做事务属性源匹配的一个包装
使用了@EnableAspectJAutoProxy
分两种不同类型的事务管理器
实现2
继承
@Import
@Import配置各种数据源
主要是包装连接池
ProxyTransactionManagementConfiguration
调用BeanFactoryAspectJAdvisorsBuilder的buildAspectJAdvisors()方法
CallbackPreferringPlatformTransactionManager
EntityManagerFactoryBuilder
进入advisorFactory.isAspect()通过遍历所有bean class 筛选是否带@Aspect注解,找到需要的切面类
EntityManagerFactory构建器,方便构建EntityManagerFactory
创建
首先寻找spring boot的spring.factories文件找到自动装配的类
包装jdk动态代理实现类
通过getProxy()方法创建代理对象
2
补充
事务方法调用触发invoke()
拥有事务注解匹配器TransactionAnnotationParser
JpaVendorAdapter
jdk proxy
TransactionManagerCustomizers
两种代理都会对hashCode、equals方法做特殊处理
bean初始化后调用postProcessAfterInitialization()方法
TransactionAttributeSourcePointcut
抛异常时回滚
这里开启mode为ASPECTJ时,注解事务不生效?
这里不考虑ReactiveTransaction
aop创建代理
1
第一步,创建代理工厂
注意:如果需要代理的类没有实现接口,则不管proxy-target-class=false,依然使用cglib。
PlatformTransactionManager
开启事务
在这里实现了线程内的事务传递性,通过Threadlocal实现。开启事务后,线程内,如果第二个带@Transational注解方法执行,则会跟第一次执行的方法在同一个事务上。要不一起成功,要不一起失败。
遍历之前已加排好序的advisor调用ReflectiveMethodInvocation的proceed()
AbstractAutoProxyCreator
completeTransactionAfterThrowing()
TransactionAspectSupport的invokeWithinTransaction()
PooledDataSourceConfiguration
NamedParameterJdbcTemplate
此类为核心类,实现了SmartInstantiationAwareBeanPostProcessor接口(继承自BeanPostProcessor),所以具备在bean实例化后做增强。aop就是在这时对需要代理的对象进行增强,可以通过jdk动态代理或者cglib。
cglib动态代理
AutoProxyRegistrar
调用方法wrapIfNecessary()包装bean
这里设置了增强对对象的filter为ProxyCallbackFilter。在ProxyCallbackFilter的accept()方法会匹配代理方法使用哪个callback。一般的callback类型:1、DynamicAdvisedInterceptor 2、StaticUnadvisedInterceptor3、SerializableNoOp4、StaticDispatcher5、AdvisedDispatcher6、EqualsInterceptor7、HashCodeInterceptor
获取到所有的advisor然后包装到ReflectiveMethodInvocation
cglib proxy
commitTransactionAfterReturning(txInfo)
JtaAutoConfiguration
调用
aop的pointcut advisor,在这里匹配@Transational
调用顺序依次为1、ExposeInvocationInterceptor 会调用下一个 advice,完成后调用自己的invoke2、AspectJAfterThrowingAdvice 会调用下一个advice,出现异常的时候才会调用自己的invoke3、AspectJAfterReturningAdvice 会调用下一个advice,完成后会调用自己的invoke4、AspectJAfterAdvice 会调用下一个advice,完成后会调用自己的invoke5、AspectJAroundAdvice 这里会匹配钩子方法的参数,然后直接调用自己的invoke,再调用下一个advice6、AspectJMethodBeforeAdvice 这里直接调用自己的invoke,然后到 4 -> 3 -> 1
InvocationHandler.invoke()
特别注意
最后创建代理create()
最后创建代理Proxy.newProxyInstance()代理类为JdkDynamicAopProxy
DataSourcePoolMetadataProvidersConfiguration
TransactionTemplate
txInfo = createTransactionIfNecessary()
1 自定义TargetSource
这一步比较重要,在这里会准备好需要拦截的方法,并对方法进行排序
一套jpa标准接口,使用spi加载。提供给EntityManagerFactory。
cglib
@Configuration@Import
getAdvicesAndAdvisorsForBean()调用findEligibleAdvisors()找到需要代理的类
OpenEntityManagerInViewInterceptor
LocalContainerEntityManagerFactoryBean
HibernateJpaConfiguration
PlatformTransactionManager默认JpaTransactionManager
触发事务处理过程
重点
EmbeddedDataSourceConfiguration
AbstractTransactionManagementConfiguration
@Importregistrar注册
最终
Spring Boot AOP源码阅读
调用CglibMethodInvocation的proceed()方法。跟jdk代理一样。
从各advisor中拿到advice,类似于责任链模式调用模式依次调用。注意:这里会不断匹配方法。
找到TransactionAutoConfiguration
Neo4jDataAutoConfiguration
找到AopAutoConfiguration
调用核心方法
自定义TargetSource创建的代理对象是通过postProcessBeforeInstantiation()创建的
@EnableTransactionManagement开启事务管理。默认使用cglib代理,可使用spring.aop.proxy-target-class修改
事务方法拦截器,Advice
@Import导入了一个beanAspectJAutoProxyRegistrar
TransactionInterceptor
BeanFactoryTransactionAttributeSourceAdvisor
DataSourceInitializationConfiguration.Registrar注册了DataSourceInitializerPostProcessor
创建了AnnotationAwareAspectJAutoProxyCreator
例如这里事务实现了这个接口,事务就是通过aop实现的。
Spring Boot Transation相关源码阅读
主要有两种注解类型匹配:1、JtaTransactionAnnotationParser => 匹配的是javax注解@Transational2、SpringTransactionAnnotationParser => 匹配的是spring注解@Transational
第二步,真正创建代理
DataSourceInitializedPublisher实现BeanPostProcessor
代理过程
DataSourceTransactionManagerAutoConfiguration
entityManagerFactory
匹配完Advisor后
0 条评论
回复 删除
下一页