Spring事务一:tx 标签

如果在spring中想根据Transactoional标签让代码赋能事务控制,最基础的使用方式是 tx:标签;那么标签是怎样起作用的呢

namespacehandler

我们来看看处理事务标签的namespacehandler:

org.springframework.transaction.config.TxNamespaceHandler
public class TxNamespaceHandler extends NamespaceHandlerSupport {
	static final String TRANSACTION_MANAGER_ATTRIBUTE = "transaction-manager";
	static final String DEFAULT_TRANSACTION_MANAGER_BEAN_NAME = "transactionManager";

	static String getTransactionManagerName(Element element) {
		return (element.hasAttribute(TRANSACTION_MANAGER_ATTRIBUTE) ?
				element.getAttribute(TRANSACTION_MANAGER_ATTRIBUTE) : DEFAULT_TRANSACTION_MANAGER_BEAN_NAME);
	}

	@Override
	public void init() {
		registerBeanDefinitionParser("advice", new TxAdviceBeanDefinitionParser());
		registerBeanDefinitionParser("annotation-driven", new AnnotationDrivenBeanDefinitionParser());
		registerBeanDefinitionParser("jta-transaction-manager", new JtaTransactionManagerBeanDefinitionParser());
	}
}

我们首先来分析一下:“annotation-driven”这个标签的解析;处理这个标签的类是org.springframework.transaction.config.AnnotationDrivenBeanDefinitionParser,parse方法会被自动调用;

	@Override
	public BeanDefinition parse(Element element, ParserContext parserContext) {
		registerTransactionalEventListenerFactory(parserContext);
		String mode = element.getAttribute("mode");
		if ("aspectj".equals(mode)) {
			// mode="aspectj"
			registerTransactionAspect(element, parserContext);
		}
		else {
			// mode="proxy"
			AopAutoProxyConfigurer.configureAutoProxyCreator(element, parserContext);
		}
		return null;
	}

逻辑很清晰:1、向容器中注入 TransactionalEventListenerFactory bean定义,该类主要功能是事务监控。

2、根据标签里的mode属性判断是注入“aspectj”模式还是 proxy模式,aspectj模式采用的是LTW(类加载时植入),需要javaagent(参考:百科例子);下面摘抄一段两者区别:

平常我们大部分的时候用的都是默认的模式(不写或者mode="proxy"),
proxy是代理模式,仅有外部方法调用才会被代理截获,自身方法调用,即使配置了@Transactional注解,
事务也无法生效,也不能应用在非public方法上;
而aspectj模式与代理模式不同,aspectj模式可以自身方法调用,也可以应用在非public上。

这里我们分析proxy模式(即代理生成的模式),主要方法是

org.springframework.transaction.config.AnnotationDrivenBeanDefinitionParser.AopAutoProxyConfigurer#configureAutoProxyCreator

该方法主要动作是向容器中注入了三个bean定义

public static void configureAutoProxyCreator(Element element, ParserContext parserContext) {
//@A
			AopNamespaceUtils.registerAutoProxyCreatorIfNecessary(parserContext, element);

			String txAdvisorBeanName = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME;
//@B
			if (!parserContext.getRegistry().containsBeanDefinition(txAdvisorBeanName)) {
				Object eleSource = parserContext.extractSource(element);

				// Create the TransactionAttributeSource definition.
				RootBeanDefinition sourceDef = new RootBeanDefinition(
						"org.springframework.transaction.annotation.AnnotationTransactionAttributeSource");
				sourceDef.setSource(eleSource);
				sourceDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
				String sourceName = parserContext.getReaderContext().registerWithGeneratedName(sourceDef);

				// Create the TransactionInterceptor definition.
				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);

				// Create the TransactionAttributeSourceAdvisor definition.
				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);
			}
		}

@A:判断容器中是否有代理生成的类,如果没有则注入相关的后置处理器

调用链如下:

org.springframework.aop.config.AopNamespaceUtils#registerAutoProxyCreatorIfNecessary

程序会判断容器中是否有名字为:

public static final String AUTO_PROXY_CREATOR_BEAN_NAME ="org.springframework.aop.config.internalAutoProxyCreator";

的bean定义,如果没有则向容器中注入一个类型为 InfrastructureAdvisorAutoProxyCreator的bean定义;这个类是一个后置处理器,会执行后续的代理生成;

 

@B: AnnotationTransactionAttributeSource,TransactionInterceptor,BeanFactoryTransactionAttributeSourceAdvisor注入了Advisor为后续生成代理做准备

InfrastructureAdvisorAutoProxyCreator

类图

可以看出 InfrastructureAdvisorAutoProxyCreator 是一个代理建造器也是一个bean后置处理器,父类中的AbstractAutoProxyCreator实现了后置处理器的 postProcessBeforeInstantiation、postProcessBeforeInitialization(对bean不做任何处理,直接返回)、postProcessAfterInitialization 方法;

postProcessBeforeInstantiation方法

该方法会在bean实例化前被调用,为代理生成提供入口;但是需要配置自定义的 TargetSource(即下面标注@A的代码),一般我们好像不这样使用;

@Override
	public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
		Object cacheKey = getCacheKey(beanClass, beanName);

		if (beanName == null || !this.targetSourcedBeans.contains(beanName)) {
			if (this.advisedBeans.containsKey(cacheKey)) {
				return null;
			}
			if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
				this.advisedBeans.put(cacheKey, Boolean.FALSE);
				return null;
			}
		}

		// Create proxy here if we have a custom TargetSource.
		// Suppresses unnecessary default instantiation of the target bean:
		// The TargetSource will handle target instances in a custom fashion.
		if (beanName != null) {
//@A
			TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
			if (targetSource != null) {
				this.targetSourcedBeans.add(beanName);
				Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
				Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
				this.proxyTypes.put(cacheKey, proxy.getClass());
				return proxy;
			}
		}

		return null;
	}

该方法会在 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#resolveBeforeInstantiation调用,这个方法如果返回了对象,后面会继续调用bean后置处理器处理返回的对象;

postProcessAfterInitialization

该方法会在真实类实例化后被调用

	@Override
	public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		if (bean != null) {
			Object cacheKey = getCacheKey(bean.getClass(), beanName);
			if (!this.earlyProxyReferences.contains(cacheKey)) {
//@A
				return wrapIfNecessary(bean, beanName, cacheKey);
			}
		}
		return bean;
	}

@A:该方法返回真实类的代理类

	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;
		}
		if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
			this.advisedBeans.put(cacheKey, Boolean.FALSE);
			return bean;
		}
//@A 根据当前的类,类名获得匹配的所有的拦截器
		// Create proxy if we have advice.
		Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
		if (specificInterceptors != DO_NOT_PROXY) {
			this.advisedBeans.put(cacheKey, Boolean.TRUE);
//@B 生成代理对象
			Object proxy = createProxy(
					bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
			this.proxyTypes.put(cacheKey, proxy.getClass());
			return proxy;
		}

		this.advisedBeans.put(cacheKey, Boolean.FALSE);
		return bean;
	}

@A:该方法主要是获得所有的拦截方法,返回对象实际是 List<Advisor> findEligibleAdvisors,真正实现的方法是

org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#findEligibleAdvisors

从这里可以看出,所有的AOP定义都被抽象成了Advisor(由PointCut,Advice组成),上面的 BeanFactoryTransactionAttributeSourceAdvisor就是一个Advisor

回到生成代理的方法:

org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#createProxy

------

protected Object createProxy(
			Class<?> beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource) {

		if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
			AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
		}

//创建一个ProxyFactory
		ProxyFactory proxyFactory = new ProxyFactory();
		proxyFactory.copyFrom(this);

		if (!proxyFactory.isProxyTargetClass()) {
			if (shouldProxyTargetClass(beanClass, beanName)) {
				proxyFactory.setProxyTargetClass(true);
			}
			else {
				evaluateProxyInterfaces(beanClass, proxyFactory);
			}
		}

//将所有的Advisor加入到proxyFactory中
		Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
		for (Advisor advisor : advisors) {
			proxyFactory.addAdvisor(advisor);
		}

		proxyFactory.setTargetSource(targetSource);
		customizeProxyFactory(proxyFactory);

		proxyFactory.setFrozen(this.freezeProxy);
		if (advisorsPreFiltered()) {
			proxyFactory.setPreFiltered(true);
		}

//创建代理类
		return proxyFactory.getProxy(getProxyClassLoader());
	}

方法来到

	public Object getProxy(ClassLoader classLoader) {
		return createAopProxy().getProxy(classLoader);
	}

这里分为两个部分,第一部分是确定 AopProxy即createAopProxy()方法,这个方法返回的目前就两种实现类:CglibAopProxy和JdkDynamicAopProxy,然后调用getProxy方法获得代理对象

おすすめ

転載: blog.csdn.net/Aqu415/article/details/108682388
おすすめ