Spring 事务是如何应用到你的业务场景中的?
初衷
日常开发中经常用到@Transaction注解,那你知道它是怎么应用到你的业务代码中的吗?本篇文章将从以下两个方面阐述Spring事务实现原理:
解析并加载事务配置:本质上是解析xml文件将标签加载成 BeanDefinition 对象;
生成事务代理对象并运行:本质上是Spring AOP在事务这块的应用,将业务Bean替换成事务代理对象(JdkDynamicAopProxy:JDK代理,CglibAopProxy:CGLIB代理);
本文使用的源码版本是Spring 4.3.18.RELEASE,使用的是XML开启事务。
关键类
这里列出几个核心类,提前留个印象,后面会讲解什么时候调用
XmlBeanDefinitionReader 加载XML定义的Bean入口
TxNamespaceHandler 解析XML中的事务标签: advice、annotation-driven等;
InfrastructureAdvisorAutoProxyCreator 该类实现了 BeanPostProcessor 接口(可以在Bean初始化后进行替换),是生成事务代理类并替换的关键类;
AnnotationTransactionAttributeSource 用来解析业务方法使用注解 @Transaction 上的配置,提供给 TransactionInterceptor 使用;
TransactionInterceptor 事务拦截类:真正处理事务的类,开启、回滚事务,可以理解成切面中的通知:做什么;
BeanFactoryTransactionAttributeSourceAdvisor 实现了Advisor接口,可以理解为切面:切点(TransactionAttributeSourcePointcut) + 通知(TransactionInterceptor)。
示例代码:
public class TransactionService { @Transactional(rollbackFor = Throwable.class) public void testTransaction(){ System.out.println("方法逻辑"); } }
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("config.xml"); TransactionService transactionService = context.getBean(TransactionService.class); transactionService.testTransaction();
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:task="http://www.springframework.org/schema/task" xsi:schemaLocation=" http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.0.xsd"> <bean id="transactionService" class="com.yangwq.spring.transaction.TransactionService"/> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://127.0.0.1:3306/blog"/> <property name="username" value="root"/> <property name="password" value="11"/> </bean> <!-- 定义事务管理器 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean> <!--使用注释事务 --> <tx:annotation-driven/></beans>
1. 解析并加载事务配置
加载的入口(同时也是Spring容器加载的核心代码):
synchronized (this.startupShutdownMonitor) { // Prepare this context for refreshing. prepareRefresh(); // 重点,这里是Spring初始化默认的容器,在这一步会通过解析配置文件将定义的bean转换为 BeanDefinition, // 保存在 beanDefinitionMap 中 ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // Prepare the bean factory for use in this context. prepareBeanFactory(beanFactory); try { // Allows post-processing of the bean factory in context subclasses. postProcessBeanFactory(beanFactory); // Invoke factory processors registered as beans in the context. invokeBeanFactoryPostProcessors(beanFactory); // Register bean processors that intercept bean creation. registerBeanPostProcessors(beanFactory); // Initialize message source for this context. initMessageSource(); // Initialize event multicaster for this context. initApplicationEventMulticaster(); // Initialize other special beans in specific context subclasses. onRefresh(); // Check for listener beans and register them. registerListeners(); // 重点,初始化所有非懒加载bean的方法,也可以理解为根据特定规则将 BeanDefinition 转成 Bean对象的方法 finishBeanFactoryInitialization(beanFactory); // Last step: publish corresponding event. finishRefresh(); } catch (BeansException ex) { if (logger.isWarnEnabled()) { logger.warn("Exception encountered during context initialization - " + "cancelling refresh attempt: " + ex); } // Destroy already created singletons to avoid dangling resources. destroyBeans(); // Reset 'active' flag. cancelRefresh(ex); // Propagate exception to caller. throw ex; } finally { // Reset common introspection caches in Spring's core, since we // might not ever need metadata for singleton beans anymore... resetCommonCaches(); } }
事务配置的解析在上面的obtainFreshBeanFactory,由于我们使用的是ClassPathXmlApplicationContext 作为容器,它的解析类为:XmlBeanDefinitionReader;核心方法:
public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException { Assert.notNull(encodedResource, "EncodedResource must not be null"); if (logger.isInfoEnabled()) { logger.info("Loading XML bean definitions from " + encodedResource.getResource()); } Set<EncodedResource> currentResources = this.resourcesCurrentlyBeingLoaded.get(); if (currentResources == null) { currentResources = new HashSet<EncodedResource>(4); this.resourcesCurrentlyBeingLoaded.set(currentResources); } if (!currentResources.add(encodedResource)) { throw new BeanDefinitionStoreException( "Detected cyclic loading of " + encodedResource + " - check your import definitions!"); } try { // 读取 config.xml 文件 InputStream inputStream = encodedResource.getResource().getInputStream(); try { InputSource inputSource = new InputSource(inputStream); if (encodedResource.getEncoding() != null) { inputSource.setEncoding(encodedResource.getEncoding()); } // 开始加载 config.xml 文件中定义的bean,这里只是加载成BeanDefinition,初始化在另外的方法 return doLoadBeanDefinitions(inputSource, encodedResource.getResource()); } finally { inputStream.close(); } } catch (IOException ex) { throw new BeanDefinitionStoreException( "IOException parsing XML document from " + encodedResource.getResource(), ex); } finally { currentResources.remove(encodedResource); if (currentResources.isEmpty()) { this.resourcesCurrentlyBeingLoaded.remove(); } } }
doLoadBeanDefinitions 具体解析的方法是在org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader#doRegisterBeanDefinitions 中进行,该方法如下
protected void doRegisterBeanDefinitions(Element root) { // Any nested <beans> elements will cause recursion in this method. In // order to propagate and preserve <beans> default-* attributes correctly, // keep track of the current (parent) delegate, which may be null. Create // the new (child) delegate with a reference to the parent for fallback purposes, // then ultimately reset this.delegate back to its original (parent) reference. // this behavior emulates a stack of delegates without actually necessitating one. BeanDefinitionParserDelegate parent = this.delegate; this.delegate = createDelegate(getReaderContext(), root, parent); if (this.delegate.isDefaultNamespace(root)) { String profileSpec = root.getAttribute(PROFILE_ATTRIBUTE); if (StringUtils.hasText(profileSpec)) { String[] specifiedProfiles = StringUtils.tokenizeToStringArray( profileSpec, BeanDefinitionParserDelegate.MULTI_VALUE_ATTRIBUTE_DELIMITERS); if (!getReaderContext().getEnvironment().acceptsProfiles(specifiedProfiles)) { if (logger.isInfoEnabled()) { logger.info("Skipped XML bean definition file due to specified profiles [" + profileSpec + "] not matching: " + getReaderContext().getResource()); } return; } } } preProcessXml(root); // 真正解析config.xml文件 parseBeanDefinitions(root, this.delegate); postProcessXml(root); this.delegate = parent; } protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) { // 判断根节点是不是默认的节点,实际通过判断根节点的 namespaceURI 属性是不是 http://www.springframework.org/schema/beans , // 我们这里的配置文件声明的正好是这个属性,所以返回的是true,注意bean标签也是默认标签 if (delegate.isDefaultNamespace(root)) { // 获取子节点 NodeList nl = root.getChildNodes(); for (int i = 0; i < nl.getLength(); i++) { Node node = nl.item(i); // 判断子节点是不是标签 if (node instanceof Element) { Element ele = (Element) node; // bean标签的解析 if (delegate.isDefaultNamespace(ele)) { parseDefaultElement(ele, delegate); } // 重点:tx标签在这里进行 else { delegate.parseCustomElement(ele); } } } } else { delegate.parseCustomElement(root); } } // 解析非bean的标签 public BeanDefinition parseCustomElement(Element ele) { return parseCustomElement(ele, null); } // 解析非默认标签方法 public BeanDefinition parseCustomElement(Element ele, BeanDefinition containingBd) { String namespaceUri = getNamespaceURI(ele); // 这里是Spring使用了策略模式解析配置,通过namespaceUri匹配对应的处理类,也就是上面的关键类 TxNamespaceHandler, // 这里的resolve运用了懒加载,在获取映射关系handlerMappings属性为null时会从META-INF/spring.handlers 下面获取映射关系, // 由于IDEA debug的时候默认会调用getHandlerMappings方法,所以使用debug的时候会发现一开始就有值 NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri); if (handler == null) { error("Unable to locate Spring NamespaceHandler for XML schema namespace [" + namespaceUri + "]", ele); return null; } // 获取到处理类后,让处理类开始解析配置 return handler.parse(ele, new ParserContext(this.readerContext, this, containingBd)); }
TxNamespaceHandler 最终交给类 AnnotationDrivenBeanDefinitionParser 进行解析事务配置;
public BeanDefinition parse(Element element, ParserContext parserContext) { // 注册一个事务工厂事件,允许我们自定义监听事务的提交等操作 registerTransactionalEventListenerFactory(parserContext); String mode = element.getAttribute("mode"); // 如果使用的是 aspectj 方式,走这个方法 if ("aspectj".equals(mode)) { // mode="aspectj" registerTransactionAspect(element, parserContext); } else { // 默认使用的是代理模式 // mode="proxy" AopAutoProxyConfigurer.configureAutoProxyCreator(element, parserContext); } return null; } /** * Inner class to just introduce an AOP framework dependency when actually in proxy mode. */ private static class AopAutoProxyConfigurer { public static void configureAutoProxyCreator(Element element, ParserContext parserContext) { // 重点,注册 InfrastructureAdvisorAutoProxyCreator 的 BeanDefinition,这个是个关键类,代理业务bean的操作都靠它了 AopNamespaceUtils.registerAutoProxyCreatorIfNecessary(parserContext, element); String txAdvisorBeanName = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME; if (!parserContext.getRegistry().containsBeanDefinition(txAdvisorBeanName)) { Object eleSource = parserContext.extractSource(element); // 重点,注册一个全局的 TransactionAttributeSource 的BeanDefinition ,用于解析 @Transaction 定义的元数据 RootBeanDefinition sourceDef = new RootBeanDefinition( "org.springframework.transaction.annotation.AnnotationTransactionAttributeSource"); sourceDef.setSource(eleSource); sourceDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); String sourceName = parserContext.getReaderContext().registerWithGeneratedName(sourceDef); // 重点,注册 TransactionInterceptor 的BeanDefinition,这个就是事务真正执行的类,可以理解为是事务切面上的通知 RootBeanDefinition interceptorDef = new RootBeanDefinition(TransactionInterceptor.class); interceptorDef.setSource(eleSource); interceptorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); registerTransactionManager(element, interceptorDef); interceptorDef.getPropertyValues().add("transactionAttributeSource", new RuntimeBeanReference(sourceName)); String interceptorName = parserContext.getReaderContext().registerWithGeneratedName(interceptorDef); // 重点,注册 BeanFactoryTransactionAttributeSourceAdvisor 的BeanDefinition,可以理解为事务的切面, // 包含了切点(TransactionAttributeSourcePointcut) + 通知(TransactionInterceptor),保存在 ProxyFactory 中,用于生成代理对象 RootBeanDefinition advisorDef = new RootBeanDefinition(BeanFactoryTransactionAttributeSourceAdvisor.class); advisorDef.setSource(eleSource); advisorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); advisorDef.getPropertyValues().add("transactionAttributeSource", new RuntimeBeanReference(sourceName)); advisorDef.getPropertyValues().add("adviceBeanName", interceptorName); if (element.hasAttribute("order")) { advisorDef.getPropertyValues().add("order", element.getAttribute("order")); } parserContext.getRegistry().registerBeanDefinition(txAdvisorBeanName, advisorDef); CompositeComponentDefinition compositeDef = new CompositeComponentDefinition(element.getTagName(), eleSource); compositeDef.addNestedComponent(new BeanComponentDefinition(sourceDef, sourceName)); compositeDef.addNestedComponent(new BeanComponentDefinition(interceptorDef, interceptorName)); compositeDef.addNestedComponent(new BeanComponentDefinition(advisorDef, txAdvisorBeanName)); parserContext.registerComponent(compositeDef); } } }
到这里,事务配置的加载就结束了,上面的步骤只是将事务的关键类变成 BeanDefinition,实际上还没有生成Bean对象的,下面我们看下BeanDefinition 是如何变成Bean的(这一个步骤不是Spring事务独有的,是所有BeanDefinition 的共同逻辑),然后是如何生成业务bean代理对象并替换业务bean的。
2. 生成事务代理对象
入口在 1.解析并加载事务配置 列举的finishBeanFactoryInitialization(beanFactory) 方法中:
/** * Finish the initialization of this context's bean factory, * initializing all remaining singleton beans. */ protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) { // Initialize conversion service for this context. if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) && beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) { beanFactory.setConversionService( beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)); } // Register a default embedded value resolver if no bean post-processor // (such as a PropertyPlaceholderConfigurer bean) registered any before: // at this point, primarily for resolution in annotation attribute values. if (!beanFactory.hasEmbeddedValueResolver()) { beanFactory.addEmbeddedValueResolver(new StringValueResolver() { @Override public String resolveStringValue(String strVal) { return getEnvironment().resolvePlaceholders(strVal); } }); } // Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early. String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false); for (String weaverAwareName : weaverAwareNames) { getBean(weaverAwareName); } // Stop using the temporary ClassLoader for type matching. beanFactory.setTempClassLoader(null); // Allow for caching all bean definition metadata, not expecting further changes. beanFactory.freezeConfiguration(); // 重点,开始初始化所有非懒加载的bean beanFactory.preInstantiateSingletons(); }
beanFactory.preInstantiateSingletons() 具体方法如下:
public void preInstantiateSingletons() throws BeansException { if (this.logger.isDebugEnabled()) { this.logger.debug("Pre-instantiating singletons in " + this); } // Iterate over a copy to allow for init methods which in turn register new bean definitions. // While this may not be part of the regular factory bootstrap, it does otherwise work fine.将所有注册的BeanDefinition 名称保存到起来 List<String> beanNames = new ArrayList<String>(this.beanDefinitionNames); // Trigger initialization of all non-lazy singleton beans... for (String beanName : beanNames) { // 获取 BeanDefinition RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName); // bean定义不是抽象、懒加载而且是单例bean if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) { // 工厂bean特有逻辑,这不是我们的关注点,我们关注点是else的 getBean(beanName); if (isFactoryBean(beanName)) { final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName); boolean isEagerInit; if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) { isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() { @Override public Boolean run() { return ((SmartFactoryBean<?>) factory).isEagerInit(); } }, getAccessControlContext()); } else { isEagerInit = (factory instanceof SmartFactoryBean && ((SmartFactoryBean<?>) factory).isEagerInit()); } if (isEagerInit) { getBean(beanName); } } else { // 重点,将 BeanDefinition 创建成bean的核心方法,同时也是执行 BeanPostProcessor 的入口 getBean(beanName); } } } // Trigger post-initialization callback for all applicable beans... for (String beanName : beanNames) { Object singletonInstance = getSingleton(beanName); if (singletonInstance instanceof SmartInitializingSingleton) { final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance; if (System.getSecurityManager() != null) { AccessController.doPrivileged(new PrivilegedAction<Object>() { @Override public Object run() { smartSingleton.afterSingletonsInstantiated(); return null; } }, getAccessControlContext()); } else { smartSingleton.afterSingletonsInstantiated(); } } } }
getBean(beanName) 方法比较复杂,这里只列举出关键点:AbstractAutowireCapableBeanFactory 的 initializeBean方法,所有bean的创建都绕不开这个方法,这个方法是执行实现了 BeanPostProcessor 的bean的逻辑:
protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) { if (System.getSecurityManager() != null) { AccessController.doPrivileged(new PrivilegedAction<Object>() { @Override public Object run() { invokeAwareMethods(beanName, bean); return null; } }, getAccessControlContext()); } else { invokeAwareMethods(beanName, bean); } Object wrappedBean = bean; if (mbd == null || !mbd.isSynthetic()) { // 执行 BeanPostProcessor 的 postProcessBeforeInitialization 方法 wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); } try { invokeInitMethods(beanName, wrappedBean, mbd); } catch (Throwable ex) { throw new BeanCreationException( (mbd != null ? mbd.getResourceDescription() : null), beanName, "Invocation of init method failed", ex); } if (mbd == null || !mbd.isSynthetic()) { // 重点,InfrastructureAdvisorAutoProxyCreator 实现了BeanPostProcessor 接口,所以这里会调用 InfrastructureAdvisorAutoProxyCreator 的postProcessBeforeInitialization 方法, // wrappedBean 是生成代理后对象,wrappedBean 会替换掉传入的bean,如果当前bean需要事务,wrappedBean就是被JDK或者CGLIB代理后的bean wrappedBean = postProcessAfterInitialization(wrappedBean, beanName); } return wrappedBean; }
InfrastructureAdvisorAutoProxyCreator 的 postProcessAfterInitialization 定义在父类:AbstractAutoProxyCreator,AbstractAutoProxyCreator这个类同时是Spring AOP处理的入口,并不是说事务处理独有的,具体实现如下:
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { if (bean != null) { Object cacheKey = getCacheKey(bean.getClass(), beanName); if (!this.earlyProxyReferences.contains(cacheKey)) { // 重点,AOP生成代理对象的入口,这里也会生成事务代理对象 return wrapIfNecessary(bean, beanName, cacheKey); } } return bean; } // 从Spring容器中获取所有切面bean,并判断是否在切面中,如果是的话生成一个代理对象,怎么代理由具体的切面定义 protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) { if (beanName != null && this.targetSourcedBeans.contains(beanName)) { return bean; } if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) { return bean; } // 这里就是用来判断当前bean 能不能代理 if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) { this.advisedBeans.put(cacheKey, Boolean.FALSE); return bean; } // 首先查找切面Bean,对于本篇文章就是我们上面定义的 BeanFactoryTransactionAttributeSourceAdvisor 的 BeanDefinition,注意:实际应用场景肯定不仅只有一个切面的。 // spring现在只有BeanDefinition,这个方法先通过获取切面 beanNames ,然后再调用上面的 getBean 方法生成 BeanFactoryTransactionAttributeSourceAdvisor bean对象 Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null); // 需要代理,生成代理对象 if (specificInterceptors != DO_NOT_PROXY) { // 加入缓存中 this.advisedBeans.put(cacheKey, Boolean.TRUE); // 真正生成代理的地方 Object proxy = createProxy( bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean)); this.proxyTypes.put(cacheKey, proxy.getClass()); // 返回代理后的bean return proxy; } this.advisedBeans.put(cacheKey, Boolean.FALSE); // 不代理,返回原始bean return bean; } // 获取切面bean,先通过获取切面BeanNames ,然后通过获取bean protected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, TargetSource targetSource) { List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName); if (advisors.isEmpty()) { return DO_NOT_PROXY; } return advisors.toArray(); } protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) { // 这个方法就是获取切面bean,首先从容器中获取实现了 Advisor 的beanNames,然后通过beanName再获取Bean, // 对于本篇文章只定义了一个事务切面,所以这里返回的结果是 BeanFactoryTransactionAttributeSourceAdvisor Bean对象 List<Advisor> candidateAdvisors = findCandidateAdvisors(); // 判断当前bean是否能被切面应用,判断规则在下面有说明 List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName); extendAdvisors(eligibleAdvisors); if (!eligibleAdvisors.isEmpty()) { eligibleAdvisors = sortAdvisors(eligibleAdvisors); } return eligibleAdvisors; } // findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName) 具体实现逻辑在org.springframework.aop.support.AopUtils#findAdvisorsThatCanApply public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) { if (candidateAdvisors.isEmpty()) { return candidateAdvisors; } List<Advisor> eligibleAdvisors = new LinkedList<Advisor>(); for (Advisor candidate : candidateAdvisors) { if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) { eligibleAdvisors.add(candidate); } } boolean hasIntroductions = !eligibleAdvisors.isEmpty(); for (Advisor candidate : candidateAdvisors) { if (candidate instanceof IntroductionAdvisor) { // already processed continue; } if (canApply(candidate, clazz, hasIntroductions)) { eligibleAdvisors.add(candidate); } } return eligibleAdvisors; } // 请注意,这个方法是AOP通用判断是否能应用切面的方法,不是事务处理独有的 public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) { Assert.notNull(pc, "Pointcut must not be null"); // 首先判断类能不能匹配上,匹配不上就返回false, BeanFactoryTransactionAttributeSourceAdvisor 的切点类: // TransactionAttributeSourcePointcut,默认ClassFilter 返回true,所以这里不会进if if (!pc.getClassFilter().matches(targetClass)) { return false; } // 然后判断方法匹配,TransactionAttributeSourcePointcut 通过继承关系可以看到不是 MethodMatcher.TRUE,所以不会进if MethodMatcher methodMatcher = pc.getMethodMatcher(); if (methodMatcher == MethodMatcher.TRUE) { // No need to iterate the methods if we're matching any method anyway... return true; } // 判断是不是引介方法匹配,什么是引介增强:为目标类追加方法,属于类的增强, // 而 PointcutAdvisor 属于拦截目标类的方法并增强,TransactionAttributeSourcePointcut 是 PointcutAdvisor 的子类,不属于引介增强 IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null; if (methodMatcher instanceof IntroductionAwareMethodMatcher) { introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher; } // 开始读取目标类的每一个方法,判断是否在切面中 Set<Class<?>> classes = new LinkedHashSet<Class<?>>(ClassUtils.getAllInterfacesForClassAsSet(targetClass)); classes.add(targetClass); for (Class<?> clazz : classes) { Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz); for (Method method : methods) { // 对于事务而言,判断条件重点在 TransactionAttributeSourcePointcut 的 matches 方法 if ((introductionAwareMethodMatcher != null && introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions)) || methodMatcher.matches(method, targetClass)) { return true; } } } return false; } // TransactionAttributeSourcePointcut 的 matches 方法核心逻辑在 SpringTransactionAnnotationParser#parseTransactionAnnotation(java.lang.reflect.AnnotatedElement) // 注意:只会判断 public 的方法,判断有没有 Transactional 注解;判断的顺序为:先判断方法上面有没有,再判断类上面有没有。 // 判断核心就是看方法或类上面有没有 Transactional 注解,有这个注解就解析这个注解的元数据 public TransactionAttribute parseTransactionAnnotation(AnnotatedElement ae) { AnnotationAttributes attributes = AnnotatedElementUtils.getMergedAnnotationAttributes(ae, Transactional.class); if (attributes != null) { return parseTransactionAnnotation(attributes); } else { return null; } } // 解析 Transactional 注解元数据 protected TransactionAttribute parseTransactionAnnotation(AnnotationAttributes attributes) { RuleBasedTransactionAttribute rbta = new RuleBasedTransactionAttribute(); Propagation propagation = attributes.getEnum("propagation"); rbta.setPropagationBehavior(propagation.value()); Isolation isolation = attributes.getEnum("isolation"); rbta.setIsolationLevel(isolation.value()); rbta.setTimeout(attributes.getNumber("timeout").intValue()); rbta.setReadOnly(attributes.getBoolean("readOnly")); rbta.setQualifier(attributes.getString("value")); ArrayList<RollbackRuleAttribute> rollBackRules = new ArrayList<RollbackRuleAttribute>(); Class<?>[] rbf = attributes.getClassArray("rollbackFor"); for (Class<?> rbRule : rbf) { RollbackRuleAttribute rule = new RollbackRuleAttribute(rbRule); rollBackRules.add(rule); } String[] rbfc = attributes.getStringArray("rollbackForClassName"); for (String rbRule : rbfc) { RollbackRuleAttribute rule = new RollbackRuleAttribute(rbRule); rollBackRules.add(rule); } Class<?>[] nrbf = attributes.getClassArray("noRollbackFor"); for (Class<?> rbRule : nrbf) { NoRollbackRuleAttribute rule = new NoRollbackRuleAttribute(rbRule); rollBackRules.add(rule); } String[] nrbfc = attributes.getStringArray("noRollbackForClassName"); for (String rbRule : nrbfc) { NoRollbackRuleAttribute rule = new NoRollbackRuleAttribute(rbRule); rollBackRules.add(rule); } rbta.getRollbackRules().addAll(rollBackRules); return rbta; } // 以上就是 findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName) 的逻辑 // 下面回到wrapIfNecessary方法,如果当前bean需要生成代理对象,会调用下面的这个方法 protected Object createProxy( Class<?> beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource) { if (this.beanFactory instanceof ConfigurableListableBeanFactory) { AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass); } // 创建代理工厂,用于创建代理bean ProxyFactory proxyFactory = new ProxyFactory(); proxyFactory.copyFrom(this); // 判断是否配置了代理目标类,配置了这个选项会全部使用cglib代理 if (!proxyFactory.isProxyTargetClass()) { if (shouldProxyTargetClass(beanClass, beanName)) { proxyFactory.setProxyTargetClass(true); } else { evaluateProxyInterfaces(beanClass, proxyFactory); } } // 把所有的切面类放入 ProxyFactory Advisor[] advisors = buildAdvisors(beanName, specificInterceptors); proxyFactory.addAdvisors(advisors); proxyFactory.setTargetSource(targetSource); customizeProxyFactory(proxyFactory); proxyFactory.setFrozen(this.freezeProxy); if (advisorsPreFiltered()) { proxyFactory.setPreFiltered(true); } // 开始创建代理bean return proxyFactory.getProxy(getProxyClassLoader()); }
proxyFactory.getProxy(getProxyClassLoader()) 方法实现:
public Object getProxy(ClassLoader classLoader) { return createAopProxy().getProxy(classLoader); } // createAopProxy方法逻辑,config 其实就是上面的 proxyFactory 对象,这个对象包含了目标对象以及切面类: public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException { // optimize:代理是否应该执行优化,一般用不上 // proxyTargetClass:这个属性为treu时,不管目标类是不是实现的接口,都使用cglib代理 // hasNoUserSuppliedProxyInterfaces:是否只使用了Spring支持的代理接口,如果用户自定义了代理接口不能进行cglib代理 if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) { Class<?> targetClass = config.getTargetClass(); if (targetClass == null) { throw new AopConfigException("TargetSource cannot determine target class: " + "Either an interface or a target is required for proxy creation."); } // 如果目标类是接口或者已经被jdk代理过了,使用jdk代理 if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) { return new JdkDynamicAopProxy(config); } // 其他情况使用CGLIB代理 return new ObjenesisCglibAopProxy(config); } // 使用JDK代理 else { return new JdkDynamicAopProxy(config); } } // ObjenesisCglibAopProxy 的 getProxy(classLoader) 方法,cglib是使用Enhancer创建代理对象的 : public Object getProxy(ClassLoader classLoader) { if (logger.isDebugEnabled()) { logger.debug("Creating CGLIB proxy: target source is " + this.advised.getTargetSource()); } try { // 获取目标类 Class<?> rootClass = this.advised.getTargetClass(); Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy"); // 代理类的父类,默认是目标类 Class<?> proxySuperClass = rootClass; // 如果目标类以及是cglib代理类, if (ClassUtils.isCglibProxyClass(rootClass)) { // 取cglib代理类的父类作为代理类的父类 proxySuperClass = rootClass.getSuperclass(); // 获取代理类的接口追加到当前类的接口集合中 Class<?>[] additionalInterfaces = rootClass.getInterfaces(); for (Class<?> additionalInterface : additionalInterfaces) { this.advised.addInterface(additionalInterface); } } // 验证目标类是否能被代理,仅仅是打印日志,不做其他处理 validateClassIfNecessary(proxySuperClass, classLoader); // 使用Enhancer 来构造cglib代理对象 Enhancer enhancer = createEnhancer(); if (classLoader != null) { enhancer.setClassLoader(classLoader); if (classLoader instanceof SmartClassLoader && ((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) { enhancer.setUseCache(false); } } enhancer.setSuperclass(proxySuperClass); enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised)); enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE); enhancer.setStrategy(new ClassLoaderAwareUndeclaredThrowableStrategy(classLoader)); // 重点,设置回调的类,很重要的一个类 DynamicAdvisedInterceptor,这个类就是应用AOP 通知的地方,对于本篇文章就是应用TransactionInterceptor Callback[] callbacks = getCallbacks(rootClass); Class<?>[] types = new Class<?>[callbacks.length]; for (int x = 0; x < types.length; x++) { types[x] = callbacks[x].getClass(); } // fixedInterceptorMap only populated at this point, after getCallbacks call above enhancer.setCallbackFilter(new ProxyCallbackFilter( this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset)); enhancer.setCallbackTypes(types); // 创建代理类的字节码,并创建实例,实例设置回调 return createProxyClassAndInstance(enhancer, callbacks); } catch (CodeGenerationException ex) { throw new AopConfigException("Could not generate CGLIB subclass of " + this.advised.getTargetClass() + ": Common causes of this problem include using a final class or a non-visible class", ex); } catch (IllegalArgumentException ex) { throw new AopConfigException("Could not generate CGLIB subclass of " + this.advised.getTargetClass() + ": Common causes of this problem include using a final class or a non-visible class", ex); } catch (Throwable ex) { // TargetSource.getTarget() failed throw new AopConfigException("Unexpected AOP exception", ex); } } // JdkDynamicAopProxy 的 getProxy(classLoader) 方法:public Object getProxy(ClassLoader classLoader) { if (logger.isDebugEnabled()) { logger.debug("Creating JDK dynamic proxy: target source is " + this.advised.getTargetSource()); } Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true); findDefinedEqualsAndHashCodeMethods(proxiedInterfaces); return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this); }
通过2. 生成事务代理对象,此时创建的bean就是以及被JDK或者CGLIB代理的类,这一步是Spring AOP通用的处理逻辑,那具体是怎么运行的呢?
JDK动态代理运行:
// 本质是调用org.springframework.aop.framework.JdkDynamicAopProxy#invoke方法 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { MethodInvocation invocation; Object oldProxy = null; boolean setProxyContext = false; TargetSource targetSource = this.advised.targetSource; Class<?> targetClass = null; Object target = null; try { if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) { // The target does not implement the equals(Object) method itself. return equals(args[0]); } else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) { // The target does not implement the hashCode() method itself. return hashCode(); } else if (method.getDeclaringClass() == DecoratingProxy.class) { // There is only getDecoratedClass() declared -> dispatch to proxy config. return AopProxyUtils.ultimateTargetClass(this.advised); } else if (!this.advised.opaque && method.getDeclaringClass().isInterface() && method.getDeclaringClass().isAssignableFrom(Advised.class)) { // Service invocations on ProxyConfig with the proxy config... return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args); } Object retVal; if (this.advised.exposeProxy) { // Make invocation available if necessary. oldProxy = AopContext.setCurrentProxy(proxy); setProxyContext = true; } // May be null. Get as late as possible to minimize the time we "own" the target, // in case it comes from a pool. target = targetSource.getTarget(); if (target != null) { targetClass = target.getClass(); } // 获取方法的拦截器链,对于本篇文章就是关键类:BeanFactoryTransactionAttributeSourceAdvisor List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass); // Check whether we have any advice. If we don't, we can fallback on direct // reflective invocation of the target, and avoid creating a MethodInvocation. if (chain.isEmpty()) { // We can skip creating a MethodInvocation: just invoke the target directly // Note that the final invoker must be an InvokerInterceptor so we know it does // nothing but a reflective operation on the target, and no hot swapping or fancy proxying. Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args); retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse); } else { // 将所有参数:代理对象,目标对象,方法,参数,拦截器链封装到一个ReflectiveMethodInvocation对象中 invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain); // 然后调用ReflectiveMethodInvocation的proceed方法,会执行拦截器 retVal = invocation.proceed(); } // Massage return value if necessary. Class<?> returnType = method.getReturnType(); if (retVal != null && retVal == target && returnType != Object.class && returnType.isInstance(proxy) && !RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) { // Special case: it returned "this" and the return type of the method // is type-compatible. Note that we can't help if the target sets // a reference to itself in another returned object. retVal = proxy; } else if (retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) { throw new AopInvocationException( "Null return value from advice does not match primitive return type for: " + method); } return retVal; } finally { if (target != null && !targetSource.isStatic()) { // Must have come from TargetSource. targetSource.releaseTarget(target); } if (setProxyContext) { // Restore old proxy. AopContext.setCurrentProxy(oldProxy); } } }
org.springframework.aop.framework.ReflectiveMethodInvocation#proceed 方法:
public Object proceed() throws Throwable { // 所有拦截器调用完成,一般情况是没有匹配到任意的拦截器,这里会执行目标类本身的方法 if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) { return invokeJoinpoint(); } // 获取拦截器链中的第一个拦截器 Object interceptorOrInterceptionAdvice = this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex); // 通知器或通知是动态匹配方法拦截器类型,对于本篇文章,interceptorOrInterceptionAdvice 是TransactionInterceptor对象, // 所有走的是else,直接执行TransactionInterceptor的invoke方法 if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) { // 动态匹配方法拦截器 InterceptorAndDynamicMethodMatcher dm = (InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice; // 匹配成功就执行对应的拦截器 if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) { return dm.interceptor.invoke(this); } else { // 如果不匹配,就跳过此拦截器,递归执行下一个拦截器 return proceed(); } } else { // 如果是一个interceptor,直接调用这个interceptor对应的方法 return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this); } }
CGLIB代理运行:
// 其实就是创建代理对象时设置的回调类DynamicAdvisedInterceptor private static class DynamicAdvisedInterceptor implements MethodInterceptor, Serializable { private final AdvisedSupport advised; public DynamicAdvisedInterceptor(AdvisedSupport advised) { this.advised = advised; } // 主要是这个方法执行拦截,处理逻辑大致和JDK动态代理差不多,都是获取拦截器链, // 然后构建ReflectiveMethodInvocation的子类CglibMethodInvocation对象, // 执行ReflectiveMethodInvocation的proceed方法 @Override public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { Object oldProxy = null; boolean setProxyContext = false; Class<?> targetClass = null; Object target = null; try { if (this.advised.exposeProxy) { // Make invocation available if necessary. oldProxy = AopContext.setCurrentProxy(proxy); setProxyContext = true; } // May be null. Get as late as possible to minimize the time we // "own" the target, in case it comes from a pool... target = getTarget(); if (target != null) { targetClass = target.getClass(); } // 获取方法的拦截器链,对于本篇文章就是关键类:BeanFactoryTransactionAttributeSourceAdvisor List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass); Object retVal; // Check whether we only have one InvokerInterceptor: that is, // no real advice, but just reflective invocation of the target. if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) { // We can skip creating a MethodInvocation: just invoke the target directly. // Note that the final invoker must be an InvokerInterceptor, so we know // it does nothing but a reflective operation on the target, and no hot // swapping or fancy proxying. Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args); retVal = methodProxy.invoke(target, argsToUse); } else { // 将参数封装成CglibMethodInvocation对象并执行proceed方法,CglibMethodInvocation 其实是ReflectiveMethodInvocation的子类,可以理解为ReflectiveMethodInvocation是模板类,CglibMethodInvocation通过重写了部分方法,proceed是两种代理处理的共同逻辑 retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed(); } retVal = processReturnType(proxy, target, method, retVal); return retVal; } finally { if (target != null) { releaseTarget(target); } if (setProxyContext) { // Restore old proxy. AopContext.setCurrentProxy(oldProxy); } } } @Override public boolean equals(Object other) { return (this == other || (other instanceof DynamicAdvisedInterceptor && this.advised.equals(((DynamicAdvisedInterceptor) other).advised))); } /** * CGLIB uses this to drive proxy creation. */ @Override public int hashCode() { return this.advised.hashCode(); } protected Object getTarget() throws Exception { return this.advised.getTargetSource().getTarget(); } protected void releaseTarget(Object target) throws Exception { this.advised.getTargetSource().releaseTarget(target); } }
事务的最终执行类 TransactionInterceptor 的invoke 方法:
public Object invoke(final MethodInvocation invocation) throws Throwable { // Work out the target class: may be {@code null}. // The TransactionAttributeSource should be passed the target class // as well as the method, which may be from an interface. Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null); // Adapt to TransactionAspectSupport's invokeWithinTransaction... return invokeWithinTransaction(invocation.getMethod(), targetClass, new InvocationCallback() { @Override public Object proceedWithInvocation() throws Throwable { // 事务执行完毕后调用链继续向下执行 return invocation.proceed(); } }); } protected Object invokeWithinTransaction(Method method, Class<?> targetClass, final InvocationCallback invocation) throws Throwable { // 获取当前方法的事务属性 final TransactionAttribute txAttr = getTransactionAttributeSource().getTransactionAttribute(method, targetClass); // 获取事务管理器 final PlatformTransactionManager tm = determineTransactionManager(txAttr); // 方法名 final String joinpointIdentification = methodIdentification(method, targetClass, txAttr); // 如果方法没有事务或者事务管理器不属于CallbackPreferringPlatformTransactionManager,CallbackPreferringPlatformTransactionManager需要回调函数来实现事务流程,而我们常用的DataSourceTransactionManager就不是CallbackPreferringPlatformTransactionManager if (txAttr == null || !(tm instanceof CallbackPreferringPlatformTransactionManager)) { // 创建TransactionInfo事务对象,事务的管理都是通过TransactionInfo对象来完成,这里创建事务会使用到Spring的事务隔离级别,具体的逻辑可以自行查看 TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification); Object retVal = null; try { // 拦截器链继续向下执行 retVal = invocation.proceedWithInvocation(); } catch (Throwable ex) { // 抛出异常时提交或者回滚事务 completeTransactionAfterThrowing(txInfo, ex); throw ex; } finally { // 重置TransactionInfo 的 ThreadLocal cleanupTransactionInfo(txInfo); } // 提交/回滚事务 commitTransactionAfterReturning(txInfo); return retVal; } // else使用的是CallbackPreferringPlatformTransactionManager, else { // .......略 } }
总结
以上就是事务应用到业务场景中的原理,可以简单理解:Spring事务是在Spring AOP的基础上开发的,关注关键类:TransactionInterceptor 的实现就行了,不管是JDK动态代理还是CGLIB代理都是要用到这个类去提交/回滚事务的。如有错误欢迎指出。
欢迎收藏点赞关注!共同进步~ :)更多技术干货可关注【Java烂猪皮】公众号
作者: yangwqonly
原文出处:https://www.cnblogs.com/winkin/p/13667568.html?utm_source=tuicool&utm_medium=referral
版权声明: 本文为 InfoQ 作者【AI乔治】的原创文章。
原文链接:【http://xie.infoq.cn/article/2e03f34eebb0aba1092ccec49】。文章转载请联系作者。
AI乔治
分享后端技术干货。公众号【 Java烂猪皮】 2019.06.30 加入
一名默默无闻的扫地僧!
评论