假如有一个Service叫ASerice,代码如下
@Service
public class AService {
@Transactional
public void doA() {
}
}
有一个Controller,叫AController,如下
@RestController
public class AController {
@Autowired
AService aService;
}
极简单的两个类。我们最常使用的场景。
题外话,AController和AService的实例化的关系
首先在应用启动时,一个叫做ConfigurationClassPostProcessor
的BeanDefinitionRegistryPostProcessor
会通过处理带有@ComponentScan
注释的@Configuration
类,扫描整个包,来将AController和AService都注册成为BeanDefinition。
紧接着,会调用AbstractApplicationContext#finishBeanFactoryInitialization
方法来实例化所有的BeanDefinition。
实例化的具体做法,是通过调用BeanFactory#getBean
方法来实现的。
因为BeanFactory#getBean
如果发现这个BeanDefinition还没有被实例化,就实例化之然后返回。
那我们假设AController
这个BeanDefinition先于AService
被实例化。
BeanFactory#getBean
最终会调用AbstractAutowireCapableBeanFactory#doCreateBean
来看代码
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
throws BeanCreationException {
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
// *** 先实例化这个Bean
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);
mbd.resolvedTargetType = beanType;
// Allow post-processors to modify the merged bean definition.
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}
// 此处省略代码》》》》》》
// Initialize the bean instance.
Object exposedObject = bean;
try {
// *** 在这里填充这个Bean
// *** 填充的内容包括@Autowired标签引入的其他的Bean等等
populateBean(beanName, mbd, instanceWrapper);
if (exposedObject != null) {
// *** 然后才会初始化Bean
// *** 初始化Bean包括四方面的内容
// *** 1. 调用各种Aware接口
// *** 2. 调用各个BeanPostProcessor的前处理
// *** 3. 真正自定义初始化,包括两种,1种是InitializingBean接口的行为,1种是自定义的init-method
// *** 4. 调用各个BeanPostProcessor的前处理
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
}
catch (Throwable ex) {
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex;
}
else {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
}
}
// 此处省略代码》》》》》》
// Register bean as disposable.
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}exposedObject;
}
以上的处理可以总结为
- 先创建
AController
类的一个实例 - 调用
MergedBeanDefinitionPostProcessor
- 调用
populateBean
来填充AController
的Bean实例 - 初始化
AController
的Bean
那跟今天主题有关的,重点是AbstractAutowireCapableBeanFactory#populateBean
方法。
protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
PropertyValues pvs = mbd.getPropertyValues();
// 此处省略代码》》》》》》
// Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
// state of the bean before properties are set. This can be used, for example,
// to support styles of field injection.
boolean continueWithPropertyPopulation = true;
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
continueWithPropertyPopulation = false;
break;
}
}
}
}
// 此处省略代码》》》》》》
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);
if (hasInstAwareBpps || needsDepCheck) {
PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
if (hasInstAwareBpps) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvs == null) {
return;
}
}
}
}
if (needsDepCheck) {
checkDependencies(beanName, mbd, filteredPds, pvs);
}
}
applyPropertyValues(beanName, mbd, bw, pvs);
}
在populateBean
方法中,给予InstantiationAwareBeanPostProcessor
被执行的机会。
可以看到会分别执行InstantiationAwareBeanPostProcessor
接口的2个方法。
InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation
InstantiationAwareBeanPostProcessor#postProcessPropertyValues
在容器中,有一个InstantiationAwareBeanPostProcessor
叫做AutowiredAnnotationBeanPostProcessor
,它就是用来处理Bean中的注入属性(基本上是通过识别几个注解来工作的:@Autowired,@Value,@Inject)。
它就是在这个时间点被调用。
那aService
作为aController
的一个属性,自然在这里就被处理了。
因为要为aController
的属性设值,自然要拿到aService
的实例。这样,又对aService
走了一遍BeanFactory#getBean
->createBean()。
注意,如果aService
在aController
之前被实例化,那么这里到getBean()就直接返回了,不会再去createBean了。
以上多少是题外话了,下面进入正题。
AOP的代理对象创建的时机
我们都知道,AOP是通过对原有的类创建代理类来实现的。
那代理类是什么时候被创建的呢。
既然DefaultListableBeanFactory
中保存了所有Bean的BeanDefinition
,和这些Bean的实例缓存singletonObjects
,那是否也保存了这些Bean的代理对象呢?如果不是,getBean
又是如何能得到代理对象而不是原有的实例的呢?
那我们从头说起。
刚才上面说了,第一次初始化一个Bean(Initialization)的时候,包括4个处理。
- 调用各种Aware接口
- 调用各个BeanPostProcessor的前处理
- 真正自定义初始化(包括两种,1种是InitializingBean接口的行为,1种是自定义的init-method)
- 调用各个BeanPostProcessor的前处理
关键就在这第4部。
容器中被注册了一个叫AnnotationAwareAspectJAutoProxyCreator
的BeanPostProcessor
。
每一个Bean在初始化的时候就都会被这个BeanPostProcessor
处理。顾名思义,这个BeanPostProcessor
的作用,就是创建代理对象的。
AnnotationAwareAspectJAutoProxyCreator#postProcessAfterInitialization
方法如下
/**
* Create a proxy with the configured interceptors if the bean is
* identified as one to proxy by the subclass.
* @see #getAdvicesAndAdvisorsForBean
*/
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (!this.earlyProxyReferences.contains(cacheKey)) {
// *** 在这里创建代理类(如果需要)
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
一句话总结,就是在Bean的初始化(Initialization)处理中,AnnotationAwareAspectJAutoProxyCreator
会通过创建代理类的实例来替换原有Bean。
也就是说,DefaultListableBeanFactory
的singletonObjects
缓存中,存放的就是代理类的对象。
AOP的实现方式就是这样的。通过BeanPostProcessor
来进行替换。
继续
还是上代码AbstractAutoProxyCreator#wrapIfNecessary
注意这一块是基类,也就是跟具体的aspect无关,所有的AOP都是走这个处理。
/**
* Wrap the given bean if necessary, i.e. if it is eligible for being proxied.
*/
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;
}
// Create proxy if we have advice.
// 在这里查找当前的Bean的所有可用的Advisor。
// 查找方式呢,就是把BeanFactory中所有的Advisor实例都找出来
// 然后再一一判断是否应该应用到这个Bean上
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
// 如果找到了advisor,那么就创建代理
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;
}
那这个找Advisor的具体实现也看一下
AbstractAdvisorAutoProxyCreator#getAdvicesAndAdvisorsForBean
,就是拿到这个Bean的所有advisor。
@Override
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();
}
继续
/**
* Find all eligible Advisors for auto-proxying this class.
*/
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
// 第一步先拿到容器中所有的advisor
List<Advisor> candidateAdvisors = findCandidateAdvisors();
// 第二步确定哪些advisor可以应用到这个Bean上
List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
extendAdvisors(eligibleAdvisors);
if (!eligibleAdvisors.isEmpty()) {
eligibleAdvisors = sortAdvisors(eligibleAdvisors);
}
return eligibleAdvisors;
}
先看第一步的代码(先拿到容器中所有的advisor)
/**
* Find all candidate Advisors to use in auto-proxying.
*/
protected List<Advisor> findCandidateAdvisors() {
return this.advisorRetrievalHelper.findAdvisorBeans();
}
这里用到了一个Help类。(这个Help对象最开始就被设置了BeanFactory成员)。
继续BeanFactoryAdvisorRetrievalHelper#findAdvisorBeans
/**
* Find all eligible Advisor beans in the current bean factory,
* ignoring FactoryBeans and excluding beans that are currently in creation.
*/
public List<Advisor> findAdvisorBeans() {
// Determine list of advisor bean names, if not cached already.
String[] advisorNames = null;
// 这里用到了缓存机制,只有第一次执行此方法的时候,才会调用BeanFactoryUtils.beanNamesForTypeIncludingAncestors
// 如果已经取过了,就把取到地advisor放到advisorNames中。
synchronized (this) {
advisorNames = this.cachedAdvisorBeanNames;
if (advisorNames == null) {
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the auto-proxy creator apply to them!
// 其实就是从BeanFactory中找到所有的Advisor类型的Bean
advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this.beanFactory, Advisor.class, true, false);
this.cachedAdvisorBeanNames = advisorNames;
}
}
if (advisorNames.length == 0) {
return new LinkedList<Advisor>();
}
// 下面就比较简单,Advisor其实就是Bean。在这里把Bean实例拿出来。
List<Advisor> advisors = new LinkedList<Advisor>();
for (String name : advisorNames) {
if (isEligibleBean(name)) {
if (this.beanFactory.isCurrentlyInCreation(name)) {
if (logger.isDebugEnabled()) {
logger.debug("Skipping currently created advisor '" + name + "'");
}
}
else {
try {
advisors.add(this.beanFactory.getBean(name, Advisor.class));
}
catch (BeanCreationException ex) {
Throwable rootCause = ex.getMostSpecificCause();
if (rootCause instanceof BeanCurrentlyInCreationException) {
BeanCreationException bce = (BeanCreationException) rootCause;
if (this.beanFactory.isCurrentlyInCreation(bce.getBeanName())) {
if (logger.isDebugEnabled()) {
logger.debug("Skipping advisor '" + name +
"' with dependency on currently created bean: " + ex.getMessage());
}
// Ignore: indicates a reference back to the bean we're trying to advise.
// We want to find advisors other than the currently created bean itself.
continue;
}
}
throw ex;
}
}
}
}
return advisors;
}
转过头来我们再看findEligibleAdvisors()
方法中的第二步findAdvisorsThatCanApply()
的代码
/**
* Search the given candidate Advisors to find all Advisors that
* can apply to the specified bean.
*/
protected List<Advisor> findAdvisorsThatCanApply(
List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {
ProxyCreationContext.setCurrentProxiedBeanName(beanName);
try {
// AopUtils的这个判断方法是核心
return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
}
finally {
ProxyCreationContext.setCurrentProxiedBeanName(null);
}
}
再来看AopUtils.findAdvisorsThatCanApply
的代码
/**
* Determine the sublist of the {@code candidateAdvisors} list
* that is applicable to the given class.
*/
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) {
// 关键在这里,canApply方法判断这个advisor可不可以用在这个class上
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;
}
再来看AopUtils.canApply
的代码
/**
* Can the given advisor apply at all on the given class?
* <p>This is an important test as it can be used to optimize out a advisor for a class.
* This version also takes into account introductions (for IntroductionAwareMethodMatchers).
*/
public static boolean canApply(Advisor advisor, Class<?> targetClass, boolean hasIntroductions) {
if (advisor instanceof IntroductionAdvisor) {
return ((IntroductionAdvisor) advisor).getClassFilter().matches(targetClass);
}
else if (advisor instanceof PointcutAdvisor) {
PointcutAdvisor pca = (PointcutAdvisor) advisor;
// 以PointcutAdvisor为例
// 那具体的判断代码我们就先不看了
// 日后再钻研
// 总之,是拿到所有的advisor,再从advisor中拿到pointcut,
// 通过逻辑判断当前Bean是否符合
return canApply(pca.getPointcut(), targetClass, hasIntroductions);
}
else {
// It doesn't have a pointcut so we assume it applies.
return true;
}
}
现在拿到了当前Bean的所有的Advisor了。
看AbstractAutoProxyCreator#wrapIfNecessary
中,拿到了advisor之后的createProxy
方法
注意这也是基类的方法。
/**
* Create an AOP proxy for the given bean.
*/
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 = new ProxyFactory();
proxyFactory.copyFrom(this);
if (!proxyFactory.isProxyTargetClass()) {
if (shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
}
else {
evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
proxyFactory.addAdvisors(advisors);
proxyFactory.setTargetSource(targetSource);
customizeProxyFactory(proxyFactory);
proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
// 在这里创建代理实例
return proxyFactory.getProxy(getProxyClassLoader());
}
这里把创建代理实例委托给了ProxyFactory
对象。
看看具体的创建代理实例的代码
ProxyFactory#getProxy(java.lang.ClassLoader)
/**
* Create a new proxy according to the settings in this factory.
* Can be called repeatedly. Effect will vary if we have added
* or removed interfaces. Can add and remove interceptors.
* Uses the given class loader (if necessary for proxy creation).
*/
public Object getProxy(ClassLoader classLoader) {
return createAopProxy().getProxy(classLoader);
}
createAopProxy()
返回以个AopProxy
对象
protected final synchronized AopProxy createAopProxy() {
if (!this.active) {
activate();
}
// 这里分两步
return getAopProxyFactory().createAopProxy(this);
}
那这个AopProxy
对象是通过工厂生成的。
getAopProxyFactory()
直接返回父类ProxyCreatorSupport
的DefaultAopProxyFactory
类型的成员,也就是工厂。
public ProxyCreatorSupport() {
this.aopProxyFactory = new DefaultAopProxyFactory();
}
而DefaultAopProxyFactory#createAopProxy(this)
的代码如下
@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
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的动态代理
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
// 如果没有接口则使用CGLIB的动态代理
return new ObjenesisCglibAopProxy(config);
}
else {
return new JdkDynamicAopProxy(config);
}
}
再回到ProxyFactory#getProxy(java.lang.ClassLoader)
的代码,就可以知道,会根据情况分别调用JdkDynamicAopProxy#getProxy()
或者ObjenesisCglibAopProxy#getProxy()
了。
下面就以JDK代理为例说明。
/**
* Construct a new JdkDynamicAopProxy for the given AOP configuration.
*/
public JdkDynamicAopProxy(AdvisedSupport config) throws AopConfigException {
Assert.notNull(config, "AdvisedSupport must not be null");
if (config.getAdvisors().length == 0 && config.getTargetSource() == AdvisedSupport.EMPTY_TARGET_SOURCE) {
throw new AopConfigException("No advisors and no TargetSource specified");
}
this.advised = config;
}
如上可以看到在构造方法中,是把config参数设置给了属性advised。
JdkDynamicAopProxy
本身实现了InvocationHandler
接口
而JdkDynamicAopProxy#getProxy()
方法则调用Proxy.newProxyInstance()
来创建代理对象。
@Override
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);
}
这样说来,关键就在JdkDynamicAopProxy#invoke()
方法了,因为invoke()
方法定义了代理类的行为
/**
* Implementation of {@code InvocationHandler.invoke}.
* <p>Callers will see exactly the exception thrown by the target,
* unless a hook method throws an exception.
*/
@Override
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 {
// 如果代理方法equals()被调用
if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
// The target does not implement the equals(Object) method itself.
return equals(args[0]);
}
// 如果代理方法hashCode()被调用
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();
}
// Get the interception chain for this method.
// 得到这个方法的拦截器链
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 {
// We need to create a method invocation...
// 使用chain的内容创建一个MethodInvocation对象
invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
// Proceed to the joinpoint through the interceptor chain.
// 执行这个MethodInvocation对象
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);
}
}
}
Transaction切面的设置(Spring Boot为例)
从Spring Boot应用的入口@SpringBootApplication
看起
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = {
@Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
......略
}
从语义上看,@EnableAutoConfiguration
是负责自动配置的。
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
......略
}
我们知道,ConfigurationClassPostProcessor
这个BDRPP会处理@Configuration
类的@Import
注解。
那@Import
注解是干什么的呢?
@Import
注解可以处理3种类型的Class。
- 普通的类,就当做
@Configuration
类来处理 ImportSelector
类型。把ImportSelect#selectImports()
返回的类型当做@Configuration
来处理DeferredImportSelector
类型。与2.相同。但是推迟到最后再处理。ImportBeanDefinitionRegistrar
类型。该接口提供了void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry)
行为用来自定义注册Bean的行为。
那AutoConfigurationImportSelector
其实是第3种,DeferredImportSelector
类型。
它的selectImports()
代码如下。
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
if (!isEnabled(annotationMetadata)) {
return NO_IMPORTS;
}
AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader
.loadMetadata(this.beanClassLoader);
AnnotationAttributes attributes = getAttributes(annotationMetadata);
// 得到所有的配置类
List<String> configurations = getCandidateConfigurations(annotationMetadata,
attributes);
// 去掉重复
configurations = removeDuplicates(configurations);
// 去掉应该排除掉的
Set<String> exclusions = getExclusions(annotationMetadata, attributes);
checkExcludedClasses(configurations, exclusions);
configurations.removeAll(exclusions);
configurations = filter(configurations, autoConfigurationMetadata);
fireAutoConfigurationImportEvents(configurations, exclusions);
return StringUtils.toStringArray(configurations);
}
也就是这里导入了很多@Configuration
类。
这其中就包括TransactionAutoConfiguration
。代码如下
@Configuration
@ConditionalOnClass(PlatformTransactionManager.class)
@AutoConfigureAfter({ JtaAutoConfiguration.class, HibernateJpaAutoConfiguration.class,
DataSourceTransactionManagerAutoConfiguration.class,
Neo4jDataAutoConfiguration.class })
@EnableConfigurationProperties(TransactionProperties.class)
public class TransactionAutoConfiguration {
@Bean
@ConditionalOnMissingBean
public TransactionManagerCustomizers platformTransactionManagerCustomizers(
ObjectProvider<List<PlatformTransactionManagerCustomizer<?>>> customizers) {
return new TransactionManagerCustomizers(customizers.getIfAvailable());
}
@Configuration
@ConditionalOnSingleCandidate(PlatformTransactionManager.class)
public static class TransactionTemplateConfiguration {
private final PlatformTransactionManager transactionManager;
public TransactionTemplateConfiguration(
PlatformTransactionManager transactionManager) {
this.transactionManager = transactionManager;
}
@Bean
@ConditionalOnMissingBean
public TransactionTemplate transactionTemplate() {
return new TransactionTemplate(this.transactionManager);
}
}
@Configuration
@ConditionalOnBean(PlatformTransactionManager.class)
@ConditionalOnMissingBean(AbstractTransactionManagementConfiguration.class)
public static class EnableTransactionManagementConfiguration {
// 这里用@ConditionalOnProperty注解提供了两个分支
// 如果属性文件中设置了spring.aop=false,则使用JdkDynamicAutoProxyConfiguration
// 如果属性文件中设置了spring.aop=true,或者没设置,则使用CglibAutoProxyConfiguration
@Configuration
@EnableTransactionManagement(proxyTargetClass = false)
@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "false", matchIfMissing = false)
public static class JdkDynamicAutoProxyConfiguration {
}
@Configuration
@EnableTransactionManagement(proxyTargetClass = true)
@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "true", matchIfMissing = true)
public static class CglibAutoProxyConfiguration {
}
}
}
如上可以看到,Spring Boot中默认是spring.aop.proxy-target-class
= true的,也就是强制使用CGLIB式的动态代理。
这跟原生的Spring是有区别的。
接下来看@EnableTransactionManagement
的代码。
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(TransactionManagementConfigurationSelector.class)
public @interface EnableTransactionManagement {
......省略
}
可以看到,又是@import
注解。
TransactionManagementConfigurationSelector
类的selectImports()
代码如下
public class TransactionManagementConfigurationSelector extends AdviceModeImportSelector<EnableTransactionManagement> {
/**
* Returns {@link ProxyTransactionManagementConfiguration} or
* {@code AspectJTransactionManagementConfiguration} for {@code PROXY}
* and {@code ASPECTJ} values of {@link EnableTransactionManagement#mode()},
* respectively.
*/
@Override
protected String[] selectImports(AdviceMode adviceMode) {
switch (adviceMode) {
// 实际上,这里的adviceMode=PROXY。具体为什么是PROXY以后再仔细看。
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;
}
}
}
那这里就注册了2个Bean,AutoProxyRegistrar
、ProxyTransactionManagementConfiguration
。
重点看第2个。还是配置类, 上代码。
这个类定义了一个Adviosr叫BeanFactoryTransactionAttributeSourceAdvisor
。
/**
* {@code @Configuration} class that registers the Spring infrastructure beans
* necessary to enable proxy-based annotation-driven transaction management.
*/
@Configuration
public class ProxyTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration {
// 定义Advisor
@Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor() {
BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();
advisor.setTransactionAttributeSource(transactionAttributeSource());
advisor.setAdvice(transactionInterceptor());
if (this.enableTx != null) {
advisor.setOrder(this.enableTx.<Integer>getNumber("order"));
}
return advisor;
}
@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public TransactionAttributeSource transactionAttributeSource() {
return new AnnotationTransactionAttributeSource();
}
// 定义Advice
@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public TransactionInterceptor transactionInterceptor() {
TransactionInterceptor interceptor = new TransactionInterceptor();
interceptor.setTransactionAttributeSource(transactionAttributeSource());
if (this.txManager != null) {
interceptor.setTransactionManager(this.txManager);
}
return interceptor;
}
}
终于我们知道了,这个Advisor(BeanFactoryTransactionAttributeSourceAdvisor
)的pointcut会对所有带有@Transactional
注解的方法生效,具体行为就是transactionInterceptor
。
AnnotationAwareAspectJAutoProxyCreator是如何注入的?
上面说了,AnnotationAwareAspectJAutoProxyCreator
是完成AOP的关键。
它是一个BPP,它会在第一个Bean的生命周期中的第3步
- 实例化
- populate,包括IABPP
- 初始化,包括BPP
中对Bean进行处理。
那AnnotationAwareAspectJAutoProxyCreator
是在哪里被注入的呢?
上面提到的TransactionManagementConfigurationSelector
注册了2个Bean:AutoProxyRegistrar
、ProxyTransactionManagementConfiguration
。
我们只讲了ProxyTransactionManagementConfiguration
。
那AutoProxyRegistrar
实现了什么呢?
/**
* Registers an {@link org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator
* AnnotationAwareAspectJAutoProxyCreator} against the current {@link BeanDefinitionRegistry}
* as appropriate based on a given @{@link EnableAspectJAutoProxy} annotation.
*/
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
/**
* Register, escalate, and configure the AspectJ auto proxy creator based on the value
* of the @{@link EnableAspectJAutoProxy#proxyTargetClass()} attribute on the importing
* {@code @Configuration} class.
*/
@Override
public void registerBeanDefinitions(
AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
// 在这里
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
AnnotationAttributes enableAspectJAutoProxy =
AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
if (enableAspectJAutoProxy != null) {
if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
}
if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
}
}
}
}
AopConfigUtils#registerAspectJAnnotationAutoProxyCreatorIfNecessary()
的代码如下
@Nullable
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(
BeanDefinitionRegistry registry, @Nullable Object source) {
// 在这里注入的AnnotationAwareAspectJAutoProxyCreator。
return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
}
这样我们就知道了,EnableTransactionManagement
注解会分兵两路,一路去注册BPP,一路去注册Advisor。
这两者合力完成了@Transational
注解的AOP。
PlatformTransactionManager和DataSource的注入时机
上面看到TransactionAutoConfiguration
这个类的注解上,其实还有DataSourceTransactionManagerAutoConfiguration
这个配置类。
@Configuration
@ConditionalOnClass({ JdbcTemplate.class, PlatformTransactionManager.class })
@AutoConfigureOrder(Ordered.LOWEST_PRECEDENCE)
@EnableConfigurationProperties(DataSourceProperties.class)
public class DataSourceTransactionManagerAutoConfiguration {
@Configuration
@ConditionalOnSingleCandidate(DataSource.class)
static class DataSourceTransactionManagerConfiguration {
private final DataSource dataSource;
private final TransactionManagerCustomizers transactionManagerCustomizers;
DataSourceTransactionManagerConfiguration(DataSource dataSource,
ObjectProvider<TransactionManagerCustomizers> transactionManagerCustomizers) {
this.dataSource = dataSource;
this.transactionManagerCustomizers = transactionManagerCustomizers
.getIfAvailable();
}
// 在这里注入一个关键的Bean
// transactionManager
@Bean
@ConditionalOnMissingBean(PlatformTransactionManager.class)
public DataSourceTransactionManager transactionManager(
DataSourceProperties properties) {
DataSourceTransactionManager transactionManager = new DataSourceTransactionManager(
this.dataSource);
if (this.transactionManagerCustomizers != null) {
this.transactionManagerCustomizers.customize(transactionManager);
}
return transactionManager;
}
}
}
如上可以看到在这里注入了transactionManager
@Transational
的AdviceTransactionInterceptor
都干了些什么
@Override
@Nullable
public Object invoke(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, invocation::proceed);
}
如上可以看到调了invokeWithinTransaction()
方法
/**
* General delegate for around-advice-based subclasses, delegating to several other template
* methods on this class. Able to handle {@link CallbackPreferringPlatformTransactionManager}
* as well as regular {@link PlatformTransactionManager} implementations.
*/
@Nullable
protected Object invokeWithinTransaction(Method method, @Nullable Class<?> targetClass,
final InvocationCallback invocation) throws Throwable {
// If the transaction attribute is null, the method is non-transactional.
// TransactionAttributeSource是一个Bean,是随着TransactionInterceptor一起被注入,
// 而且被设置成TransactionAttributeSource的一个属性
TransactionAttributeSource tas = getTransactionAttributeSource();
// 拿到这个方法的属性,属性呢,说的就是隔离级别和传播级别
final TransactionAttribute txAttr = (tas != null ? tas.getTransactionAttribute(method, targetClass) : null);
//
final PlatformTransactionManager tm = determineTransactionManager(txAttr);
final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);
if (txAttr == null || !(tm instanceof CallbackPreferringPlatformTransactionManager)) {
// Standard transaction demarcation with getTransaction and commit/rollback calls.
// 根据逻辑,来判断是否创建Transaction
// 这里面会进行判断txAttr里面的传播属性来进行具体的是否创建
TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);
Object retVal = null;
try {
// This is an around advice: Invoke the next interceptor in the chain.
// This will normally result in a target object being invoked.
// 执行原来的方法
retVal = invocation.proceedWithInvocation();
}
catch (Throwable ex) {
// target invocation exception
// 有异常的时候判断是commit还是rollback
completeTransactionAfterThrowing(txInfo, ex);
throw ex;
}
finally {
// 清理操作
cleanupTransactionInfo(txInfo);
}
// 如果没有异常,commit
commitTransactionAfterReturning(txInfo);
return retVal;
}
else {
final ThrowableHolder throwableHolder = new ThrowableHolder();
// It's a CallbackPreferringPlatformTransactionManager: pass a TransactionCallback in.
try {
Object result = ((CallbackPreferringPlatformTransactionManager) tm).execute(txAttr, status -> {
TransactionInfo txInfo = prepareTransactionInfo(tm, txAttr, joinpointIdentification, status);
try {
return invocation.proceedWithInvocation();
}
catch (Throwable ex) {
if (txAttr.rollbackOn(ex)) {
// A RuntimeException: will lead to a rollback.
if (ex instanceof RuntimeException) {
throw (RuntimeException) ex;
}
else {
throw new ThrowableHolderException(ex);
}
}
else {
// A normal return value: will lead to a commit.
throwableHolder.throwable = ex;
return null;
}
}
finally {
cleanupTransactionInfo(txInfo);
}
});
// Check result state: It might indicate a Throwable to rethrow.
if (throwableHolder.throwable != null) {
throw throwableHolder.throwable;
}
return result;
}
catch (ThrowableHolderException ex) {
throw ex.getCause();
}
catch (TransactionSystemException ex2) {
if (throwableHolder.throwable != null) {
logger.error("Application exception overridden by commit exception", throwableHolder.throwable);
ex2.initApplicationException(throwableHolder.throwable);
}
throw ex2;
}
catch (Throwable ex2) {
if (throwableHolder.throwable != null) {
logger.error("Application exception overridden by commit exception", throwableHolder.throwable);
}
throw ex2;
}
}
}
commitTransactionAfterReturning(txInfo)
就不看了,实际上就是在commit。
completeTransactionAfterThrowing(txInfo, ex)
则是把ex
传进去,然后根据ex
的种类决定是否rollback
。
/**
* Handle a throwable, completing the transaction.
* We may commit or roll back, depending on the configuration.
*/
protected void completeTransactionAfterThrowing(@Nullable TransactionInfo txInfo, Throwable ex) {
if (txInfo != null && txInfo.getTransactionStatus() != null) {
if (logger.isTraceEnabled()) {
logger.trace("Completing transaction for [" + txInfo.getJoinpointIdentification() +
"] after exception: " + ex);
}
// 如果ex应该rollback,则rollback
if (txInfo.transactionAttribute != null && txInfo.transactionAttribute.rollbackOn(ex)) {
try {
txInfo.getTransactionManager().rollback(txInfo.getTransactionStatus());
}
catch (TransactionSystemException ex2) {
logger.error("Application exception overridden by rollback exception", ex);
ex2.initApplicationException(ex);
throw ex2;
}
catch (RuntimeException | Error ex2) {
logger.error("Application exception overridden by rollback exception", ex);
throw ex2;
}
}
else { // 否则就commit
// We don't roll back on this exception.
// Will still roll back if TransactionStatus.isRollbackOnly() is true.
try {
txInfo.getTransactionManager().commit(txInfo.getTransactionStatus());
}
catch (TransactionSystemException ex2) {
logger.error("Application exception overridden by commit exception", ex);
ex2.initApplicationException(ex);
throw ex2;
}
catch (RuntimeException | Error ex2) {
logger.error("Application exception overridden by commit exception", ex);
throw ex2;
}
}
}
}
那看完了TransactionInterceptor
的行为的框架,来看细节,重要的是transaction的创建逻辑。也就是这一句
ransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);
看createTransactionIfNecessary()
的代码。
/**
* Create a transaction if necessary based on the given TransactionAttribute.
* <p>Allows callers to perform custom TransactionAttribute lookups through
* the TransactionAttributeSource.
*/
@SuppressWarnings("serial")
protected TransactionInfo createTransactionIfNecessary(@Nullable PlatformTransactionManager tm,
@Nullable TransactionAttribute txAttr, final String joinpointIdentification) {
// If no name specified, apply method identification as transaction name.
// 只是给transaction指定个名字而已
if (txAttr != null && txAttr.getName() == null) {
txAttr = new DelegatingTransactionAttribute(txAttr) {
@Override
public String getName() {
return joinpointIdentification;
}
};
}
TransactionStatus status = null;
if (txAttr != null) {
if (tm != null) {
// 拿到transaction
status = tm.getTransaction(txAttr);
}
else {
if (logger.isDebugEnabled()) {
logger.debug("Skipping transactional joinpoint [" + joinpointIdentification +
"] because no transaction manager has been configured");
}
}
}
return prepareTransactionInfo(tm, txAttr, joinpointIdentification, status);
}
那继续看AbstractPlatformTransactionManager#getTransaction()
的代码。
其实就是该不该创建transaction的逻辑。
/**
* This implementation handles propagation behavior. Delegates to
* {@code doGetTransaction}, {@code isExistingTransaction}
* and {@code doBegin}.
*/
@Override
public final TransactionStatus getTransaction(@Nullable TransactionDefinition definition) throws TransactionException {
// 首先拿到当前线程里的当前DataSource的transaction。
// 其实这里的逻辑比较重要,可以看看
Object transaction = doGetTransaction();
// Cache debug flag to avoid repeated checks.
boolean debugEnabled = logger.isDebugEnabled();
if (definition == null) {
// Use defaults if no transaction definition given.
definition = new DefaultTransactionDefinition();
}
// 如果是已经创建了transaction
// 那就要根据传播行为来判断是否创建新的transaction
if (isExistingTransaction(transaction)) {
// Existing transaction found -> check propagation behavior to find out how to behave.
return handleExistingTransaction(definition, transaction, debugEnabled);
}
// Check definition settings for new transaction.
if (definition.getTimeout() < TransactionDefinition.TIMEOUT_DEFAULT) {
throw new InvalidTimeoutException("Invalid transaction timeout", definition.getTimeout());
}
// No existing transaction found -> check propagation behavior to find out how to proceed.
// 既然现在没有被创建的transaction,那么还是根据传播级别来判断接下来的行为
if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_MANDATORY) {
throw new IllegalTransactionStateException(
"No existing transaction found for transaction marked with propagation 'mandatory'");
}
else if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRED ||
definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW ||
definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {
SuspendedResourcesHolder suspendedResources = suspend(null);
if (debugEnabled) {
logger.debug("Creating new transaction with name [" + definition.getName() + "]: " + definition);
}
try {
boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
DefaultTransactionStatus status = newTransactionStatus(
definition, transaction, true, newSynchronization, debugEnabled, suspendedResources);
doBegin(transaction, definition);
prepareSynchronization(status, definition);
return status;
}
catch (RuntimeException | Error ex) {
resume(null, suspendedResources);
throw ex;
}
}
else {
// Create "empty" transaction: no actual transaction, but potentially synchronization.
if (definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT && logger.isWarnEnabled()) {
logger.warn("Custom isolation level specified but no actual transaction initiated; " +
"isolation level will effectively be ignored: " + definition);
}
boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS);
return prepareTransactionStatus(definition, null, true, newSynchronization, debugEnabled, null);
}
}
那接下来看handleExistingTransaction()
的代码
/**
* Create a TransactionStatus for an existing transaction.
*/
private TransactionStatus handleExistingTransaction(
TransactionDefinition definition, Object transaction, boolean debugEnabled)
throws TransactionException {
// ......省略
if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NOT_SUPPORTED) {
// ......省略
// 如果传播行为是NOT_SUPPORT
// 那挂起原来的transaction,也不创建新的transaction
Object suspendedResources = suspend(transaction);
boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS);
return prepareTransactionStatus(
definition, null, false, newSynchronization, debugEnabled, suspendedResources);
}
if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW) {
// ......省略
// 如果传播行为时REQUIRE_NEW
// 则挂起原来的transaction,
// 创建一个新的transaction,并开始
SuspendedResourcesHolder suspendedResources = suspend(transaction);
try {
boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
DefaultTransactionStatus status = newTransactionStatus(
definition, transaction, true, newSynchronization, debugEnabled, suspendedResources);
doBegin(transaction, definition);
prepareSynchronization(status, definition);
return status;
}
catch (RuntimeException | Error beginEx) {
resumeAfterBeginException(transaction, suspendedResources, beginEx);
throw beginEx;
}
}
if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {
if (!isNestedTransactionAllowed()) {
throw new NestedTransactionNotSupportedException(
"Transaction manager does not allow nested transactions by default - " +
"specify 'nestedTransactionAllowed' property with value 'true'");
}
// ......省略
if (useSavepointForNestedTransaction()) {
// Create savepoint within existing Spring-managed transaction,
// through the SavepointManager API implemented by TransactionStatus.
// Usually uses JDBC 3.0 savepoints. Never activates Spring synchronization.
DefaultTransactionStatus status =
prepareTransactionStatus(definition, transaction, false, false, debugEnabled, null);
status.createAndHoldSavepoint();
return status;
}
else {
// Nested transaction through nested begin and commit/rollback calls.
// Usually only for JTA: Spring synchronization might get activated here
// in case of a pre-existing JTA transaction.
boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
DefaultTransactionStatus status = newTransactionStatus(
definition, transaction, true, newSynchronization, debugEnabled, null);
doBegin(transaction, definition);
prepareSynchronization(status, definition);
return status;
}
}
// Assumably PROPAGATION_SUPPORTS or PROPAGATION_REQUIRED.
// ......省略
if (isValidateExistingTransaction()) {
if (definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT) {
Integer currentIsolationLevel = TransactionSynchronizationManager.getCurrentTransactionIsolationLevel();
if (currentIsolationLevel == null || currentIsolationLevel != definition.getIsolationLevel()) {
Constants isoConstants = DefaultTransactionDefinition.constants;
throw new IllegalTransactionStateException("Participating transaction with definition [" +
definition + "] specifies isolation level which is incompatible with existing transaction: " +
(currentIsolationLevel != null ?
isoConstants.toCode(currentIsolationLevel, DefaultTransactionDefinition.PREFIX_ISOLATION) :
"(unknown)"));
}
}
if (!definition.isReadOnly()) {
if (TransactionSynchronizationManager.isCurrentTransactionReadOnly()) {
throw new IllegalTransactionStateException("Participating transaction with definition [" +
definition + "] is not marked as read-only but existing transaction is");
}
}
}
boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
return prepareTransactionStatus(definition, transaction, false, newSynchronization, debugEnabled, null);
}
那我们知道,其实这边的内容很简单。就是根据传播行为来判断是否创建新的transaction。
DataSourceTransactionManager#doGetTransaction()
的代码比较有意思。
到底是怎么拿到现有的transaction的呢?
@Override
protected Object doGetTransaction() {
// 可以看到TransactionObject这个对象总是被新创建的
DataSourceTransactionObject txObject = new DataSourceTransactionObject();
txObject.setSavepointAllowed(isNestedTransactionAllowed());
// 只不过其中的ConnectionHolder可能是旧的
ConnectionHolder conHolder =
(ConnectionHolder) TransactionSynchronizationManager.getResource(obtainDataSource());
txObject.setConnectionHolder(conHolder, false);
return txObject;
}
那就通过调TransactionSynchronizationManager.getResource(obtainDataSource())
来从dataSource中拿出Connection
/**
* Retrieve a resource for the given key that is bound to the current thread.
* @param key the key to check (usually the resource factory)
*/
@Nullable
public static Object getResource(Object key) {
// key就是dataSource
Object actualKey = TransactionSynchronizationUtils.unwrapResourceIfNecessary(key);
Object value = doGetResource(actualKey);
// ......省略
return value;
}
/**
* Actually check the value of the resource that is bound for the given key.
*/
@Nullable
private static Object doGetResource(Object actualKey) {
Map<Object, Object> map = resources.get();
if (map == null) {
return null;
}
// 可以看到是从一个map中,通过dataSource为key来拿到的
Object value = map.get(actualKey);
// Transparently remove ResourceHolder that was marked as void...
if (value instanceof ResourceHolder && ((ResourceHolder) value).isVoid()) {
map.remove(actualKey);
// Remove entire ThreadLocal if empty...
if (map.isEmpty()) {
resources.remove();
}
value = null;
}
return value;
}
那这个map
是什么呢?也就是resources
是什么呢?
private static final ThreadLocal<Map<Object, Object>> resources =
new NamedThreadLocal<>("Transactional resources");
可以看到,resources
是一个ThreadLocal
的实例。
那么对Connection的管理,就是通过ThreadLocal
在每个线程内用一个key是dataSource的Map
来管理。
那这个Map的内容是什么时候放进去的呢?逻辑上推断当然是一个新的连接创建的时候才会放进去。
看DataSourceTransactionManager#doBegin()
/**
* This implementation sets the isolation level but ignores the timeout.
*/
@Override
protected void doBegin(Object transaction, TransactionDefinition definition) {
DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;
Connection con = null;
try {
// 可以看如果transaction的对象里,没有连接的话,就拿到一个新连接
if (!txObject.hasConnectionHolder() ||
txObject.getConnectionHolder().isSynchronizedWithTransaction()) {
Connection newCon = obtainDataSource().getConnection();
if (logger.isDebugEnabled()) {
logger.debug("Acquired Connection [" + newCon + "] for JDBC transaction");
}
txObject.setConnectionHolder(new ConnectionHolder(newCon), true);
}
txObject.getConnectionHolder().setSynchronizedWithTransaction(true);
con = txObject.getConnectionHolder().getConnection();
Integer previousIsolationLevel = DataSourceUtils.prepareConnectionForTransaction(con, definition);
txObject.setPreviousIsolationLevel(previousIsolationLevel);
// Switch to manual commit if necessary. This is very expensive in some JDBC drivers,
// so we don't want to do it unnecessarily (for example if we've explicitly
// configured the connection pool to set it already).
if (con.getAutoCommit()) {
txObject.setMustRestoreAutoCommit(true);
if (logger.isDebugEnabled()) {
logger.debug("Switching JDBC Connection [" + con + "] to manual commit");
}
con.setAutoCommit(false);
}
prepareTransactionalConnection(con, definition);
txObject.getConnectionHolder().setTransactionActive(true);
int timeout = determineTimeout(definition);
if (timeout != TransactionDefinition.TIMEOUT_DEFAULT) {
txObject.getConnectionHolder().setTimeoutInSeconds(timeout);
}
// 可以看到在开始一个新的事务的时候,会把这个事务的连接装到ThreadLocal里面
// Bind the connection holder to the thread.
if (txObject.isNewConnectionHolder()) {
TransactionSynchronizationManager.bindResource(obtainDataSource(), txObject.getConnectionHolder());
}
}
catch (Throwable ex) {
if (txObject.isNewConnectionHolder()) {
DataSourceUtils.releaseConnection(con, obtainDataSource());
txObject.setConnectionHolder(null, false);
}
throw new CannotCreateTransactionException("Could not open JDBC Connection for transaction", ex);
}
}
总结一下。
容器启动的时候,
会有一个处理@Transactional
注解的Advisor(BeanFactoryTransactionAttributeSourceAdvisor
)被注册。那这个Advisor的Advice就是TransactionInterceptor
。
容器中被注册了一个叫AnnotationAwareAspectJAutoProxyCreator
的BeanPostProcessor
。
这个BPP会处理每一个Bean。给每一个Bean如果必要的情况下创建代理类的实例。
这个代理类重新定义了原有Bean的行为,具体就是找到可以应用到他们身上的Advisor,也就是BeanFactoryTransactionAttributeSourceAdvisor
,把这个advisor的行为额外附加在原有Bean的行为上。
那advisor的行为就是Advice了。
从结果上来说,就是Adviosr的Advice(TransactionInterceptor
)的invokeWithinTransaction()
方法来代替了原有的方法。
那最核心还是一个BPP:AnnotationAwareAspectJAutoProxyCreator
还有一个Advisor:BeanFactoryTransactionAttributeSourceAdvisor
那就到这儿吧。