AnnotationConfigApplicationContext
public AnnotationConfigApplicationContext(String... basePackages) {
this();
scan(basePackages);
refresh();
}
this构造方法
1.初始化AnnotatedBeanDefinitionReader
2.初始化DefaultListableBeanFactory
3.注册一些后置处理器,例如ConfigurationClassPostProcessor
refresh方法
//1:准备刷新上下文环境
prepareRefresh();
//2:获取告诉子类初始化Bean工厂 不同工厂不同实现
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
//3:对bean工厂进行填充属性
prepareBeanFactory(beanFactory);
try {
// 第四:留个子类去实现该接口
postProcessBeanFactory(beanFactory);
// 调用我们的bean工厂的后置处理器. 1. 会在此将class扫描成beanDefinition 2.bean工厂的后置处理器调用
invokeBeanFactoryPostProcessors(beanFactory);
// 注册我们bean的后置处理器
registerBeanPostProcessors(beanFactory);
// 初始化国际化资源处理器.
initMessageSource();
// 创建事件多播器
initApplicationEventMulticaster();
// 这个方法同样也是留个子类实现的springboot也是从这个方法进行启动tomcat的.
onRefresh();
//把我们的事件监听器注册到多播器上
registerListeners();
// 实例化我们剩余的单实例bean.
finishBeanFactoryInitialization(beanFactory);
// 最后容器刷新 发布刷新事件(Spring cloud也是从这里启动的)
finishRefresh();
}
prepareRefresh 设置容器id等
invokeBeanFactoryPostProcessors
根据PriorityOrdered、Ordered 排序后调用
BeanDefinitionRegistryPostProcessor、BeanFactoryPostProcessor的方法
上文ConfigurationClassPostProcessor的就实现了这两个接口
org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry
递归解析CompentScan、Import、@Bean、ImportSelector、ImportBeanDefinitionRegistrar
其中Import这三个注解都是实例化对象后反射调用,他们也实现了Aware接口
//实例化我们的SelectImport组件
ImportSelector selector = BeanUtils.instantiateClass(candidateClass, ImportSelector.class);
//调用相关的aware方法
ParserStrategyUtils.invokeAwareMethods(
selector, this.environment, this.resourceLoader, this.registry);
//调用selector的selectImports
String[] importClassNames = selector.selectImports(currentSourceClass.getMetadata());
// 所以递归解析-- 直到成普通组件
Collection<SourceClass> importSourceClasses = asSourceClasses(importClassNames);
processImports(configClass, currentSourceClass, importSourceClasses, false);
}
org.springframework.context.annotation.ConfigurationClassPostProcessor#postProcessBeanFactory
此方法主要是为Full的配置类BeanDefinition设置代理class
/*
只有full版配置类才会创建cglib代理
虽然我们在指定配置的时候不标注@Configuration也行,所以加不加注解的区别就在这里
那么加了@Configuration和不加有本质上有什么区别的?
当在配置类中一个@Bean 使用方法的方式引用另一个Bean如果不加注解就会重复加载Bean
如果加了@Configuration 则会在这里创建cglib代理,当调用@Bean方法时会先检测容器中是否存在*/
Class<?> enhancedClass = enhancer.enhance(configClass, this.beanClassLoader);
if (configClass != enhancedClass) {
if (logger.isDebugEnabled()) {
logger.debug(String.format("Replacing bean definition '%s' existing class '%s' with " +
"enhanced class '%s'", entry.getKey(), configClass.getName(), enhancedClass.getName()));
}
// 重新修改Bean定义的Class,在创建Bean的实例时将会实例cglib的类
beanDef.setBeanClass(enhancedClass);
}
至此BeanDefinition解析完成
registerBeanPostProcessors
实例化我们的后置处理器,方便下面创建bean的时候生命周期调用
finishBeanFactoryInitialization 初始化剩下的单例bean
简单说一下过程
singletonsCurrentlyInCreation 集合是正在创建的bean的集合,创建完会移除,用来判断循环依赖
getBean->doGetBean->createBean->doCreateBean
1.先从一级缓存拿,没有从二级缓存拿,没有从三级缓存拿,实例化后放入二级缓存
所以 循环引用就是
A先放入三级,B放入三级,A放入二级,B放入一级,A放入一级
AOP
@EnableAspectJAutoProxy Import AspectJAutoProxyRegistrar
注册了AnnotationAwareAspectJAutoProxyCreator BeanDefinition
这个类的父接口 AbstractAutoProxyCreator 实现了 InstantiationAwareBeanPostProcessor
而InstantiationAwareBeanPostProcessor 接口会在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean 之前调用
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
/**
* 获取容器中的所有后置处理器
*/
for (BeanPostProcessor bp : getBeanPostProcessors()) {
//判断后置处理器是不是InstantiationAwareBeanPostProcessor
if (bp instanceof InstantiationAwareBeanPostProcessor) {
//把我们的BeanPostProcessor强制转为InstantiationAwareBeanPostProcessor
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
/**
* 【很重要】
* 我们AOP @EnableAspectJAutoProxy 为我们容器中导入了 AnnotationAwareAspectJAutoProxyCreator
* 我们事务注解@EnableTransactionManagement 为我们的容器导入了 InfrastructureAdvisorAutoProxyCreator
* 都是实现了我们的 BeanPostProcessor接口,InstantiationAwareBeanPostProcessor,
* 进行后置处理解析切面
*/
Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
if (result != null) {
return result;
}
}
}
return null;
}
public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory,
int declarationOrderInAspect, String aspectName) {
validate(aspectInstanceFactory.getAspectMetadata().getAspectClass());
// 获得当前通知的 切点表达式
AspectJExpressionPointcut expressionPointcut = getPointcut(
candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass());
if (expressionPointcut == null) {
return null;
}
// 将切点表达式、 和通知 封装到InstantiationModelAwarePointcutAdvisorImpl对象中
return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod,
this, aspectInstanceFactory, declarationOrderInAspect, aspectName);
}
也就是说加了这个注解,org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessBeforeInstantiation 会在第一个bean 创建之前 解析Aspect @Before、@Pointcut这些注解,封装成beanname 和 Advisor的map,缓存起来,判断是否需要创建代理的时候用到
接下来就是创建代理
org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessAfterInitialization
实现了
```java
org.springframework.beans.factory.config.BeanPostProcessor#postProcessAfterInitialization
org.springframework.aop.support.AopUtils#canApply(org.springframework.aop.Pointcut, java.lang.Class<?>, boolean)
判断是否需要代理
org.springframework.aop.aspectj.AspectJExpressionPointcut#matches(java.lang.Class<?>)
@Override
public boolean matches(Class<?> targetClass) {
PointcutExpression pointcutExpression = obtainPointcutExpression();
try {
try {
return pointcutExpression.couldMatchJoinPointsInType(targetClass);
}
catch (ReflectionWorldException ex) {
logger.debug("PointcutExpression matching rejected target class - trying fallback expression", ex);
// Actually this is still a "maybe" - treat the pointcut as dynamic if we don't know enough yet
PointcutExpression fallbackExpression = getFallbackPointcutExpression(targetClass);
if (fallbackExpression != null) {
return fallbackExpression.couldMatchJoinPointsInType(targetClass);
}
}
}
catch (Throwable ex) {
logger.debug("PointcutExpression matching rejected target class", ex);
}
return false;
}
利用Aspect能力粗筛、精筛
筛选到有Advisor 就去创建代理
注意一下三级缓存的这个接口
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#getEarlyBeanReference
他会调用
org.springframework.beans.factory.config.SmartInstantiationAwareBeanPostProcessor#getEarlyBeanReference
而我们引用了切面的Enable注解上文不是会 实例 org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#getEarlyBeanReference,他就实现了这个接口,所以他第一次创建的时候就会判断是否需要代理,如果代理了,放入earlyProxyReferences的Map,接下来 初始化就不会重复创建了
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) throws BeansException {
if (bean != null) {
//获取缓存key
Object cacheKey = getCacheKey(bean.getClass(), beanName);
// 之前循环依赖创建的动态代理 如果是现在的bean 就不再创建,,并且移除
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
// 该方法将会返回动态代理实例
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
返回代理bean
// 是早期对象暴露
if (earlySingletonExposure) {
/**
* 去缓存中获取到我们的对象 由于传递的allowEarlyReference 是false 要求只能在一级二级缓存中去获取
* 正常普通的bean(不存在循环依赖的bean) 创建的过程中,压根不会把三级缓存提升到二级缓存中
*/
Object earlySingletonReference = getSingleton(beanName, false);
//能够获取到
if (earlySingletonReference != null) {
//经过后置处理的bean和早期的bean引用还相等的话(表示当前的bean没有被代理过)
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
}
}
而普通bean的创建是
@Override
public Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {
return bean;
}
三级缓存为什么要使用工厂而不是直接使用引用?换而言之,为什么需要这个三级缓存,直接通过二级缓存暴露一个引用不行吗?
答:这个工厂的目的在于延迟对实例化阶段生成的对象的代理,只有真正发生循环依赖的时候,才去提前生成代理对象,否则只会创建一个工厂并将其放入到三级缓存中,但是不会去通过这个工厂去真正创建对象
即使没有循环依赖,也会将其添加到三级缓存中,而且是不得不添加到三级缓存中,因为到目前为止Spring也不能确定这个Bean有没有跟别的Bean出现循环依赖。
假设我们在这里直接使用二级缓存的话,那么意味着所有的Bean在这一步都要完成AOP代理。这样做有必要吗?
不仅没有必要,而且违背了Spring在结合AOP跟Bean的生命周期的设计!Spring结合AOP跟Bean的生命周期本身就是通过AnnotationAwareAspectJAutoProxyCreator这个后置处理器来完成的,在这个后置处理的postProcessAfterInitialization方法中对初始化后的Bean完成AOP代理。如果出现了循环依赖,那没有办法,只有给Bean先创建代理,但是没有出现循环依赖的情况下,设计之初就是让Bean在生命周期的最后一步完成代理而不是在实例化后就立马完成代理。
EnableTransactionManagement
也是import了InfrastructureAdvisorAutoProxyCreator,他也是实现了org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator
和我们aop 一样的实现接口
aop 事物都存在的时候 注册了相同的bean名称
但是只会保留一个,AOP的会覆盖事务的, 因为AOP优先级更大
所以事物注解的解析也是和aop 一样的,第一个bean 实例化的前置处理器
EnableTransactionManagement 还会import一个配置类,也就是我们需要的 BeanFactoryTransactionAttributeSourceAdvisor、TransactionAttributeSource、TransactionInterceptor,以及父类的PlatformTransactionManager
aop 是自己扫描@Aspect构建出来的 advisor和advice、而事物是配置类配置的bean,这样事物的advisor 也会被扫描出来了
BeanFactoryTransactionAttributeSourceAdvisor 会设置TransactionAttributeSource
BeanFactoryTransactionAttributeSourceAdvisor中还会有TransactionAttributeSourcePointcut,
TransactionAttributeSourcePointcut 会有match方法,match方法就是调用TransactionAttributeSource的getTransactionAttribute方法,会在我们ioc 创建代理是调用
@Override
public boolean matches(Method method, @Nullable Class<?> targetClass) {
if (targetClass != null && TransactionalProxy.class.isAssignableFrom(targetClass)) {
return false;
}
/**
* 获取我们@EnableTransactionManagement注解为我们容器中导入的ProxyTransactionManagementConfiguration
* 配置类中的TransactionAttributeSource对象
*/
TransactionAttributeSource tas = getTransactionAttributeSource();
// 通过getTransactionAttribute看是否有@Transactional注解
return (tas == null || tas.getTransactionAttribute(method, targetClass) != null);
}
上面说完了事物Advisor的构建和扫描,接下来说事物的代理创建
前面拿Advisor 和 aop 没区别,
从这开始有区别
org.springframework.aop.support.AopUtils#canApply(org.springframework.aop.Pointcut, java.lang.Class<?>, boolean)
aop是 粗筛->精筛
接下来我们看下 事物的
上面说了 事物配的TransactionAttributeSourcePointcut 是StaticMethodMatcherPointcut 子类,所以类过滤永远返回true,进不去,接着往下看
那么MethodMatcher就是我们上面设置的TransactionAttributeSourcePointcut ,看TransactionAttributeSourcePointcut的match方法就好,也就是
实现类方法—>接口的方法—>实现类---->接口类 这个去找没有@Transactional注解
org.springframework.transaction.annotation.SpringTransactionAnnotationParser#parseTransactionAnnotation(java.lang.reflect.AnnotatedElement)
其实TransactionAttribute 也就是注解上的属性封装的对象,并放入缓存,TransactionAttribute属性解析不为空就是可以创建代理喽
调用事物代理
也就是我们配置类里配置的通知
org.springframework.aop.framework.ReflectiveMethodInvocation#proceed
org.springframework.transaction.interceptor.TransactionInterceptor#invoke
先看创建事物
也就是TransactionInfo对象
先说下主要结构
TransactionInfo里有TransactionStatus
DefaultTransactionStatus里有DataSourceTransactionObject
DataSourceTransactionObject 里有ConnectionHolder
而ConnectionHolder 保存了Connection 对象,如果ConnectionHolder有则基本说明存在事务
这里判断是否存在事务,
如果已存在就处理嵌套的事务逻辑, 这里我们待会作为分支再来跟进
如果不存在就处理顶层的事务逻辑,下面将先介绍顶层的事务逻辑
我们先看不存在就处理顶层的事务逻辑,那么就是开启一个事物,其实就是从数据源拿到一个Connection,并构建成ConnectionHolder,设置到DataSourceTransactionObject中,然后从TransactionAttribute给Connection设置一些是否只读,超时等,然后设置到现成变量里
resources 对象存放 ,key是数据源,value就说是ConnectionHolder对像,能拿到就说明存在嵌套事物
异常
rollbackOn属性不就是我们注解上的 很熟悉吧
没问题就提交
接下来细看获取事物的方法,里面涉及事物隔离级别
嵌套事物逻辑
org.springframework.transaction.support.AbstractPlatformTransactionManager#handleExistingTransaction
其实就是对不同事物传播行为的判断处理
我们重点看下挂起怎么做的
其实就是清空线程变量
newTransaction:false, 代表不是一个新的事务,如果不是新事务,提交事务时: 由外层事务控制统一提交事务
org.springframework.transaction.support.AbstractPlatformTransactionManager#processCommit