Spring版本:5.2.0.RELEASE
Spring事务依赖spring-tx包,SpringBoot为我们自动配置了Spring AOP事务。在以往的SSM程序中,可能需要手动配置Spring事务,如下代码:
@EnableTransactionManagement
@Configuration
public class TxConfig {
@Bean
public DataSource dataSource() throws PropertyVetoException {
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setUser("xxx");
dataSource.setPassword("xxx");
dataSource.setDriverClass("xxx");
dataSource.setJdbcUrl("xxx");
return dataSource;
}
@Bean
public PlatformTransactionManager platformTransactionManager() throws PropertyVetoException {
return new DataSourceTransactionManager(dataSource());//放入数据源
}
}
对于事务方法,只需要再加上@Transactional注解即可。Spring事务依赖数据源,并通过数据源注入一个平台事务管理器PlatformTransactionManager。而SpringBoot之后,仅仅需要在方法上加@Transactional注解即可实现事务,本质上,它通过数据源自动配置事务,完成了传统的@EnableTransactionManagement所实现的配置事务功能。于是从@EnableTransactionManagement注解实现事务源码开始。
入口程序:
@EnableTransactionManagement
@MapperScan("com.chen.mapper")
@SpringBootApplication(exclude = TransactionAutoConfiguration.class)
@EnableWebMvc
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
}
排除了TransactionAutoConfiguration.class,即排除了SpringBoot自动配置事务,这种方式和传统SSM事务配置方式一样了。由于没有排除DataSourceAutoConfiguration.class,依然采用了SpringBoot自动配置数据源。因此,这种方式就是spring-tx包通过@EnableTransactionManagement实现声明式事务。接下来逐步分析源码:
1、@EnableTransactionManagement注解通过@Import向Spring导入组件。
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(TransactionManagementConfigurationSelector.class)
public @interface EnableTransactionManagement {
boolean proxyTargetClass() default false;
AdviceMode mode() default AdviceMode.PROXY; //PROXY
int order() default Ordered.LOWEST_PRECEDENCE;
}
public class TransactionManagementConfigurationSelector extends AdviceModeImportSelector<EnableTransactionManagement> {
@Override
protected String[] selectImports(AdviceMode adviceMode) {
switch (adviceMode) {
case PROXY:
//导入2个组件AutoProxyRegistrar和ProxyTransactionManagementConfiguration
return new String[] {AutoProxyRegistrar.class.getName(),
ProxyTransactionManagementConfiguration.class.getName()};
case ASPECTJ:
return new String[] {determineTransactionAspectClass()};
default:
return null;
}
}
}
2、接下来看AutoProxyRegistrar类,可以看到它实现了ImportBeanDefinitionRegistrar接口:
public class AutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
private final Log logger = LogFactory.getLog(getClass());
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
boolean candidateFound = false;
//获取Spring容器中全部的组件导入类上的注解名,可简单理解成获取标记了@Configuration注解类上的全部注解名,由于开启事务启动类上标记了@EnableTransactionManagement注解,因此这个注解名也被扫描到。
Set<String> annTypes = importingClassMetadata.getAnnotationTypes();
for (String annType : annTypes) {
//封装注解的元数据属性成AnnotationAttributes对象,注解元数据属性可能有多个
//采用了Map缓存,具体可以点进去看。从Map取,取不到再去容器遍历,得到的注解名放入Map。
AnnotationAttributes candidate = AnnotationConfigUtils.attributesFor(importingClassMetadata, annType);
if (candidate == null) {
continue;
}
Object mode = candidate.get("mode");
Object proxyTargetClass = candidate.get("proxyTargetClass");
if (mode != null && proxyTargetClass != null && AdviceMode.class == mode.getClass() &&
Boolean.class == proxyTargetClass.getClass()) {
candidateFound = true;
if (mode == AdviceMode.PROXY) {
//Spring AOP核心实现
AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry);
if ((Boolean) proxyTargetClass) {
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
return;
}
}
}
}
}
}
public interface ImportBeanDefinitionRegistrar {
default void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry,
BeanNameGenerator importBeanNameGenerator) {
registerBeanDefinitions(importingClassMetadata, registry);
}
//根据@Configuration配置类的注解元信息注册Bean的定义器。比如:项目启动类上注解@SpringBootApplication是不是包含了@Configuration?那么实现这个接口的类,可将@EnableTransactionManagement中的注解元信息注册为BeanDefinition。
default void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
}
}
[2.1]接下来重点看AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry)方法:
//方法最终调用来到这里,接收前面传过来的BeanDefinitionRegistry,可以把它看成存储BeanDefinition的仓库。
@Nullable
private static BeanDefinition registerOrEscalateApcAsRequired(
Class<?> cls, BeanDefinitionRegistry registry, @Nullable Object source) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
if (!cls.getName().equals(apcDefinition.getBeanClassName())) {
int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());
int requiredPriority = findPriorityForClass(cls);
if (currentPriority < requiredPriority) {
apcDefinition.setBeanClassName(cls.getName());
}
}
return null;
}
//初次执行registry并不包含cls的BeanDefinition,进行创建
RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
beanDefinition.setSource(source);
beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
//往容器中注入cls类实例,beanName为AUTO_PROXY_CREATOR_BEAN_NAME,静态常量定义了值为"org.springframework.aop.config.internalAutoProxyCreator"
registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
return beanDefinition;
}
[2.2]接下来分析,往容器中注册的Bean Name=org.springframework.aop.config.internalAutoProxyCreator的组件InfrastructureAdvisorAutoProxyCreator能为我们做什么。首先看它的类继承树关系:
BeanPostProcessor
|--InstantiationAwareBeanPostProcessor
|--SmartInstantiationAwareBeanPostProcessor
|--AbstractAutoProxyCreator
|--AbstractAdvisorAutoProxyCreator
|--InfrastructureAdvisorAutoProxyCreator
可以看到InfrastructureAdvisorAutoProxyCreator向上继承了2个抽象父类并且实现了2个接口。AbstractAutoProxyCreator完全实现了BeanPostProcessor和InstantiationAwareBeanPostProcessor接口。 两个接口以及对它的实现如下:
public interface BeanPostProcessor {
//Bean初始化之前调用
@Nullable
default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
//Bean初始化之后调用
@Nullable
default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
}
public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {
//Bean实例化之前调用
@Nullable
default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
return null;
}
//Bean实例化之前调用
default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
return true;
}
@Nullable
default PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName)
throws BeansException {
return null;
}
@Deprecated
@Nullable
default PropertyValues postProcessPropertyValues(
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
return pvs;
}
}
4个方法的执行顺序如下:
实例化之前==================>:myBean
实例化之后==================>:myBean
初始化前===========>:myBean
初始化后===========>:myBean
接下来,跳到Spring容器启动源码,证实这4个接口方法调用时机:
====================Spring容器启动迭代BeanPostProcessor调用这4个接口方法====================
①InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation():
@Nullable
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
//Bean实例化之前,遍历InstantiationAwareBeanPostProcessor,调用其ostProcessBeforeInstantiation()方法。
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
if (result != null) {
return result;
}
}
}
return null;
}
方法调用链如下:
SpringAppplication.run(App.class, args)——>
SpringApplication.refreshContext(context)——>
AbstractApplicationContext.refresh()——>
AbstractApplicationContext.finishBeanFactoryInitialization(beanFactory)——>
DefaultListableBeanFactory.preInstantiateSingletons()——>
AbstractBeanFactory.doGetBean(String name, @Nullable Class requiredType, @Nullable Object[] args, boolean typeCheckOnly)——>
AbstractAutowireCapableBeanFactory.createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)——>
AbstractAutowireCapableBeanFactory.resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd)——>
AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName)
②InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation():
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
if (bw == null) {
if (mbd.hasPropertyValues()) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
}
else {
// Skip property population phase for null instance.
return;
}
}
// 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()) {
//实例化Bean之后,在populateBean()放法中,遍历InstantiationAwareBeanPostProcessor并调用其postProcessAfterInstantiation()方法。
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
continueWithPropertyPopulation = false;
break;
}
}
}
}
if (!continueWithPropertyPopulation) {
return;
}
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
int resolvedAutowireMode = mbd.getResolvedAutowireMode();
if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// Add property values based on autowire by name if applicable.
if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
// Add property values based on autowire by type if applicable.
if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
PropertyDescriptor[] filteredPds = null;
if (hasInstAwareBpps) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
return;
}
}
pvs = pvsToUse;
}
}
}
if (needsDepCheck) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
checkDependencies(beanName, mbd, filteredPds, pvs);
}
if (pvs != null) {
applyPropertyValues(beanName, mbd, bw, pvs);
}
}
方法调用链如下:
SpringAppplication.run(App.class, args)——>
SpringApplication.refreshContext(context)——>
AbstractApplicationContext.refresh()——>
AbstractApplicationContext.finishBeanFactoryInitialization(beanFactory)——>
DefaultListableBeanFactory.preInstantiateSingletons()——>
AbstractBeanFactory.doGetBean(String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)——>
AbstractAutowireCapableBeanFactory.createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)——>
AbstractAutowireCapableBeanFactory.doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)——>
AbstractAutowireCapableBeanFactory.populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw)
③BeanPostProcessor.postProcessBeforeInitialization():
@Override
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
//Bean初始化之前,遍历BeanPostProcessor,调用其postProcessBeforeInitialization()方法。
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessBeforeInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
方法调用链如下:
SpringAppplication.run(App.class, args)——>
SpringApplication.refreshContext(context)——>
AbstractApplicationContext.refresh()——>
AbstractApplicationContext.finishBeanFactoryInitialization(beanFactory)——>
DefaultListableBeanFactory.preInstantiateSingletons()——>
AbstractBeanFactory.doGetBean(String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)——>
AbstractAutowireCapableBeanFactory.createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)——>
AbstractAutowireCapableBeanFactory.doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)——>
AbstractAutowireCapableBeanFactory.initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd)——>
AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
④BeanPostProcessor.postProcessAfterInitialization():
@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
//Bean初始化之后,调用BeanPostProcessor,调用其postProcessAfterInitialization()方法。
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
方法调用链如下:
SpringAppplication.run(App.class, args)——>
SpringApplication.refreshContext(context)——>
AbstractApplicationContext.refresh()——>
AbstractApplicationContext.finishBeanFactoryInitialization(beanFactory)——>
DefaultListableBeanFactory.preInstantiateSingletons()——>
AbstractBeanFactory.doGetBean(String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)——>
AbstractAutowireCapableBeanFactory.createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)——>
AbstractAutowireCapableBeanFactory.doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)——>
AbstractAutowireCapableBeanFactory.initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd)——>
AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
====================Spring容器启动迭代BeanPostProcessor调用这4个接口方法==================== Spring容器启动时,会在run()方法调用到refresh()方法,遍历容器中的BeanPostProcessor实现,按规则顺序调用这些方法(本篇重点讲SpringAOP事务实现,对Spring容器启动源码分析放到后面,先挑关键代码片段知道这个结论就行)。于是我们再来分析往容器中注册的InternalAutoProxyCreator,由于它实现了上面2个接口的4个方法,因此Spring容器启动,在实例化和初始化Bean前后,会依次执行InternalAutoProxyCreator的这4个实现方法,因此这个InfrastructureAdvisorAutoProxyCreator对容器中注册的Bean在其实例化前后、初始化前后做了增强。
InfrastructureAdvisorAutoProxyCreator对接口的实现全部继承自父抽象类AbstractAutoProxyCreator,下面来看这个类怎么扩展Bean的。
AbstractAutoProxyCreator
#postProcessBeforeInstantiation(Class<?> beanClass, String beanName)
#postProcessAfterInstantiation(Object bean, String beanName)
#postProcessBeforeInitialization(Object bean, String beanName)
#postProcessAfterInitialization(@Nullable Object bean, String beanName)
采用了模板方法设计模式,抽象父类实现其子类共性方法,暴露需要抽象父类其自身子类需要实现的特性方法。于是来看其抽象父类AbstractAutoProxyCreator对这两个接口的实现:
public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {
@Nullable
protected static final Object[] DO_NOT_PROXY = null;
protected static final Object[] PROXY_WITHOUT_ADDITIONAL_INTERCEPTORS = new Object[0];
protected final Log logger = LogFactory.getLog(this.getClass());
private AdvisorAdapterRegistry advisorAdapterRegistry = GlobalAdvisorAdapterRegistry.getInstance();
private boolean freezeProxy = false;
private String[] interceptorNames = new String[0];
private boolean applyCommonInterceptorsFirst = true;
@Nullable
private TargetSourceCreator[] customTargetSourceCreators;
@Nullable
private BeanFactory beanFactory;
private final Set<String> targetSourcedBeans = Collections.newSetFromMap(new ConcurrentHashMap(16));
private final Map<Object, Object> earlyProxyReferences = new ConcurrentHashMap(16);
private final Map<Object, Class<?>> proxyTypes = new ConcurrentHashMap(16);
private final Map<Object, Boolean> advisedBeans = new ConcurrentHashMap(256);
public AbstractAutoProxyCreator() {
}
public void setFrozen(boolean frozen) {
this.freezeProxy = frozen;
}
public boolean isFrozen() {
return this.freezeProxy;
}
public void setAdvisorAdapterRegistry(AdvisorAdapterRegistry advisorAdapterRegistry) {
this.advisorAdapterRegistry = advisorAdapterRegistry;
}
public void setCustomTargetSourceCreators(TargetSourceCreator... targetSourceCreators) {
this.customTargetSourceCreators = targetSourceCreators;
}
public void setInterceptorNames(String... interceptorNames) {
this.interceptorNames = interceptorNames;
}
public void setApplyCommonInterceptorsFirst(boolean applyCommonInterceptorsFirst) {
this.applyCommonInterceptorsFirst = applyCommonInterceptorsFirst;
}
public void setBeanFactory(BeanFactory beanFactory) {
this.beanFactory = beanFactory;
}
@Nullable
protected BeanFactory getBeanFactory() {
return this.beanFactory;
}
@Nullable
public Class<?> predictBeanType(Class<?> beanClass, String beanName) {
if (this.proxyTypes.isEmpty()) {
return null;
} else {
Object cacheKey = this.getCacheKey(beanClass, beanName);
return (Class)this.proxyTypes.get(cacheKey);
}
}
@Nullable
public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName) {
return null;
}
public Object getEarlyBeanReference(Object bean, String beanName) {
Object cacheKey = this.getCacheKey(bean.getClass(), beanName);
this.earlyProxyReferences.put(cacheKey, bean);
return this.wrapIfNecessary(bean, beanName, cacheKey);
}
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
Object cacheKey = this.getCacheKey(beanClass, beanName);
if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
if (this.advisedBeans.containsKey(cacheKey)) {
return null;
}
if (this.isInfrastructureClass(beanClass) || this.shouldSkip(beanClass, beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return null;
}
}
//判断是否为目标类自定义TargetSource,如果存在创建自定义逻辑的代理类
TargetSource targetSource = this.getCustomTargetSource(beanClass, beanName);
if (targetSource != null) {
if (StringUtils.hasLength(beanName)) {
this.targetSourcedBeans.add(beanName);
}
Object[] specificInterceptors = this.getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
Object proxy = this.createProxy(beanClass, beanName, specificInterceptors, targetSource);
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
} else {
return null;
}
}
public boolean postProcessAfterInstantiation(Object bean, String beanName) {
return true;
}
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
return pvs;
}
public Object postProcessBeforeInitialization(Object bean, String beanName) {
return bean;
}
//重点看这个方法,从缓存中取出beanName,earlyProxyReferences保存已经创建代理对象的Bean,
//由于Bean还并未创建代理因此remove()方法返回的不是bean本身,因此条件满足进入wrapIfNecessary方法
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
if (bean != null) {
Object cacheKey = this.getCacheKey(bean.getClass(), beanName);
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
return this.wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
protected Object getCacheKey(Class<?> beanClass, @Nullable String beanName) {
if (StringUtils.hasLength(beanName)) {
return FactoryBean.class.isAssignableFrom(beanClass) ? "&" + beanName : beanName;
} else {
return beanClass;
}
}
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
return bean;
} else if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
} else if (!this.isInfrastructureClass(bean.getClass()) && !this.shouldSkip(bean.getClass(), beanName)) {
Object[] specificInterceptors = this.getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, (TargetSource)null);
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
Object proxy = this.createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
} else {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
} else {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
}
protected boolean isInfrastructureClass(Class<?> beanClass) {
boolean retVal = Advice.class.isAssignableFrom(beanClass) || Pointcut.class.isAssignableFrom(beanClass) || Advisor.class.isAssignableFrom(beanClass) || AopInfrastructureBean.class.isAssignableFrom(beanClass);
if (retVal && this.logger.isTraceEnabled()) {
this.logger.trace("Did not attempt to auto-proxy infrastructure class [" + beanClass.getName() + "]");
}
return retVal;
}
protected boolean shouldSkip(Class<?> beanClass, String beanName) {
return AutoProxyUtils.isOriginalInstance(beanName, beanClass);
}
@Nullable
protected TargetSource getCustomTargetSource(Class<?> beanClass, String beanName) {
if (this.customTargetSourceCreators != null && this.beanFactory != null && this.beanFactory.containsBean(beanName)) {
TargetSourceCreator[] var3 = this.customTargetSourceCreators;
int var4 = var3.length;
for(int var5 = 0; var5 < var4; ++var5) {
TargetSourceCreator tsc = var3[var5];
TargetSource ts = tsc.getTargetSource(beanClass, beanName);
if (ts != null) {
if (this.logger.isTraceEnabled()) {
this.logger.trace("TargetSourceCreator [" + tsc + "] found custom TargetSource for bean with name '" + beanName + "'");
}
return ts;
}
}
}
return null;
}
protected Object createProxy(Class<?> beanClass, @Nullable String beanName, @Nullable 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 (this.shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
} else {
this.evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
Advisor[] advisors = this.buildAdvisors(beanName, specificInterceptors);
proxyFactory.addAdvisors(advisors);
proxyFactory.setTargetSource(targetSource);
this.customizeProxyFactory(proxyFactory);
proxyFactory.setFrozen(this.freezeProxy);
if (this.advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
return proxyFactory.getProxy(this.getProxyClassLoader());
}
protected boolean shouldProxyTargetClass(Class<?> beanClass, @Nullable String beanName) {
return this.beanFactory instanceof ConfigurableListableBeanFactory && AutoProxyUtils.shouldProxyTargetClass((ConfigurableListableBeanFactory)this.beanFactory, beanName);
}
protected boolean advisorsPreFiltered() {
return false;
}
protected Advisor[] buildAdvisors(@Nullable String beanName, @Nullable Object[] specificInterceptors) {
Advisor[] commonInterceptors = this.resolveInterceptorNames();
List<Object> allInterceptors = new ArrayList();
if (specificInterceptors != null) {
allInterceptors.addAll(Arrays.asList(specificInterceptors));
if (commonInterceptors.length > 0) {
if (this.applyCommonInterceptorsFirst) {
allInterceptors.addAll(0, Arrays.asList(commonInterceptors));
} else {
allInterceptors.addAll(Arrays.asList(commonInterceptors));
}
}
}
int i;
if (this.logger.isTraceEnabled()) {
int nrOfCommonInterceptors = commonInterceptors.length;
i = specificInterceptors != null ? specificInterceptors.length : 0;
this.logger.trace("Creating implicit proxy for bean '" + beanName + "' with " + nrOfCommonInterceptors + " common interceptors and " + i + " specific interceptors");
}
Advisor[] advisors = new Advisor[allInterceptors.size()];
for(i = 0; i < allInterceptors.size(); ++i) {
advisors[i] = this.advisorAdapterRegistry.wrap(allInterceptors.get(i));
}
return advisors;
}
private Advisor[] resolveInterceptorNames() {
BeanFactory bf = this.beanFactory;
ConfigurableBeanFactory cbf = bf instanceof ConfigurableBeanFactory ? (ConfigurableBeanFactory)bf : null;
List<Advisor> advisors = new ArrayList();
String[] var4 = this.interceptorNames;
int var5 = var4.length;
for(int var6 = 0; var6 < var5; ++var6) {
String beanName = var4[var6];
if (cbf == null || !cbf.isCurrentlyInCreation(beanName)) {
Assert.state(bf != null, "BeanFactory required for resolving interceptor names");
Object next = bf.getBean(beanName);
advisors.add(this.advisorAdapterRegistry.wrap(next));
}
}
return (Advisor[])advisors.toArray(new Advisor[0]);
}
protected void customizeProxyFactory(ProxyFactory proxyFactory) {
}
@Nullable
protected abstract Object[] getAdvicesAndAdvisorsForBean(Class<?> var1, String var2, @Nullable TargetSource var3) throws BeansException;
}
下面根据Bean的生命周期按顺序分别来分析它实现父接口的4个方法: ①先来看postProcessBeforeInstantiation:
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
Object cacheKey = getCacheKey(beanClass, beanName);
if (!StringUtils.hasLength(beanName) || !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.
//为自定义TargetSource创建代理对象,如果我们没自定义TargetSource,直接返回null。这里是SpringAOP为我们提供了一个自定义生成目标对象代理的方式。
//TagrgetSource为代理源,持有被代理对象的地址引用。SpringAOP获取目标对象是通过TargetSource的getTarget()方法
TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
if (targetSource != null) {
if (StringUtils.hasLength(beanName)) {
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;
}
结论:Bean实例化之前,容器通过调用AbstractAutoProxyCreator.postProcessBeforeInstantiation方法检查目标bean是否存在自定义代理逻辑的TargetSource,如果存在通过自定义TargetSource创建Bean的代理对象。否者直接返回null。
之后,进行Bean的实例化,此时构造函数执行。源码如下:
@Override
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
// Don't override the class with CGLIB if no overrides.
if (!bd.hasMethodOverrides()) {
Constructor<?> constructorToUse;
synchronized (bd.constructorArgumentLock) {
constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
if (constructorToUse == null) {
final Class<?> clazz = bd.getBeanClass();
if (clazz.isInterface()) {
throw new BeanInstantiationException(clazz, "Specified class is an interface");
}
try {
if (System.getSecurityManager() != null) {
constructorToUse = AccessController.doPrivileged(
(PrivilegedExceptionAction<Constructor<?>>) clazz::getDeclaredConstructor);
}
else {
//反射,通过Class字节码获取Constructor构造器,调用BeanUtils.instantiateClass实例化对象,此时Bean的构造函数执行。
constructorToUse = clazz.getDeclaredConstructor();
}
bd.resolvedConstructorOrFactoryMethod = constructorToUse;
}
catch (Throwable ex) {
throw new BeanInstantiationException(clazz, "No default constructor found", ex);
}
}
}
return BeanUtils.instantiateClass(constructorToUse);
}
else {
// Must generate CGLIB subclass.
return instantiateWithMethodInjection(bd, beanName, owner);
}
}
②实例化之后,调用postProcessAfterInstantiation:
@Override
public boolean postProcessAfterInstantiation(Object bean, String beanName) {
return true;
}
结论:直接返回true,啥也没做。
③接下来来看Bean的init流程,首先看下流程:
//Bean的初始化执行时机
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
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 {
//然后执行Bean的init()方法
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()) {
//最后执行BeanPostProcessor的postProcessAfterInitialization()方法
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
接下来进行初始化之前的postProcessBeforeInitialization:
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) {
return bean;
}
结论:直接返回Bean本身,啥也没做。
④最后来看bean的初始化之后的postProcessAfterInitialization,前面3个切入方法都没对Bean进行增强,那么这个方法一定对Bean进行代理增强了。
通过上面嵌入代码的分析,直接来看wrapIfNecessary方法。
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
return bean;
}
//如果缓存中有,直接从Map中取,advisedBeans是ConcurrentHashMap类型
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对应的Advices和Advisors,代理对象的创建需要他们
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
//创建代理对象,传入参数为上面获取的Advices和Advisors
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;
}
然后来看getAdvicesAndAdvisorsForBean()方法,看它如何获取到Bean的Advices和Advisors的。
@Override
@Nullable
protected Object[] getAdvicesAndAdvisorsForBean(
Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {
//获取符合条件的Advisor
List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
if (advisors.isEmpty()) {
return DO_NOT_PROXY;
}
return advisors.toArray();
}
看到,AbstractAutoProxyCreator委派给子抽象类实现getAdvicesAndAdvisorsForBean()方法,顺着方法调用,继续找下去,发现它最终调用AbstractAdvisorAutoProxyCreator.findEligibleAdvisors(Class<?> beanClass, String beanName),在这个方法里,来查找bean的Advisors。
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
List<Advisor> candidateAdvisors = findCandidateAdvisors();
List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
extendAdvisors(eligibleAdvisors);
if (!eligibleAdvisors.isEmpty()) {
eligibleAdvisors = sortAdvisors(eligibleAdvisors);
}
return eligibleAdvisors;
}
可以看到,它调用了两个方法,第一步获取候选的List<Advisor>,第二步通过传入获取的候选List<Advisor>、beanClass和beanName获取符合条件的List<Advisor>。第二步只是对第一步做了个判断是否符合条件,我们先看第一步:
①findCandidateAdvisors()依次调用BeanFactoryAdvisorRetrievalHelper.findAdvisorBeans()最终调用DefaultListableBeanFactory.doGetBeanNamesForType(ResolvableType type, boolean includeNonSingletons, boolean allowEagerInit),两个方法源码如下:
//BeanFactoryAdvisorRetrievalHelper.findAdvisorBeans()
public List<Advisor> findAdvisorBeans() {
// Determine list of advisor bean names, if not cached already.
String[] 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!
//这里调用进入下面那个方法,注意它的传参 Advisor.class
advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this.beanFactory, Advisor.class, true, false);
this.cachedAdvisorBeanNames = advisorNames;
}
if (advisorNames.length == 0) {
return new ArrayList<>();
}
List<Advisor> advisors = new ArrayList<>();
for (String name : advisorNames) {
if (isEligibleBean(name)) {
if (this.beanFactory.isCurrentlyInCreation(name)) {
if (logger.isTraceEnabled()) {
logger.trace("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;
String bceBeanName = bce.getBeanName();
if (bceBeanName != null && this.beanFactory.isCurrentlyInCreation(bceBeanName)) {
if (logger.isTraceEnabled()) {
logger.trace("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;
}
//DefaultListableBeanFactory.doGetBeanNamesForType(ResolvableType type, boolean includeNonSingletons, boolean allowEagerInit)
//从上个方法调用进来,type类型则为org.springframework.aop.Advisor
//由于这里同样涉及Spring容器启动时,BeanFactoryPostProcessor、SmartInstantiationAwareBeanPostProcessor执行,譬如程序中的@Autowire、@Configuration等等之类的注解,其实都是依靠了AutowiredAnnotationBeanPostProcessor、ConfigurationClassPostProcessor等组件来实现功能的。这里只需要知道,在AbstractAutoProxyCreator.postProcessAfterInitialization执行之前,这些组件的注册到了容器,并已经执行他们的前置处理、后置处理方法。而且下面的方法,在BeanFactoryPostProcessor执行时机也被调用了。也就是说,在AbstractAutoProxyCreator.postProcessAfterInitialization执行之前,就已经获取到了容器中各种Type的BeanName。
private String[] doGetBeanNamesForType(ResolvableType type, boolean includeNonSingletons, boolean allowEagerInit) {
List<String> result = new ArrayList<>();
// Check all bean definitions.
for (String beanName : this.beanDefinitionNames) {
// Only consider bean as eligible if the bean name
// is not defined as alias for some other bean.
if (!isAlias(beanName)) {
try {
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
// Only check bean definition if it is complete.
if (!mbd.isAbstract() && (allowEagerInit ||
(mbd.hasBeanClass() || !mbd.isLazyInit() || isAllowEagerClassLoading()) &&
!requiresEagerInitForType(mbd.getFactoryBeanName()))) {
boolean isFactoryBean = isFactoryBean(beanName, mbd);
BeanDefinitionHolder dbd = mbd.getDecoratedDefinition();
boolean matchFound = false;
boolean allowFactoryBeanInit = allowEagerInit || containsSingleton(beanName);
boolean isNonLazyDecorated = dbd != null && !mbd.isLazyInit();
if (!isFactoryBean) {
if (includeNonSingletons || isSingleton(beanName, mbd, dbd)) {
matchFound = isTypeMatch(beanName, type, allowFactoryBeanInit);
}
}
else {
if (includeNonSingletons || isNonLazyDecorated ||
(allowFactoryBeanInit && isSingleton(beanName, mbd, dbd))) {
matchFound = isTypeMatch(beanName, type, allowFactoryBeanInit);
}
if (!matchFound) {
// In case of FactoryBean, try to match FactoryBean instance itself next.
beanName = FACTORY_BEAN_PREFIX + beanName;
matchFound = isTypeMatch(beanName, type, allowFactoryBeanInit);
}
}
if (matchFound) {
result.add(beanName);
}
}
}
catch (CannotLoadBeanClassException | BeanDefinitionStoreException ex) {
if (allowEagerInit) {
throw ex;
}
// Probably a placeholder: let's ignore it for type matching purposes.
LogMessage message = (ex instanceof CannotLoadBeanClassException) ?
LogMessage.format("Ignoring bean class loading failure for bean '%s'", beanName) :
LogMessage.format("Ignoring unresolvable metadata in bean definition '%s'", beanName);
logger.trace(message, ex);
onSuppressedException(ex);
}
}
}
// Check manually registered singletons too.
for (String beanName : this.manualSingletonNames) {
try {
// In case of FactoryBean, match object created by FactoryBean.
if (isFactoryBean(beanName)) {
if ((includeNonSingletons || isSingleton(beanName)) && isTypeMatch(beanName, type)) {
result.add(beanName);
// Match found for this bean: do not match FactoryBean itself anymore.
continue;
}
// In case of FactoryBean, try to match FactoryBean itself next.
beanName = FACTORY_BEAN_PREFIX + beanName;
}
// Match raw bean instance (might be raw FactoryBean).
if (isTypeMatch(beanName, type)) {
result.add(beanName);
}
}
catch (NoSuchBeanDefinitionException ex) {
// Shouldn't happen - probably a result of circular reference resolution...
logger.trace(LogMessage.format("Failed to check manually registered singleton with name '%s'", beanName), ex);
}
}
return StringUtils.toStringArray(result);
}
再来看第二个findAdvisorsThatCanApply()方法,它委托给TransactionAttributeSourcePointcut的matches()进行条件判断,源码如下:
@Override
public boolean matches(Method method, Class<?> targetClass) {
TransactionAttributeSource tas = getTransactionAttributeSource();
return (tas == null || tas.getTransactionAttribute(method, targetClass) != null);
}
继续看TransactionAttributeSource#getTransactionAttribute(method, targetClass)源码:
@Nullable
protected TransactionAttribute computeTransactionAttribute(Method method, @Nullable Class<?> targetClass) {
// Don't allow no-public methods as required.
if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) {
return null;
}
// The method may be on an interface, but we need attributes from the target class.
// If the target class is null, the method will be unchanged.
Method specificMethod = AopUtils.getMostSpecificMethod(method, targetClass);
// First try is the method in the target class.
//回头取看@Transactional注解,发现他给事务属性了。而这里对每个目标方法检查事务属性,很显然,有@Transactional注解的才能返回非null。而非null才是符合条件的,因此目标方法没@Transactional是不会找到事务增强器的。
TransactionAttribute txAttr = findTransactionAttribute(specificMethod);
if (txAttr != null) {
return txAttr;
}
// Second try is the transaction attribute on the target class.
txAttr = findTransactionAttribute(specificMethod.getDeclaringClass());
if (txAttr != null && ClassUtils.isUserLevelMethod(method)) {
return txAttr;
}
if (specificMethod != method) {
// Fallback is to look at the original method.
txAttr = findTransactionAttribute(method);
if (txAttr != null) {
return txAttr;
}
// Last fallback is the class of the original method.
txAttr = findTransactionAttribute(method.getDeclaringClass());
if (txAttr != null && ClassUtils.isUserLevelMethod(method)) {
return txAttr;
}
}
return null;
}
现在,再回到上面doGetBeanNamesForType(ResolvableType type, boolean includeNonSingletons, boolean allowEagerInit)方法
if (includeNonSingletons || isSingleton(beanName, mbd, dbd)) {
//在已注册的Bean Definition Names中查找Type匹配Advisor类型的bean name,发现找到一个bean name为"org.springframework.aop.config.internalAutoProxyCreator",而它的组件便是BeanFactoryTransactionAttributeSourceAdvisor实例
registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
matchFound = isTypeMatch(beanName, type, allowFactoryBeanInit);
}
}
else {
if (includeNonSingletons || isNonLazyDecorated ||
(allowFactoryBeanInit && isSingleton(beanName, mbd, dbd))) {
matchFound = isTypeMatch(beanName, type, allowFactoryBeanInit);
}
if (!matchFound) {
// In case of FactoryBean, try to match FactoryBean instance itself next.
beanName = FACTORY_BEAN_PREFIX + beanName;
matchFound = isTypeMatch(beanName, type, allowFactoryBeanInit);
}
}
if (matchFound) {
result.add(beanName);
}
那么这里有个疑问,BeanFactoryTransactionAttributeSourceAdvisor何时注册进Spring容器的,在哪里实现注册的?文章开头写了@EnableTransactionManagement注解通过@Import向Spring导入组件,导入了AutoProxyRegistrar和ProxyTransactionManagementConfiguration,这个组件向容器注册正是通过第二个组件ProxyTransactionManagementConfiguration来实现的。这里只需要知道,执行AbstractAutoProxyCreator 的postProcessAfterInitialization方法之前,它就已经在Spring容器中注册完成。
接下来看第二处重点,很明显,要做的是通过筛选到的beanName从容器拿到bean实例对象。
public List<Advisor> findAdvisorBeans() {
// Determine list of advisor bean names, if not cached already.
String[] 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!
advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this.beanFactory, Advisor.class, true, false);
this.cachedAdvisorBeanNames = advisorNames;
}
if (advisorNames.length == 0) {
return new ArrayList<>();
}
List<Advisor> advisors = new ArrayList<>();
for (String name : advisorNames) {
if (isEligibleBean(name)) {
if (this.beanFactory.isCurrentlyInCreation(name)) {
if (logger.isTraceEnabled()) {
logger.trace("Skipping currently created advisor '" + name + "'");
}
}
else {
try {
//通过beanName和Advisor.class拿到容器中具体的bean实例,并存入List<Advisior>
advisors.add(this.beanFactory.getBean(name, Advisor.class));
}
catch (BeanCreationException ex) {
Throwable rootCause = ex.getMostSpecificCause();
if (rootCause instanceof BeanCurrentlyInCreationException) {
BeanCreationException bce = (BeanCreationException) rootCause;
String bceBeanName = bce.getBeanName();
if (bceBeanName != null && this.beanFactory.isCurrentlyInCreation(bceBeanName)) {
if (logger.isTraceEnabled()) {
logger.trace("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;
}
再回头来看AbstractAutoProxyCreator的wrapIfNeccessary()方法:
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
if (StringUtils.hasLength(beanName) && 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.
//方法返回List<Advisor> size=1
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
//如果需要增强,则创建代理对象
if (specificInterceptors != DO_NOT_PROXY) {
//adviseBeans Map先缓存是否生成代理对象标记为TRUE
this.advisedBeans.put(cacheKey, Boolean.TRUE);
//通过bean、bean的class、List<Advisor>增强链、bean的单实例TargetSource来创建代理对象
Object proxy = createProxy(
bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
//Map缓存生成的代理对象
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
Object[] specificInterceptors就是size=1 的List,里面元素是beanName=org.springframework.transaction.config.internalTransactionAdvisor 类型为BeanFactoryTransactionAttributeSourceAdvisor的Bean实例对象。
然后,创建代理对象:通过bean、bean字节码、beanName、上面得到的List、为bean生成一个单实例TargetSource这些参数,采用JDK动态代理来创建代理对象。
现在应该明白AbstractAutoProxyCreator通过实现BeanPostProcessor接口的postProcessAfterInitialization方法,为Bean在实例化、初始化之后进行增强,获取容器中为该Bean注册的BeanFactoryTransactionAttributeSourceAdvisor增强链,通过增强链创建代理对象。
上面讲完了AutoProxyRegistrar组件,@EnableTransactionManagement除了导入了它,还导入了另一个组件ProxyTransactionManagementConfiguration,后面开始分析这个组件。
@Configuration(proxyBeanMethods = false)
public class ProxyTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration {
//beanName="org.springframework.aop.config.internalAutoProxyCreator",类型是BeanFactoryTransactionAttributeSourceAdvisor,这个bean就是我们创建代理对象时,获取到的增强链的List<Advisor>.get(0)
@Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor(
TransactionAttributeSource transactionAttributeSource,
TransactionInterceptor transactionInterceptor) {
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();
}
//注入事务拦截器组件
@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public TransactionInterceptor transactionInterceptor(
TransactionAttributeSource transactionAttributeSource) {
TransactionInterceptor interceptor = new TransactionInterceptor();
interceptor.setTransactionAttributeSource(transactionAttributeSource);
if (this.txManager != null) {
interceptor.setTransactionManager(this.txManager);
}
return interceptor;
}
}
通过源码看到,ProxyTransactionManagementConfiguration是一个配置类组件,它往容器中注册了3个Bean实例,分别是TransactionInterceptor、TransactionAttributeSource、BeanFactoryTransactionAttributeSourceAdvisor。BeanFactoryTransactionAttributeSourceAdvisor需要依赖其余2个组件进行注册。
结论:代理对象的创建需要BeanFactoryTransactionAttributeSourceAdvisor,而BeanFactoryTransactionAttributeSourceAdvisor中的TransactionAttributeSource属性为@EnableTransactionManagement向容器中注册的TransactionAttributeSource实例,BeanFactoryTransactionAttributeSourceAdvisor中的Advice属性为@EnableTransactionManagement向容器中注册的TransactionInterceptor实例。我们只需要看目标对象方法执行时,代理对象通过增强器BeanFactoryTransactionAttributeSourceAdvisor在其目标方法前后做了什么事,从而实现Spring AOP事务。
接下来,开始讲代理对象如何通过BeanFactoryTransactionAttributeSourceAdvisor增强器对目标方法进行事务增强。注意,本篇着重讲SpringAOP事务。至于Spring容器启动时为啥会将ProxyTransactionManagementConfiguration配置类的3个Bean提前在容器注册完成,以及何时执行他们的前置后置处理器,以及IOC过程将大幅忽略,后面讲Spring启动源码再讲这些。
首先来看代理对象创建过程:
protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
@Nullable 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增强链和bean的TargetSource交给ProxyFactory
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
proxyFactory.addAdvisors(advisors);
proxyFactory.setTargetSource(targetSource);
customizeProxyFactory(proxyFactory);
proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
//ProxyFactory创建代理对象
return proxyFactory.getProxy(getProxyClassLoader());
}
继续看ProxyFactory创建代理对象,发现ProxyFactory去获取AopProxyFactory,然后AopProxyFactory委托给子类DefaultAopProxyFactory来创建:
@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.");
}
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
return new ObjenesisCglibAopProxy(config);//bean没实现接口时,采用Cglib代理
}
else {
return new JdkDynamicAopProxy(config); //bean有实现接口时,采用jdk动态代理
}
}
先来看JDK动态代理对象创建:
@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
if (logger.isTraceEnabled()) {
logger.trace("Creating JDK dynamic proxy: " + this.advised.getTargetSource());
}
Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
//通过jdk动态代理创建代理对象,注意传入的InvocationHandler参数,此时便是JdkDynamicAopProxy对象自己,发现它实现了jdk的InvocationHandler接口,因此它用来代理目标方法执行。
return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}
于是,来看JdkDynamicAopProxy如何实现InvocationHandler接口的invoke()方法的:
@Override @Nullable public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object oldProxy = null; boolean setProxyContext = false;
TargetSource targetSource = this.advised.targetSource;
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;
}
// Get as late as possible to minimize the time we "own" the target,
// in case it comes from a pool.
target = targetSource.getTarget();
Class<?> targetClass = (target != null ? target.getClass() : null);
// 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...
//注释写的很清楚了。通过MethodInvocation.proceed()来执行。
MethodInvocation invocation =
new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
// Proceed to the joinpoint through the interceptor chain.
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);
}
}
}
于是,来看MethodInvocation.proceed()源码:
@Override
@Nullable
public Object proceed() throws Throwable {
// We start with an index of -1 and increment early.
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return invokeJoinpoint();
}
Object interceptorOrInterceptionAdvice =
this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
// Evaluate dynamic method matcher here: static part will already have
// been evaluated and found to match.
InterceptorAndDynamicMethodMatcher dm =
(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
Class<?> targetClass = (this.targetClass != null ? this.targetClass : this.method.getDeclaringClass());
if (dm.methodMatcher.matches(this.method, targetClass, this.arguments)) {
return dm.interceptor.invoke(this);
}
else {
// Dynamic matching failed.
// Skip this interceptor and invoke the next in the chain.
return proceed();
}
}
else {
// It's an interceptor, so we just invoke it: The pointcut will have
// been evaluated statically before this object was constructed.
//事务方法会委托给TransactionInterceptor来执行。
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}
通过读源码调用链,发现最后通过TransactionAspectSupport.invokeWithinTransaction来执行。来看源码:
protected Object invokeWithinTransaction(Method method, @Nullable Class<?> targetClass,
final InvocationCallback invocation) throws Throwable {
if (this.reactiveAdapterRegistry != null) {
if (KotlinDetector.isKotlinType(method.getDeclaringClass()) && KotlinDelegate.isSuspend(method)) {
throw new TransactionUsageException("Unsupported annotated transaction on suspending function detected: "
+ method + ". Use TransactionalOperator.transactional extensions instead.");
}
ReactiveAdapter adapter = this.reactiveAdapterRegistry.getAdapter(method.getReturnType());
if (adapter != null) {
return new ReactiveTransactionSupport(adapter).invokeWithinTransaction(method, targetClass, invocation);
}
}
// If the transaction attribute is null, the method is non-transactional.
TransactionAttributeSource tas = getTransactionAttributeSource();
//通过ProxyTransactionManagementConfiguration组件注入的TransactionAttributeSource获取事务属性
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.
//注意,这里就封装了ProxyTransactionManagementConfiguration组件注入的TransactionAttributeSource的事务管理器、事务属性、然后切入点joinpointIdentification便是目标方法声明。
TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);
Object retVal;
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
completeTransactionAfterThrowing(txInfo, ex);
throw ex;
}
finally {
cleanupTransactionInfo(txInfo);
}
if (vavrPresent && VavrDelegate.isVavrTry(retVal)) {
// Set rollback-only in case of Vavr failure matching our rollback rules...
TransactionStatus status = txInfo.getTransactionStatus();
if (status != null && txAttr != null) {
retVal = VavrDelegate.evaluateTryFailure(retVal, txAttr, status);
}
}
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 {
Object retVal = invocation.proceedWithInvocation();
if (vavrPresent && VavrDelegate.isVavrTry(retVal)) {
// Set rollback-only in case of Vavr failure matching our rollback rules...
retVal = VavrDelegate.evaluateTryFailure(retVal, txAttr, status);
}
return retVal;
}
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;
}
}
}
上面事务方法流程源码写的很清楚了。
再来看获取事务属性的方法tas.getTransactionAttribute(method, targetClass): @Override @Nullable public TransactionAttribute getTransactionAttribute(Method method, @Nullable Class<?> targetClass) { if (method.getDeclaringClass() == Object.class) { return null; }
// First, see if we have a cached value.
Object cacheKey = getCacheKey(method, targetClass);
TransactionAttribute cached = this.attributeCache.get(cacheKey);
if (cached != null) {
// Value will either be canonical value indicating there is no transaction attribute,
// or an actual transaction attribute.
if (cached == NULL_TRANSACTION_ATTRIBUTE) {
return null;
}
else {
return cached;
}
}
else {
// We need to work it out.
//提取事务属性
TransactionAttribute txAttr = computeTransactionAttribute(method, targetClass);
// Put it in the cache.
if (txAttr == null) {
this.attributeCache.put(cacheKey, NULL_TRANSACTION_ATTRIBUTE);
}
else {
String methodIdentification = ClassUtils.getQualifiedMethodName(method, targetClass);
if (txAttr instanceof DefaultTransactionAttribute) {
((DefaultTransactionAttribute) txAttr).setDescriptor(methodIdentification);
}
if (logger.isTraceEnabled()) {
logger.trace("Adding transactional method '" + methodIdentification + "' with attribute: " + txAttr);
}
this.attributeCache.put(cacheKey, txAttr);
}
return txAttr;
}
}
@Nullable
protected TransactionAttribute computeTransactionAttribute(Method method, @Nullable Class<?> targetClass) {
// Don't allow no-public methods as required.
if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) {
return null;
}
// The method may be on an interface, but we need attributes from the target class.
// If the target class is null, the method will be unchanged.
Method specificMethod = AopUtils.getMostSpecificMethod(method, targetClass);
// First try is the method in the target class.
//从方法上查找@Transactional注解
TransactionAttribute txAttr = findTransactionAttribute(specificMethod);
if (txAttr != null) {
return txAttr;
}
// Second try is the transaction attribute on the target class.
//从方法的接口和类上查找@Transactional注解
txAttr = findTransactionAttribute(specificMethod.getDeclaringClass());
if (txAttr != null && ClassUtils.isUserLevelMethod(method)) {
return txAttr;
}
if (specificMethod != method) {
// Fallback is to look at the original method.
txAttr = findTransactionAttribute(method);
if (txAttr != null) {
return txAttr;
}
// Last fallback is the class of the original method.
txAttr = findTransactionAttribute(method.getDeclaringClass());
if (txAttr != null && ClassUtils.isUserLevelMethod(method)) {
return txAttr;
}
}
return null;
}
//提取事务属性
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"));
List<RollbackRuleAttribute> rollbackRules = new ArrayList<>();
for (Class<?> rbRule : attributes.getClassArray("rollbackFor")) {
rollbackRules.add(new RollbackRuleAttribute(rbRule));
}
for (String rbRule : attributes.getStringArray("rollbackForClassName")) {
rollbackRules.add(new RollbackRuleAttribute(rbRule));
}
for (Class<?> rbRule : attributes.getClassArray("noRollbackFor")) {
rollbackRules.add(new NoRollbackRuleAttribute(rbRule));
}
for (String rbRule : attributes.getStringArray("noRollbackForClassName")) {
rollbackRules.add(new NoRollbackRuleAttribute(rbRule));
}
rbta.setRollbackRules(rollbackRules);
return rbta;
}
至于Cglib代理方式,采用生成目标Bean的子类,覆盖bean的目标方法。这里就不讨论了。 至于动态代理如何生成代理对象,如何将@Around环绕逻辑增强在目标对象方法前后,这个JDK动态代理底层由JVM实现,Cglib代理底层由ASM字节码技术实现。