如果在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方法获得代理对象