AbstractBeanFactory
- Map<String, RootBeanDefinition> mergedBeanDefinitions;
- private final Set alreadyCreated
- public final Map<String, Object> singletonObjects; 一级缓存
- public final Map<String, Object> earlySingletonObjects; 二级缓存
- public final Map<String, ObjectFactory<?>> singletonFactories; 三级缓存
spring概述
- BeanDefinitionReader
- BeanDefinitonRegistry
- AbstractAutowireCapableBeanFactory
- AbstractAutoProxyCreator BeanPostProcessor
- PlaceholderConfigurerSupport BeanFactoryPostProcessor
- PropertyPlaceholderConfigurer
- AbstractApplicationContext . refresh
- BeanFactory Aware BeanDefinition BeanDefinitionReader
- BeanFactoryPostProcessor BeanPostProcessor
- Environment StandardEnvironment
- FactoryBean
postProcess方法顺序
- postProcessBeforeInstantiation InstantiationAwareBeanPostProcessor 提前返回对象
- postProcessAfterInitialization BeanPostProcessor 初始化之后的方法
- determineCandidateConstructors SmartInstantiationAwareBeanPostProcessor 完成对构造函数的解析和推断
- postProcessMergedBeanDefinition MergedBeanDefinitionPostProcessor 一些注解的处理supper(@PostConstruct @PreDestroy) common(@Resource @WebServiceRef) 注解
- 方法执行在postProcessBeforeInitialization invokeInitMethods InitDestoryAnnotaionBeanPostProcessor
- CommonAnnotationBeanPostProcessor 构造方法 设置默认值
- AutowiredAnnotationBeanPostProcessor 处理@Autowired 和@Value 注解
- postProcessAfterInstantiation InstantiationAwareBeanPostProcessor 在bean实例化之后调用
- postProcessProperties InstantiationAwareBeanPostProcessor 这个方法来完成属性的注入
- AutowiredAnnotationBeanPostProcessor @Autowired 完成属性的注入
- postProcessBeforeInitialization BeanPostProcessor 初始化前 aware接口设置 执@PostConstruct @PreDestroy对应的方法
- postProcessAfterInitialization BeanPostProcessor 初始化后 动态代理
- AbstractAutoProxyCreator wrapIfNecessary(bean, beanName, cacheKey)
- postProcessBeforeDestruction DestructionAwareBeanPostProcessor 对象销毁
- getEarlyBeanReference SmartInstantiationAwareBeanPostProcessor 三级缓存中返回代理对象
- 调用三级缓存的工厂方法getEarlyBeanReference,执行BPP的方法,执行到AbstractAutoProxyCreator的getEarlyBeanReference方法,也会执行wrapIfNecessary(bean, beanName, cacheKey)
- AbstractAutoProxyCreator 的postProcessAfterInitialization 和 getEarlyBeanReference方法都有wrapIfNecessary(bean, beanName, cacheKey)执行动态代理
ConstructorResolver
- instantiateUsingFactoryMethod
- autowireConstructor
- argsHolderToUse.storeCache(mbd, constructorToUse); 缓存构造参数
spring流程概述
- BeanFactory
- ListableBeanFactory 可遍历Bean集合的工厂
- ConfigurableBeanFactory
- HierarchicalBeanFactory 可继承的Bean工厂
- ConfigurableBeanFactory 可配置的bean工厂
- StandardBeanExpressionResolver EL表达式的解析器
- ApplicationContextAwareProcessor
- ApplicationListenerDetector
Spring启动流程细节
- AbstractRefreshableConfigApplicationContext
- resolvePath 替换el表达式
- MyClassPathXmlApplicationContext extends ClassPathXmlApplicationContext
- initPropertySources 设置环境变量的值
- customizeBeanFactory 自定义bean工厂
- EntityResolver 读取本地的dtd文件 META-INF/spring.schemas
- setEntityResolver
Spring加载配置文件过程
仔细看
Properties mappings =
PropertiesLoaderUtils.loadAllProperties(this.schemaMappingsLocation, this.classLoader);
- BeanDefinitionParserDelegate
- META-INF/spring.handlers handlers路径
- NamespaceHandlerSupport
- CustomEditorConfigurer(BeanFactoryPostProcessor)
- PropertyEditorRegistrar (AddressPropertyEditorRegistrar)
- registerCustomEditors
- registerCustomEditor
- AddressPropertyEditor (PropertyEditorSupport)
- convertForProperty
- ApplicationContextAwareProcessor
Spring的BeanFactoryPostProcessor执行
- LoadTimeWeaverAwareProcessor
- postProcessBeanFactory 此方法重写
- List regularPostProcessors;
- List<BeanDefinitionRegistryPostProcessor registryProcessors;
- List currentRegistryProcessors;
- 先执行registry,后执行postProcessor
- AopConfigUtils
- AnnotationConfigUtils
- 执行流程
- 执行外部postProcessor的postProcessBeanDefinitionRegistry
- 执行实现了PriorityOrdered的postProcessBeanDefinitionRegistry
- 执行实现了Ordered的postProcessBeanDefinitionRegistry
- 执行普通的postProcessBeanDefinitionRegistry
- 执行所有registry的postProcessBeanFactory
- 执行所有(只有外部的)postProcessor的postProcessBeanFactory
- priorityOrderedPostProcessors的postProcessBeanFactory
- orderedPostProcessor的postProcessBeanFactory
- nonOrderedPostProcessorNames的postProcessBeanFactory
- PlaceholderConfigurerSupport
- ConfigurationClassPostProcessor
### Spring的BeanFactoryPostProcessor执行2
- ScannedGenericBeanDefinition
- Configuration Component ComponentScan Import ImportResource Bean
- ConditionEvaluator shouldSkip Conditional
ConfigurationClassPostProcessor解析
- BeanNameGenerator
- PropertySource使用
- ImportResource 使用
注册BeanPostProcessor
- EnableAutoConfiguration
- AutoConfigurationImportSelector
- this.deferredImportSelectorHandler.handle import解析
- this.deferredImportSelectors.add(holder) 添加到集合中
- this.deferredImportSelectorHandler.process() 处理集合中的数据
- handler.processGroupImports() 处理imports
- grouping.getImports() 获取imorts
- this.group.process 处理
- deferredImportSelector).getAutoConfigurationEntry(annotationMetadata) 获取配置
- getCandidateConfigurations(annotationMetadata, attributes) 获取配置
- loadFactoryNames() 加载名称
- getSpringFactoriesLoaderFactoryClass() 获取类 EnableAutoConfiguration
- loadSpringFactories 加载路径 FACTORIES_RESOURCE_LOCATION META-INF/spring.factories
- AutoConfigurationImportSelector
- AutoConfigurationPackage
- AutoConfigurationPackages.Registrar
- ImportBeanDefinitionRegistrar
- addImportBeanDefinitionRegistrar
- AutoConfigurationPackages.Registrar
- PropertySourceLoader
- YamlProprtySourceLoader
- PropertiesPropertySourceLoader
- AnnotationConfigUtils
- BeanPostProcessor
- BeanPostProcessor
- postProcessBeforeInitialization 初始化方法调用前要进行的处理逻辑
- postProcessAfterInitialization 在初始化方法指定后要进行的处理逻辑
- DestructionAwareBeanPostProcessor
- postProcessBeforeDestruction 在bean被销毁前调用
- requiresDestruction 判断是否要进行销毁,一般情况下都需要
- MergedBeanDefinitionPostProcessor
- postProcessMergedBeanDefinition spring通过此方法找出所有需要注入的字段,同时做缓存
- resetBeanDefinition 用于在BeanDefinition被修改后,清除容器的缓存
- InstantiationAwareBeanPostProcessor
- postProcessBeforeInstantiation 在bean实例化之前调用
- postProcessAfterInstantiation 在bean实例化之后调用
- postProcessProperties 当使用注解的时候,通过这个方法来完成属性的注入
- SmartInstantiationAwareBeanPostProcessor
- predictBeanType 预测bean的类型,主要是在bean还没有创建前我们需要获取bean的类型
- determineCandidateConstructors 完成对构造函数的解析和推断
- getEarlyBeanReference 解决循环依赖问题,通过此方法提前暴露一个合格的对象
spring的消息资源和监听器的初始化
- ApplicationEvent
- ApplicationListener
- onApplicationEvent
- ApplicationEventMulticaster
- SimpleApplicationEventMulticaster
- multicastEvent 将应用程序事件广播到对应的监听器上
- SimpleApplicationEventMulticaster
- EventPublishingRunListener
- this.initialMulticaster = new SimpleApplicationEventMulticaster();
- this.initialMulticaster = new SimpleApplicationEventMulticaster();
一. Bean的创建流程(一)
- 如何使用ConversionService
- ConversionService 转换服务 . 从一个类型到另一个类型的转换服务
- DefaultConversionService
- Convert<S,T> . 1对1
- GenericConverter . 用于两种或者更多种类型之间转换的通用转换器接口 . 1对N
- ConverterFactory N对N
- ConditionalGenericConverter . 条件判断的Converter
- ConversionServiceFactoryBean
- PropertyPlaceholderConfigurer
- BeanDefinition
- GenericBeanDefinition
- RootBeanDefinition
- bd.getParentName()
- BeanFactory . FactoryBean
- 都是对象工厂,用来创建对象.如果使用BeanFactory的接口,那么必须要严格遵守 springbean的生命周期接口,从实例化,到初始化,到 invokeAwareMethod, invokelnitMethod,before,after,此流程非常复杂且麻烦,如果需要一种更加便捷简单的方式创建,怎么办?所以有了FactoryBean这个接口,不需要遵循此创建顺序
- FactoryBean .
- getObjectType 返回类型
- isSingleton 是否单例
- getObject() 创建对象
- 不加&取的是工厂创建的对象,加&取的是工厂本身
- getObjectForBeanInstance
- doGetObjectFromFactoryBean
- this.factoryBeanObjectCache (bean工厂创建的对象的缓存)
- object = getCachedObjectForFactoryBean(beanName);
- factoryBeanObjectCache factoryBean创建的单例对象存储在这
二. bean的创建流程(二)
- DefaultSingletonBeanRegistry 三级缓存的位置
- getBean doGetBean createBean doCreateBean
- 创建对象的方式
- 反射
- factoryMethod
- supplier
- 通过FactoryBean创建对象
- 自定义BeanPostProcessor生成代理对象 InstantiationAwareBeanPostProcessor
- depends-on
- ObjectFactory 函数式接口,getObject方法
- singletonsCurrentlyInCreation 标记当前对象正在创建中
- 过程 实例化 填充属性 执行aware接口方法 执行init方法 执行后置处理器方法
- lookup-method
- spring中默认的对象都是单例的,spring会在一级缓存中持有该对象,方便下次直接获取, 那么如果是原型作用域的话,会创建一个新的对象 如果想在一个单例模式的bean下引用一个原型模式的bean,怎么办? 在此时就需要引用lookup-method标签来解决此问题
- 通过拦截器的方式每次需要的时候都去创建最新的对象,而不会把原型对象缓存起来,
- replace-method
- CglibSubclassingInstantiationStrategy . 改变创建实例的策略
- private static final Class<?>[] CALLBACK_TYPES = new Class<?>[]{NoOp.class, LookupOverrideMethodInterceptor.class, ReplaceOverrideMethodInterceptor.class};
- 通过拦截器的方式,每次创建的时候构造新的对象,不会把对象保存
- ConfigurationclassPostProcessor
三. bean的创建流程(三)
- Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
- 返回一个代理对象
- BeanPostProcessor
- 初始化前和初始化后
- postProcessBeforeInitialization
- postProcessAfterInitialization
- InstantiationAwareBeanPostProcessor
- 实例化前和实例化后
- postProcessBeforeInstantiation
- postProcessAfterInstantiation
- postProcessProperties
package com.mashibing.resolveBeforeInstantiation;
import org.springframework.beans.BeansException;
import org.springframework.beans.PropertyValues;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;
import org.springframework.cglib.proxy.Enhancer;
public class MyInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
System.out.println("beanName:"+beanName+"----执行postProcessBeforeInstantiation方法");
if (beanClass == BeforeInstantiation.class){
// Enhancer enhancer = new Enhancer();
// enhancer.setSuperclass(beanClass);
// enhancer.setCallback(new MyMethodInterceptor());
// BeforeInstantiation beforeInstantiation = (BeforeInstantiation) enhancer.create();
// System.out.println("创建代理对象:"+beforeInstantiation);
return new BeforeInstantiation();
}
return null;
}
@Override
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
System.out.println("beanName:"+beanName+"----执行postProcessAfterInstantiation方法");
return false;
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("beanName:"+beanName+"----执行postProcessBeforeInitialization方法");
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("beanName:"+beanName+"----执行postProcessAfterInitialization方法");
return bean;
}
@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
System.out.println("beanName:"+beanName+"----执行postProcessProperties方法");
return pvs;
}
}
4. 通过Supplier创建对象
- 通过factoryMethod创建对象
- 静态工厂
- BeanWrapper instantiateUsingFactoryMethod 试一下getPerson(String name) getPerson(int age) 用哪个 怎么选择的
- createArgumentArray
bean的创建流程(四)
- bd中的属性 resolvedConstructorOrFactoryMethod 缓存的构造方法
- 原型模式可以直接用这个构造器
- Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
- mbd.hasConstructorArgumentValues()
- ConstructorResolver
- 获取工厂方法的方法 public BeanWrapper instantiateUsingFactoryMethod( String beanName, RootBeanDefinition mbd, @Nullable Object[] explicitArgs)
- 获取构造方法的方法 public BeanWrapper autowireConstructor(String beanName, RootBeanDefinition mbd,@Nullable Constructor<?>[] chosenCtors, @Nullable Object[] explicitArgs)
- 找到所有的构造方法
- 根据参数个数排序 . (优化点)
- 根据类型选择合适的构造方法
- mbd.resolvedConstructorOrFactoryMethod = constructorOrFactoryMethod;
- argsHolderToUse.storeCache(mbd, constructorToUse); 缓存构造器
- SmartInstantiationAwareBeanPostProcessor
- AutowiredAnnotationBeanPostProcessor . 子类
- predictBeanType
- determineCandidateConstructors . 决定候选的构造器
- getEarlyBeanReference 获取代理对象
- AutowiredAnnotationBeanPostProcessor 处理 determineConstructorsFromBeanPostProcessors 看看
- InstantiationStrategy
- SimpleInstantiationStrategy 实现类
- Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) throws BeansException;
- Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner, Constructor<?> ctor, Object… args) throws BeansException;
- Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner, @Nullable Object factoryBean, Method factoryMethod, Object… args) throws BeansException;
- CglibSubclassingInstantiationStrategy
- instantiateWithMethodInjection 不带构造方法
- instantiateWithMethodInjection 带构造方法
- SimpleInstantiationStrategy 实现类
- 实例化策略 创造出来的有可能是具体对象也可能是代理对象
- Simple实例化策略
- 无参构造实例化
- 有参构造实例化
- 工厂方法实例化
- cglib实例化策略
- 动态代理对象
- 无参构造
- 有参构造
- 动态代理对象
- Simple实例化策略
- BeanWrapper 加了一些类型转换器
- PropertyEditorRegistry
- TypeConverter
- applyMergedBeanDefinitionPostProcessors . 修改当前bean的定义信息
- MergedBeanDefinitionPostProcessor
- postProcessMergedBeanDefinition
- resetBeanDefinition
- InitDestroyAnnotationBeanPostProcessor . 子类 解析PostConstruct 和PreDestroy
- CommonAnnotationBeanPostProcessor 子类 解析resource
- @PostConstruct
- @PreDestroy
- AutowiredAnnotationBeanPostProcessor 子类 . Autowired 和value reject 注解解析
- AutowiredFieldElement
- AutowiredMethodElement
- inject方法 . 给字段赋值
bean的创建流程(五)
- 初始化步骤
- 填充属性
- 执行aware接口对应的方法
- 执行beanPostProcessor中的before方法
- 执行init-method
- 执行beanPostProcessor中的after方法
- 三级缓存
- 一级缓存: 成品对象 . 普通对象和代理对象
- 二级缓存: 半成品对象 实例化但未初始化的对象
- 三级缓存: 生成代理对象的方法.因为不确定是否需要生成代理对象,实例化后都会进三级缓存,生成完整对象后删掉
- 查找顺序:
- 一级–>二级–>三级
- 对象可能直接从三级缓存到一级缓存
- 如果单纯为了解决循环依赖问题,那么使用二级缓存足够解决问题,三级缓存存在的意义是为了避免代理,如果没有代理对象,二级缓存足以解决
- 生成代理对象的时机
- 属性注入的时候,创建该对象时,发现需要代理
- 没有被其他对象依赖时,在生成的完整对象之前生成代理对象,beanPostProcessor中的after方法
bean的创建流程(六)
- 自动填充类型
- byName
- byType
- 填充属性
- 基本数据类型
- 直接赋值操作
- 数组 list set map properties
- 类型转换
- 引用类型
- 从容器中获取对象值,有赋值,没有创建
- 数组 list set map properties
- 注入的方式:
- 类型注入,名称注入,构造注入
- 基本数据类型
- 解析根据类型获取的字段
- Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);仔细看看
- AutowiredAnnotationBeanPostProcessor
- AutowiredFieldElement inject 属性赋值
- AutowiredMethodElement inject
### bean的创建流程(七)
-
TypeConverter converter = getCustomTypeConverter(); 用户自定义的转换器怎么用
-
BeanDefinitionValueResolver 值处理器
-
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader())); SPL表达式处理
-
PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
- 如果工厂拥有InstiationAwareBeanPostProcessor,那么处理对应的流程,主要是对几个注解的赋值工作包含的两个关键子类是CommonAnnoationBeanPostProcessor,AutowiredAnnotationBeanPostProcessor
-
applyPropertyValues(beanName, mbd, bw, pvs);
- 设置属性值
-
Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
- 解析属性的值
-
List deepCopy 深拷贝数组
-
解析list会重复调用resolveValueIfNecessary 方法
-
bw.setPropertyValues(new MutablePropertyValues(deepCopy));
- 真正给属性设值
-
populateBean步骤
-
InstantiationAwareBeanPostProcessor
-
根据配置文件的autowire属性来决定使用名称注入还是类型注入
- autowireByName
- autowireByType
-
将对象中定义的@Autowired注解进行解析,并完成对象或者属性的注入
- InstantiationAwareBeanPostProcessor中的postProcessProperties
- AutowiredAnnotationBeanPostProcessor inject
-
根据property标签定义的属性值,完成各种属性值的解析和赋值操作
- applyPropertyValues . 赋值
- List deepCopy
- resolveValueIfNecessary 解析值放入deepCopy中
- setPropertyValues 利用deepCopy中的内容调用set方法设置
- applyPropertyValues . 赋值
-
initializeBean执行的内容
-
执行调用Aware接口对应的方法
- invokeAwareMethods(beanName, bean);
- BeanNameAware
- BeanClassLoaderAware
- BeanFactoryAware
- beanFactory.ignoreDependencyInterface(EnvironmentAware.class); . 忽略aware接口
- ApplicationContextAwareProcessor. postProcessBeforeInitialization . 会设置一部分aware的内容
- invokeAwareMethods(beanName, bean);
-
执行before的初始化方法
- wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
- postProcessBeforeInitialization
- ApplicationContextAwareProcessor
- CommonAnnotaionBeanPostProcessor
- 执行注解注释的两个方法
- InitDestroyAnnotationBeanPostProcessor
- PostConstruct . PreDestory
-
调用执行init-method
- isExternallyManagedInitMethod 防止init方法重复执行
- 实现了InitializeBean接口之后调用afterPropertiesSet方法
- 调用执行用户自定义初始化方法 init-method
- afterPropertiesSet
- bean 对象实现InitializingBean, 重写afterPropertiesSet,对象创建之后会被调用
- invokeCustomInitMethod mbd.getInitMethodName() 执行init方法
-
执行after的初始化方法
- wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
- AbstractAutoProxyCreator 实现aop功能
-
BeanFacotory 的子类
-
AbstractBeanFactory
- ListableBeanFactory
- ConfigurableBeanFactory
-
ApplicationContext
- ClassPathXmlApplicationContext
- AnnotationconfigApplicationContext
- FileSystemApplicationContext
-
ImportAwareBeanPostProcessor
循环依赖问题
- registerDisposableBeanIfNecessary 注册一次性使用的对象, 调用销毁方法的逻辑
- addSingleton(beanName, singletonObject); . 添加到缓存中
- 添加一级缓存
- 移除二级和三级,添加到已注册的单例集中
- bean的生命周期
- 定义好xml文件,java类之后
- 创建容器对象 obtainFreshBeanFactory
- 创建容器DefaultListableBeanFactory
- 给容器设置某些属性值
- 加载配置文件loadBeanDefinitions document element
- parseDefaultElement bean标签
- parceCustomerElement context标签 aop标签 自定义标签
- 获取到BeanDefinition GenericBeanDefinition 合并 获取到RootBeanDefinition
- prepareBeanFactory 给容器工厂设置某些属性值
- invokeBeanFactoryPostProcessor 执行调用BFPP,可以修改或者引入其它的beanDefinition,但是需要注意,BFPP针对的操作对象是BeanFactory
- ConfigurationClassPostProcessor . 用来完成相关注解的解析工作
- registerBeanPostProcessor 实例化BPP 完成BeanPostProcessor的注册工作,方便后续在实例化完成之后调用before 和after方法
- finishBeanFactorylnitialization 完成对象的创建工作
- 先从容器中找,找不到再创建
- 将需要创建的bean对象放到数组中,挨个进行创建
- getBean doGetBean
- createBean doCreateBean
- createBeanInstance
- supplier factory-method 通过反射的方式创建 BPP动态代理(instance方法之前)
- applyMergedBeanDefinitionPostProcessors 注册生命周期接口
- @PostConstruct @PreDestroy @Resource @Autowired @Value注解的解析
- populateBean
- 填充属性
- 创建需要依赖的Bean对象 递归调用 getBean
- initialzeBean 进行初始化工作
- invokeAwareMethod
- BeanNameAware BeanClassLoaderAware BeanFactoryAware
- 执行BPP的before方法
- ApplicationAwarePostProcessor 继续实现某些Aware接口的set方法
- CommonAnnotationBeanPostProcessor 执行 @PostConstruct @PreDestroy 定义的方法
- invokeInitMethod .
- 是否实现了InitalizingBean 执行afterProperties 最后一次修改属性的值
- 执行用户自定义的init-method
- 执行BPP的after方法 -----aop
- invokeAwareMethod
- 获取对象来进行相关操作
- 执行销毁流程
- 执行DestructionAwareBeanPostProcessor . postProcessBeforeDestruction
- DisposableBean
- 自定义的destoryMethod
- 去掉三级缓存:
- 在doCreateBean中有添加lambda表达式到三级缓存的代码,直接改成放到二级缓存
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
@Nullable
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
Object singletonObject = this.singletonObjects.get(beanName);
//一级缓存中没有
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
synchronized (this.singletonObjects) {
//直接从二级缓存中获取返回
return this.earlySingletonObjects.get(beanName);
}
}
return singletonObject;
}
- 从三级缓存获取对象的方法,getSingleton方法,将三级缓存的操作去掉
protected Object getSingleton(String beanName, boolean allowEarlyReference)
- 只有二级缓存为什么不会 throw new BeanCurrentlyInCreationException
- 一个对象出现了两个版本
- 三级缓存
- 往三级缓存加东西在填充属性之前
- 正常先放到三级,然后创建对象到最后,放到一级缓存中,删除三级缓存,删除二级缓存
- 三级缓存拿取对象的时机,循环依赖的时候需要再次获取到对象,先从一级获取,一级没有,从二级获取,二级没有,调用三级缓存的工厂方法,将返回的对像放回到二级缓存中,到最后对象创建完成,放到一级缓存,删除二级缓存,三级缓存
- 可能直接三级到一级
- 也可能三级,二级,一级
- 存放的类 DefaultSingletonBeanRegistry
- 如果发生循环依赖的对象,不需要代理的话,只需要二级缓存足矣解决所有问题,但是当存在代理之后就无法解决了,必须要使用三级缓存来解决
- addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
- 给三级缓存中放入的是 对象名 : () -> getEarlyBeanReference(beanName, mbd, bean)
- 如果getEarlyBeanReference 这个方法不需要代理返回原对象,然后将原对象放回二级缓存
- 对象完全创建好后,将对象放入一级缓存,删除二级缓存和三级缓存
- 三级缓存中并不是严格的三级 > 二级> 一级的对象转换顺序,有可能在三级和一级中有对象,也有可能一二三级中都有对象
- 三级缓存改二级缓存
- 放入三级的地方放入二级 doCreateBean中有添加lambda表达式到三级缓存的代码,改成直接放到二级缓存中
- 查找的时候二级找到直接返回 直接修改getSingleton方法,将三级缓存的操作去掉
- 代理对象生成的时机 BPP的after方法
- 有代理对象只用二级缓存出现的问题
- 首先创建普通对象A,设置普通对象A属性的时候实例化B,实例化B之后
- 设置B的A属性,从二级缓存中拿到A的普通对象,设置到普通对象B中,所以普通B对象的A属性是普通A对象
- 执行返回B对象的after方法生成B的代理对象,B代理对象中的A属性为null,然后设 置给A的B属性,所以普通对象A中的B属性是代理对象
- 完成创建A过程中的after方法生成A的代理对象,但A的代理对象中的B属性为null
- 先创建A,再创建B
- 创建B的时候创建A,创建A完成给B赋值后,生成B的代理对象,容器中有了两个B的对象
- B对象给A赋值后,生成A的代理对象,容器中有了两个A对象
- 在整个三级缓存中,对象只能存在一份
- 解决:在获取具体的对象的时候,直接生成对应的代理对象,B在获取A对象的时候,直接获取到A的代理对象,在获取的时候通过lambda表达式动态生成
SpringAop的BeanDefinition的准备工作
- aop . 动态代理 jdk cglib
- 概念
- Aspect 定义额为添加的业务逻辑(切面)
- Advise 怎么筛选具体的位置 . 判断 after before 的位置
- pointcut 需要执行额外逻辑的位置 pointcut 表达式
- 自己实现的逻辑
- 先编写额外的逻辑类 切面类
- 具体的某些方法要被执行处理 . 切点 before after . advisor 通知器 advice 通知
- 被应用在哪些方法上 连接点
- spring实现的大概逻辑
- 哪些类需要进行相关的切入:
- expression, pointcut
- 额外的逻辑处理,有几个通知消息或者说有哪些逻辑可以被执行 (哪个位置去执行,之前,之后,异常…)
- before, after, afterThrowing, afterReturing, around: advisor–>advice
- 额外的处理逻辑的类是哪个,也就是那个切面
- aspect
- pointcut . advisor advice . aspect
- method对象(执行额外的方法) beanFactory取出Bean对象,遍历
- 动态代理 字节码文件
- 使用方式 : xml 注解
- 哪些类需要进行相关的切入:
<bean id="logUtil" class="com.mashibing.aop.xml.util.LogUtil" ></bean>
<!-- aop定义方式 -->
<aop:config>
<aop:aspect ref="logUtil">
<!--切入点表达式-->
<aop:pointcut id="myPoint" expression="execution( Integer com.mashibing.aop.xml.service.MyCalculator.* (..))"/>
<!--aop:around 切的方式 method 执行的方法,代理额外执行的方法 pointcut-ref 切入点 -->
<aop:around method="around" pointcut-ref="myPoint"></aop:around>
<aop:before method="start" pointcut-ref="myPoint"></aop:before>
<aop:after method="logFinally" pointcut-ref="myPoint"></aop:after>
<aop:after-returning method="stop" pointcut-ref="myPoint" returning="result"></aop:after-returning>
<aop:after-throwing method="logException" pointcut-ref="myPoint" throwing="e"></aop:after-throwing>
</aop:aspect>
</aop:config>
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
1. 查看配置文件的解析工作,在处理之后的beanDefinition中包含什么信息
1. BeanDefinition的解析工作
2. 对aop相关的beanDefinition进行实例化操作
3. 在进行第一个对象创建之前,就必须吧aop需要的相关对象提前准备好,因为无法预估哪些对象需要动态代理
4. 在哪个步骤中可以提前实例化并且生成对应的对象
1. BFPP是用来对BeanFactory进行修改操作的,不会影响到后续的实例化操作
2. BPP (BeanPostProcessor 初始化完成前后(before 和after))
3. resolveBeforeInstantiation . 利用BPP中的 InstantiationAwareBeanPostProcessor子类
5. 子类
1. BeanPostProcessor
1. InstantiationAwareBeanPostProcessor 实例化之前 实例化之后 处理属性值
1. AbstractAdvisorAutoProxyCreator
2. AnnotationAwareAspectJAutoProxyCreator
3. SmartInstantiationAwareBeanPostProcessor
2. DestructionAwareBeanPostProcessor
3. MergedBeanDefinitionPostProcessor
- AopNamespaceUtils# configureAutoProxyCreator(parserContext, element);
- AopConfigUtils
- AUTO_PROXY_CREATOR_BEAN_NAME . internalAutoProxyCreator
- 注入 AspectJAwareAdvisorAutoProxyCreator 继承 AbstractAutoProxyCreator 继承 SmartInstantiationAwareBeanPostProcessor
- context:scan . AnnotationConfigUtils . 注入internal的各种类,注解和配置文件共同使用
- isAdviceNode(node, parserContext)
private boolean isAdviceNode(Node aNode, ParserContext parserContext) {
if (!(aNode instanceof Element)) {
return false;
}
else {
String name = parserContext.getDelegate().getLocalName(aNode);
return (BEFORE.equals(name) || AFTER.equals(name) || AFTER_RETURNING_ELEMENT.equals(name) ||
AFTER_THROWING_ELEMENT.equals(name) || AROUND.equals(name));
}
}
- AbstractBeanDefinition advisorDefinition = parseAdvice 解析advice
- AspectJAroundAdvice
- 构造参数 Method 环绕通知的方法 . 0号构造参数
- AspectJExpressionPointcut . 切入点表达式 1号构造参数
- AspectInstanceFactory 工厂做什么的 2号构造参数
- MethodLocatingFactoryBean methodDef
- targetBeanName logUtil
- methodName around
- SimpleBeanFactoryAwareAspectInstanceFactory aspectFactoryDef
- aspectBeanName logUtil
- beanFactory 实现了 implement BeanFactoryAware
- RootBeanDefinition (class 根据元素的名称获取对应的advise class) getAdviceClass(adviceElement, parserContext)
- aspectName logUtil
- ConstructorArgumentValues cav = adviceDefinition.getConstructorArgumentValues(); 获取Bean定义信息的构造方法
- cav.addIndexedArgumentValue(METHOD_INDEX, methodDef); 0号参数
- pointcutRef = new RuntimeBeanReference((String) pointcut)
- cav.addIndexedArgumentValue(POINTCUT_INDEX(1), pointcutRef); 1号参数
- cav.addIndexedArgumentValue(ASPECT_INSTANCE_FACTORY_INDEX, aspectFactoryDef); 2号参数
- RootBeanDefinition advisorDefinition = new RootBeanDefinition(AspectJPointcutAdvisor.class); advise外边要包一个advisor
- AspectJPointcutAdvisor . advice 外边包advisor
- AbstractAspectJAdvice advice; 参数
- Pointcut pointcut; 参数 从advice中获取
- Integer order; 参数
- AspectJPointcutAdvisor(AbstractAspectJAdvice advice) 构造方法
- 构造方法各种嵌套
- AbstractBeanDefinition pointcutDefinition = createPointcutDefinition(expression);
- new RootBeanDefinition(AspectJExpressionPointcut.class)
- setScope(BeanDefinition.SCOPE_PROTOTYPE) 原型模式
- 要使用注解aop,必须加@EnableAspectJAutoProxy注解
- AspectJAutoProxyRegistrar
- AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
- 注入 AnnotationAwareAspectJAutoProxyCreator 继承 SmartInstantiationAwareBeanPostProcessor
- Import 有ImportBeanDefinitionRegistrar 在 ConfigurationClassPostProcessor 处理中会调用registerBeanDefinitions
- aop:aspectj-autoproxy</aop:aspectj-autoproxy> 开启注解aop
- AspectJAutoProxyBeanDefinitionParser xml的解析器
- registerAspectJAnnotationAutoProxyCreatorIfNecessary
- 实例化AspectJAwareAdvisorAutoProxyCreator BPP放入到factory中
- 总结
- 准备beanDefinition
- AspectJExpressPointcut Advisor#0–#4 AspectJAutoProxyCreator
- AspectJExpressPointcut Advisor#0–#4 AspectJAutoProxyCreator
SpringAop核心对象的创建过程
- resolveBeforeInstantiation
- postProcessBeforeInstantiation
- isInfrastructureClass(beanClass) 是否是基础信息类,创建过程中返回true,直接跳过后续流程
- AspectJAwareAdvisorAutoProxyCreator
- shouldSkip findCandidateAdvisors() 切面类的实例化
- findAdvisorBeans() 找到当前容器中存在的advisor
- this.advisedBeans.put(cacheKey, Boolean.FALSE) 跳过的类放到缓存中
- (inner bean)" + BeanFactoryUtils.GENERATED_BEAN_NAME_SEPARATOR 生成inner bean
- this.aspectJAdvisorsBuilder.buildAspectJAdvisors() 解析利用注解解析的aop @Aspect
- 注解使用切面
- EnableAspectJAutoProxy–> AspectJAutoProxyRegistar–>AnnotationAwareAspectJAutoProxyCreator->advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors()); 处理注解
- advisor创建对象步骤
- 实例化–>调用有参构造方法创建对象–>在执行之前必须要把构造器中需要的对象提前创建好–>会包含无数个嵌套的环节
- adviseBeans 缓存
- 创建AspectJPointcutAdvisor对象–> 构造–>AspectJAroundAdvice --> 构造–>Method, AspectJExpressonPointCut,AspectInstanceFactory
- this.advisorFactory.isAspect(beanType) . 判断当前bean 是否有aspect注解
SpringAop核心对象的创建过程二
- ((AspectJPointcutAdvisor) advisor).getAspectName().equals(beanName) 让logUtil可以被跳过,不用被代理
- findCandidateAdvisors() 创建出来的对象会放在一级缓存中
- TargetSource targetSource = getCustomTargetSource(beanClass, beanName) 一般会跳过,用户自定义动态代理的方式,针对当前的被代理类需要经过标准的代理流程来创建对象
- aop动态代理的入口:是在创建完对象,执行完invokeInitMethods 初始化方法,applyBeanPostProcessorsAfterInitialization增强的时候创建代理对象
- 当使用springaop的时候,需要进行n多个对象的创建,创建过程中需要判断该对象是否需要被代理,代理之前,需要的advisor对象必须要提前创建好,才能进行后续的判断
- 如果定义的普通对象,会进行resolveBeforeInstance()方法的处理
- 一个对象被代理,该对象的普通对象也会创建
- public static boolean canApply(Advisor advisor, Class<?> targetClass, boolean hasIntroductions) 根据pointcut匹配是否能够被代理
- 先匹配类再匹配方法 ClassFilter MethodMatcher
- CallbackInfo
- MethodInterceptor InvocationHandler LazyLoader Dispatcher
- findAdvisorsThatCanApply 获取可以拦截的advisor
- pc.getClassFilter().matches(targetClass) 表达式的验证
- MethodMatcher methodMatcher = pc.getMethodMatcher()
- introductionAwareMethodMatcher.matches
- 方法的匹配器
- PointcutAdvisor方法级别的增强 IntroductionAdvisor 类级别的增强
- findEligibleAdvisors(beanClass, beanName) 获取符合条件的拦截器
- advisors.add(0, ExposeInvocationInterceptor.ADVISOR); 添加ExposeInvocationInterceptor
- sortAdvisors(eligibleAdvisors) 排序advisor 拓扑排序,看是否有前驱节点
- ExposeInvocationInterceptor
- 步骤
- 遍历当前容器中存在的beanDefinition,并进行对象的创建工作
- 从list中按照顺序开始进行对象的创建
- getBean doGetBean createBean
- resolveBeforeInstance() 给beanPost一个机会去返回自定义代理的对象,在当前BPP中存在一个AutoProxyCreator的对象,会执行后续的判断逻辑,创建代理需要的对象
- postProceeBeforeInstantiation() AbstractAutoProxyCreator
- 判断当前处理中的对象是否需要被代理 shouldSkip()
- 创建动态代理需要的advisor对象
- 遍历当前容器中存在的Advisor的BeanDefinition
- 经过循环将所有的Advisor对象准备好
- findCandidateAdvisors . 获取xml中的切面
- this.aspectJAdvisorsBuilder.buildAspectJAdvisors() 获取注解中的切面
- 创建过程比较麻烦,包含了N多个对象的迭代创建,包括AspectJAroundAdvice(MethodLocationFactoryBean,AspectExpressionPointcut,SimpleBeanFactoryAwareAspectlnstanceFactory)
- 如果跳过的话,直接返回空对象
- doCreateBean . createBeanInstance . populateBean . initialzeBean
- postProcessAfterInitialization . AbstractAutoProxyCreator
- wrapIfNecessary . 判断是否需要被代理
- shouldSkip() .
- getAdvicesAndAdvisorsForBean . 获取符合条件的advisor
- findEligibleAdvisors . 找合适的增强器对象
- findAdvisorsThatCanApply . 进行切入点的匹配解析 -->List . eligibleAdvisors
- extendAdvisors(eligibleAdvisors); . 提供的hook方法 添加ExposeInvocationInterceptor
- sortAdvisors(eligibleAdvisors) 排序
- 进行代理的创建 createProxy
- findEligibleAdvisors . 找合适的增强器对象
jdk和cglib动态代理实现原理
jdk动态代理
- Proxy.newProxyInstance(loader, interfaces, h)
- getProxyClass0(loader, intfs) 获取动态代理类
- new Factory(key, parameter, subKey, valuesMap) 创建动态代理的supplier
- supplier.get() 获取
- valueFactory.apply(key, parameter)
- ProxyClassFactory 中的apply方法
- proxyPkg = ReflectUtil.PROXY_PACKAGE + “.” 生成代理类的包名
- proxyPkg + proxyClassNamePrefix + num 代理类的类名
- ProxyGenerator.generateProxyClass 生成代理类的class字节码
- defineClass0(loader, proxyName,…)生成代理类class
- cl.getConstructor(constructorParams) 获取代理类构造方法 构造参数 . InvocationHandler
- cons.newInstance(new Object[]{h}) 生成代理对象
- 调用方法 (Boolean)super.h.invoke(this, m1, new Object[]{var1});
- 实际调用的是InvocationHandler 的invoke 方法
cglib代理
new Enhancer(); 创建enchancer 对象
- EnhancerKey KEY_FACTORY = (EnhancerKey)KeyFactory.create(EnhancerKey.class, KeyFactory.HASH_ASM_TYPE, (List)null); . 创建EnhancerKey对象
- Generator gen = new Generator()
- AbstractclassGenerator.create
- Map<ClassLoader, ClassLoaderData> cache
- ClassLoaderData中 .
- Function<AbstractClassGenerator, Object> GET_KEY
- Function<AbstractClassGenerator, Object> load . 生成新的代理类
- generatedClasses = new LoadingCache<AbstractClassGenerator, Object, Object>(GET_KEY, load)
- ClassLoaderData.get()
- generatedClasses.get(gen)
- KK cacheKey = this.keyMapper.apply(key) . 执行 GET_KEY的函数
- LoadingCache.this.loader.apply(key). 执行load 的函数,
- gen.generate(ClassLoaderData.this) 创建代理
- generateClassName(data.getUniqueNamePredicate()) . 代理类的名称
- strategy.generate(this) 生成字节码
- ReflectUtils.defineClass生成class类
- ReflectUtils.newInstance(type) 创建代理对象
(MyCalculator) enhancer.create() . 创建自己的代理对象
- this.createHelper()
- KEY_FACTORY.newInstance; EnhancerKey
- super.create(key)
- AbstractclassGenerator.create
- MethodInterceptor var10000;
- var10000.intercept 调用代理对象的方法,实际调用MethodInterceptor 的intercept方法
Aop动态代理的创建过程
- shouldProxyTargetClass 判断使用jdk动态代理还是cglib代理
- evaluateProxyInterfaces 计算是否有符合的接口
- createAopProxy
// 判断目标类是否是接口 如果目标类是接口的话,则还是使用JDK的方式生成代理对象
// 如果目标类是Proxy类型 则还是使用JDK的方式生成代理对象
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
// 配置了使用Cglib进行动态代理或者目标类没有接口,那么使用Cglib的方式创建代理对象
return new ObjenesisCglibAopProxy(config);
- interface
- adviced 用来配置代理 是 proxyFactory 的 接口 代理工厂
- SpringProxy
- getCallbacks(rootClass)
- MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
- Callback[0] ===> DynamicAdvisedInterceptor
- Callback[0] ===> DynamicAdvisedInterceptor
Aop拦截器链的执行
- CglibAopProxy DynamicAdvisedInterceptor 动态代理方法跳进来的位置
- getInterceptorsAndDynamicInterceptionAdvice 获取拦截器链
- DefaultAdvisorAdapterRegistry 添加了三个适配器
registerAdvisorAdapter(new MethodBeforeAdviceAdapter());
registerAdvisorAdapter(new AfterReturningAdviceAdapter());
registerAdvisorAdapter(new ThrowsAdviceAdapter());
- mm.matches(method, actualClass) 此时会对方法再次匹配,之前匹配到方法后立即返回,说明该类会被代理,执行的时候会再次匹配,决定该方法要不要走代理
- registry.getInterceptors(advisor) 获取 interceptor
// 从Advisor中获取 Advice
Advice advice = advisor.getAdvice();
//如果是MethodInterceptor,直接添加
if (advice instanceof MethodInterceptor) {
interceptors.add((MethodInterceptor) advice);
}
for (AdvisorAdapter adapter : this.adapters) {
//adapter是否支持此advice
if (adapter.supportsAdvice(advice)) {
// 转换为对应的 MethodInterceptor类型
// AfterReturningAdviceInterceptor MethodBeforeAdviceInterceptor ThrowsAdviceInterceptor
//获取对应的Interceptor
interceptors.add(adapter.getInterceptor(advisor));
}
}
-
通过适配器获取interceptor
- AspectJMethodBeforeAdvice .
- MethodBeforeAdviceAdapter . getInterceptor 获取拦截器的方法
- MethodBeforeAdviceInterceptor 实现MethodInterceptor 调用BeforeAdvice的方法
- AspectJAfterReturningAdvice
- AfterReturningAdviceAdapter
- AfterReturningAdviceInterceptor 获取拦截器
- ThrowsAdviceAdapter
- AspectJMethodBeforeAdvice .
-
直接实现MethodInterceptor
- AspectJAfterAdvice 实现 MethodInterceptor
- AspectJAfterThrowingAdvice 实现MethodInterceptor
- AspectJAroundAdvice 实现MethodInterceptor
-
CglibMethodInvocation 是 CglibAopProxy的内部类, 是 ReflectiveMethodInvocation的子类
-
顺序
- ExposeInvocationInterceptor
- invocation.set(mi); mi 是 ReflectiveMethodInvocation
- AspectJAfterThrowingAdvice
- 直接执行后续,捕获到异常执行advice方法
- AspectJAfterReturningAdvice . (AfterReturningAdviceInterceptor)
- 直接执行后续,后续执行完,执行advice方法
- AspectJAfterAdvice
- 直接执行后续方法,finally中执行advice方法
- AspectJAroundAdvice
- ProceedingJoinPoint pjp JoinPoint 的子类
- invokeAdviceMethod 调用通知的方法
- invokeAdviceMethodWithGivenArgs
- this.aspectJAdviceMethod.invoke
- pjp.proceed(args)
- this.methodInvocation.invocableClone(arguments).proceed(); ==== mi.proceed()
- 执行advice方法,在执行的过程中,调用before的方法
- AspectJMethodBeforeAdvice(MethodBeforeAdviceInterceptor)
- 先执行advice方法,再执行后续
- ExposeInvocationInterceptor
-
ReflectiveMethodInvocation 执行代理方法的类
-
beanFactoryPostProcessor的分类
- BeanFactoryPostProcessor主要针对的操作对象是BeanFactory
- BeanDefinitionRegistryPostProcessor主要针对的操作对象是BeanDefinition
-
BeanFactoryPostProcessor
- 接口方法postProcessBeanFactory
-
BeanDefinitionRegistryPostProcessor
-
实现类 ConfigurationClassPostProcessor
-
接口方法postProcessBeanDefinitionRegistry
-
AnnotationAwareAspectJAutoProxyCreator
-
TxAdviceBeanDefinitionParser
-
TransactionInterceptor
-
TxAdviceBeanDefinitionParser
-
aop xml 配置切面的bean
-
AspectJExpressionPointCut
-
DefaultBeanFactoryPointcutAdvisor
-
TransactionInterceptor
-
NameMathcTransactionAttributeSource
-
aop 注解 配置切面的bean
-
BeanFactoryTransactionAttributeSourceAdvisor
-
TansactionInterceptor
-
AnnotationTransactionAttributeSource
注解类的启动
- AnnotatedBeanDefinitionReader
- getOrCreateEnvironment
- ConditionEvaluator 条件计算器 @ConditionOnBean 等的解析
- registerAnnotationConfigProcessors
- unwrapDefaultListableBeanFactory 获取beanFactory
- 添加 ConfigurationClassPostProcessor AutowiredAnnotationBeanPostProcessor CommonAnnotationBeanPostProcessor EventListenerMethodProcessor DefaultEventListenerFactory
- ClassPathBeanDefinitionScanner
- setEnvironment(environment);
- ac.register
- registerBean(componentClass) 注册自己的配置类
- ac.refresh()
- ConfigurationClassPostProcessor执行
- 解析ComponentScan
- 解析EnableAspectJAutoProxy
- AspectJAutoProxyRegistrar
- registerBeanDefinitions
- AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
- 将AnnotationAwareAspectJAutoProxyCreator 注入到容器中
- registerBeanDefinitions
- AspectJAutoProxyRegistrar
- aop执行的顺序不一定,因为拓扑排序时构建有向无环图的方式不一定,而且构建图之后获得的排序也不一定
声明式事务讲解
- 事务控制方式1
- TransactionManager
- TransactionDefinition(构造 TransactionManager)
- TransactionStatus(构造 TransactionDefinition)
- transactionManager.commit(transactionStatus)
- 事务控制方式2
- transactionDefinition 自动注入
- TransactionStatus transactionStatus = transactionManager.getTransaction(transactionDefinition);
- transactionManager.commit(transactionStatus);
- 需要aop的对象
- AspectJAwareAdvisorAutoProxyCreator
- advice Method 表达式 singletonFactory 把MethodInterceptor当做advice
- advisor DefaultBeanFactoryPointcutAdvisor . .
- MethodInterceptor Transactionlnterceptor 中包含 NameMatchTransactionAttributeSource, 它中包含需要事务的方法和事务的属性 里边有个invoke方法,增强的方法
- poiintcut AspectJExpressionPointcut aop:pointcut 标签
- 解析xml
- 注入
- beanDefinition 名称是#0,#1,#2
- 容器生成的内部类是(inner bean)#
- TxNamespaceHandler
- parseAttributeSource 处理xml中attribute定义的需要事务的方法,和当中的属性
- invokeBeanFactoryPostProcessors PropertySourcesPlaceholderConfigurer 进行${} 符号的替换
- registerBeanPostProcessors 创建 AspectJAwareAdvisorAutoProxyCreator
- postProcessBeforeInstantiation shouldSkip findCandidateAdvisors 进行advisor对象的创建, 创建了DefaultBeanFactoryPointcutAdvisor和AspectJExpressionPointcut 对象,但是没有进行advice对象的创建
- 创建了DataSource对象,但是没有与数据库建立连接
- getAdvicesAndAdvisorsForBean 创建Transactionlnterceptor 入口
- extendAdvisors(List candidateAdvisors) 给DefaultBeanFactoryPointcutAdvisor 设置advice
- 返回两个advisor一个ExposeInvocationInterceptor,一个DefaultBeanFactoryPointcutAdvisor,里边包含Transactionlnterceptor
- public Advice getAdvice() 创建 Transactionlnterceptor
- MethodInterceptor的子类可以当做是advice
//给DefaultBeanFactoryPointcutAdvisor 设置advice
if (this.beanFactory.isSingleton(this.adviceBeanName)) {
// Rely on singleton semantics provided by the factory.
//TransactionInterceptor, 实现了MethodInterceptor, 是advice的子类,所以能获取到
advice = this.beanFactory.getBean(this.adviceBeanName, Advice.class);
this.advice = advice;
return advice;
}
- 创建txAdvice MethodInterceptor 的时候,会创建NameMatchTransactionAttributeSource,这个里边有
- Map<String, TransactionAttribute> nameMap
- RuleBasedTransactionAttribute RuleBasedTransactionAttribute的子类
- 调用方法会进入 DynamicAdvisedInterceptor
spring注解配置的声明式事务
- EnableTransactionManagement
- @Import(TransactionManagementConfigurationSelector)
- AutoProxyRegistrar
- ProxyTransactionManagementConfiguration
- InfrastructureAdvisorAutoProxyCreator
- 使用注解声明的事务,动态代理需要的对象不在resolveBeforeInstantiation过程中创建
- ConfigurationClassPostProcessor postProcessBeanFactory
- enhanceConfigurationClasses(beanFactory) 中对@Configuration的类进行代理,目的为了@Bean标注的方法每次返回的都是单例对象,都是从工厂单例中获取
- 筛选时拿到属性为full的配置类
- 执行流程
- 准备事务处理的相关对象: 事务对象, 连接器, 事务信息, 事务状态, 事务属性
- 执行逻辑
- 是否有异常, 有异常,回滚, 没有异常,正常提交
- 由不同的传播特新决定不同方法的事务应该如何获取
Spring声明式事务的运行流程
- invokeWithinTransaction
- TransactionAttribute txAttr 事务的基础属性
- determineTransactionManager(txAttr) 获取事务管理器
- PlatformTransactionManager ptm = asPlatformTransactionManager™ 将事务管理器转换为PlatformTransactionManager
- TransactionInfo txInfo = createTransactionIfNecessary 创建事务
- TransactionStatus 事务的状态 hasSavepoint 维护了一个保存点,回滚到指定的位置,事务的状态 TransactionExecution 父类
- TransactionDefinition def 事务的定义信息
- Object transaction = doGetTransaction() 获取事务
- DataSourceTransactionObject 数据源事务对象
- nestedTransactionAllowed
- obtainDataSource() 获取数据源,获取事务管理器中的数据源
- doGetResource(actualKey) 获取存储在ThreadLocal中之前保存的数据源
- txObject.setConnectionHolder(conHolder, false) 第一次设置默认是旧的连接,后边会重新赋值
- TransactionSynchronizationManager.getResource 从缓存中获取conect对象
- DataSourceTransactionObject 数据源事务对象
- TransactionSynchronizationManager 事务管理器
- ThreadLocal<Map<Object, Object>> resources key dataSource, value connect 数据源和连接的绑定关系,第二次获取的时候直接从此获取,不用重新获取连接
- suspend(@Nullable Object transaction) 挂起之前的事务
- startTransaction(def, transaction, debugEnabled…)开启事务
- DefaultTransactionStatus status = newTransactionStatus
- doBegin(transaction, definition)
- obtainDataSource().getConnection() 建立连接
- con.setAutoCommit(false) 关闭自动提交
- TransactionSynchronizationManager.bindResource 将数据源和连接绑定
- prepareSynchronization(status, definition) 只有新事务的时候设置TransactionSynchronizationManager中其他的属性
- TransactionInfo prepareTransactionInfo 创建一个事务信息
- bindToThread() 为了事务的恢复
1. this.oldTransactionInfo = transactionInfoHolder.get(); //之前的事务信息从缓存中获取
2. transactionInfoHolder.set(this); //将当前的事务信息放到缓存中 - handleExistingTransaction(def, transaction, debugEnabled) 处理已经存在的事务
- cleanupTransactionInfo(txInfo) 清除事务信息
- restoreThreadLocalStatus
- transactionInfoHolder.set(this.oldTransactionInfo)
- commitTransactionAfterReturning(txInfo) 提交事务,但不一定会提交,在required最外层事务提交
- txInfo.getTransactionManager().commit(txInfo.getTransactionStatus())
- doCommit(status)
- con.commit()
- cleanupAfterCompletion(status)
- status.setCompleted()
Spring传播特性
- completeTransactionAfterThrowing
- processRollback(defStatus, false)
- status.hasSavepoint()
- status.rollbackToHeldSavepoint()
- getSavepointManager().rollbackToSavepoint(savepoint)
- status.rollbackToHeldSavepoint()
// 回滚到保存点(实际处理)
conHolder.getConnection().rollback((Savepoint) savepoint);
// 重置回滚标记,不需要回滚 this.rollbackOnly = false
conHolder.resetRollbackOnly();
- status.isNewTransaction()
- doRollback(status
- this.globalRollbackOnParticipationFailure 全局回滚在一部分发生异常之后
- doSetRollbackOnly(status) 设置全局回滚
- txObject.setRollbackOnly()
- 外层捕获了内层的异常,到了外层事务处理的时候,需要进行commit,但是内层事务将connect的rollBackOnly属性设置为true,所以在外层事务中执行数据库的rollback操作,同时将unexpectedRollback设置为true,在代码中抛出异常
if (unexpectedRollback) {
throw new UnexpectedRollbackException(
"Transaction rolled back because it has been marked as rollback-only");
}
- NESTED执行过程 没有创建新的连接 ,已经在内层事务中自己处理rollback了,然后设置rollbackOnly为false,外层事务正常提交就可以了
- status.createAndHoldSavepoint(); 为当前事务创建一个回退点
- this.savepointCounter++;
- conn.setSavepoint(name) savePointName
- savepoint p1 ; rollback to p1;
- REQUIRES_NEW
- suspend(transaction)
- doSuspend(transaction)
- txObject.setConnectionHolder(null);
- TransactionSynchronizationManager.unbindResource(obtainDataSource()) 将数据源和connect的绑定关系解绑,从缓存中移除
- new SuspendedResourcesHolder 创建一个挂起的Holder
- DefaultTransactionStatus( this.suspendedResources = suspendedResources; )
- TransactionSynchronizationManager.bindResource 将新的事物信息(REQUIRES_NEW)进行绑定
- cleanupAfterCompletion(status); 回滚完成后清空事务信息链接
- resume(transaction, (SuspendedResourcesHolder) status.getSuspendedResources()) 恢复之前事务挂起的信息
- TransactionSynchronizationManager.bindResource 将数据源和之前的连接Connect重新绑定