Transaction註解原理
開啟事務註解 EnableTransactionManagement ,該註解往容器中匯入了匯入 TransactionManagementConfigurationSelector 元件。該元件有個方法,在容器重新整理的時候會被呼叫。 ( 此處不講解為什麼會被呼叫,重點講解 Transaction 註解 )
protected String[] selectImports(AdviceMode adviceMode) {
switch (adviceMode) {
case PROXY:
return new String[] {AutoProxyRegistrar.class.getName(),
ProxyTransactionManagementConfiguration.class.getName()};
case ASPECTJ:
return new String[] {
TransactionManagementConfigUtils.TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME};
· default:
· return null;
· }
· }
·
·
EnableTransactionManagement
預設是
**AdviceMode mode() default AdviceMode.PROXY;**
所以
AutoProxyRegistrar
和
ProxyTransactionManagementConfiguration
會被載入到容器中。
·
· AutoProxyRegistrar 功能是往容器中註冊了 InfrastructureAdvisorAutoProxyCreator 是個 BeanPostProcessor 後置處理器。
· ProxyTransactionManagementConfiguration 利用 @Bean 註解往容器中新增多個 bean 。 (BeanFactoryTransactionAttributeSourceAdvisor 是個 Advisor 和前面 Aop 中 @Before 一樣都是通知方法,但是此處的是手動匯入的, Aop 是自己自動生成的 ) 。
·
· 在bean 生成完成以後會跟單網gendan5.com呼叫後置處理器初始化。會去查詢 bean 有沒有合適的通知方法。所以重點是在找通知方法,找到了合適的就會生成代理物件。
·
· // 簡單的分析一下流程
· AbstractAutowireCapableBeanFactory#initializeBean() ->
· AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization() ->
· AbstractAutoProxyCreator#postProcessAfterInitialization() ->
· AbstractAutoProxyCreator#wrapIfNecessary()->
· AbstractAdvisorAutoProxyCreator#getAdvicesAndAdvisorsForBean()
/**
· * 尋找可用的通知方法
· */
· protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
· // 尋找所有的 Advisors, 會去容器遍歷所有型別為 Advisor 的 bean ,
· //BeanFactoryTransactionAttributeSourceAdvisor 就是我們手動匯入的 Advisor
· List<Advisor> candidateAdvisors = findCandidateAdvisors();
· // 在所有的 Advisors, 看是否有 beanClass 匹配的
· List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
· extendAdvisors(eligibleAdvisors);
· if (!eligibleAdvisors.isEmpty()) {
· eligibleAdvisors = sortAdvisors(eligibleAdvisors);
· }
· return eligibleAdvisors;
· }
· // 找到所有的 Advisors, 剩下就是是否有匹配的 findAdvisorsThatCanApply() 方法 // 最終走到 TransactionAttributeSourcePointcut#matches//->AbstractFallbackTransactionAttributeSource#computeTransactionAttribute
·
· ```javaprotected TransactionAttribute computeTransactionAttribute(Method method, Class<?> targetClass) {
· // 判斷方法修飾符是不是 Public , allowPublicMethodsOnly() 預設是 true 的
· if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) {
· return null;
· }
·
· // 這裡面就是判斷方法上有沒有 Transactional 註解,有進行解析操作並返回。
· TransactionAttribute txAttr = findTransactionAttribute(specificMethod);
· if (txAttr != null) {
· return txAttr;
· }
· // 程式碼每貼全,為了少點沒用的東西。。。。
· 那要是找了合適的通知方法,就生成代理物件,並設定回撥函式。設定回撥函式是CglibAopProxy.DynamicAdvisedInterceptor 的 intercept 方法,該方法有個 getInterceptorsAndDynamicInterceptionAdvice 獲取合適的攔截器。 ( 事務的攔截器是 TransactionInterceptor)
· public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
· // 獲取目標物件,不是代理物件
· target = getTarget();
· if (target != null) {
· targetClass = target.getClass();
· }
· // 獲取方法合適的攔截器
· List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
· Object retVal;
· // 沒有合適的攔截器並且方法的修飾符是 Public
· if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {
· Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
· // 會呼叫目標方法
· retVal = methodProxy.invoke(target, argsToUse);
· }
· else {
· /*
· * 1. 有合適的攔截器 : 會去執行攔截器 TransactionInterceptor#invoke() ,
· * 事務的提交,回滾等一系列操作都在裡面。具體是調去了
· * TransactionAspectSupport#invokeWithinTransaction() 方法
· * 2. 沒有合適的攔截器並且方法的修飾符不是 Public: 這裡面也會去調目標方法
· * ( 這裡簡單可以走進去看一下 )
· */
· retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
· }
· retVal = processReturnType(proxy, target, method, retVal);
· return retVal;
· }
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69946337/viewspace-2740620/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Spring @Transaction 註解是如何執行事務的?Spring
- @LoadBalanced註解原理
- Java註解與原理分析Java
- JUnit 註解@RunWith的工作原理
- JUnit 註解@Category的工作原理Go
- JUnit 註解@SuiteClasses的工作原理UI
- JUnit 註解@Rule的工作原理
- 17_深入解析Oracle undo原理(1)_transactionOracle
- SpringBoot原始碼解析-@ConditionalOnXXX註解原理Spring Boot原始碼
- JAVA 註解的基本原理Java
- Spring框架裡註解@Autowired的工作原理Spring框架
- Angular @Injectable 註解的工作原理淺析Angular
- Environment Switcher 原理解析(註解、Apt、反射、混淆)APT反射
- Android 註解系列之 EventBus3 原理(四)AndroidS3
- Java JUnit框架裡@Category註解的工作原理Java框架Go
- SpringBoot事物Transaction實戰講解教程Spring Boot
- SAP Fiori 註解 @ObjectModel.readOnly工作原理解析Object
- spring boot使用@Async非同步註解,原理+原始碼Spring Boot非同步原始碼
- spring-AOP(二)實現原理之AspectJ註解方式Spring
- SAP Fiori @OData.publish 註解的工作原理解析
- oracle中的processes,session,transaction引數詳解OracleSession
- @lombok註解背後的原理是什麼,讓我們走近自定義Java註解處理器LombokJava
- 註解的原理又是怎麼一回事
- 《四 spring原始碼》spring的事務註解@Transactional 原理分析Spring原始碼
- Spring Ioc原始碼分析系列--@Autowired註解的實現原理Spring原始碼
- IDBObjectStore.transactionObject
- IDBDatabase.transaction()Database
- BTC的Transaction
- 深入理解mysqldump原理 --single-transaction --lock-all-tables --master-dataMySqlAST
- 註解專題(一)Java元註解,內建註解Java
- JAVA-註解(2)-自定義註解及反射註解Java反射
- Java註解-後設資料、註解分類、內建註解和自定義註解Java
- nacos 服務註冊原理
- @ResponseBody註解和@RequestBody註解使用
- 【Spring註解】事務註解@TransactionalSpring
- SpringBoot自動裝配原理之Configuration以及@Bean註解的使用Spring BootBean
- 死磕Spring之IoC篇 - @Bean 等註解的實現原理SpringBean
- 死磕Spring之IoC篇 - @Autowired 等註解的實現原理Spring