参考文档:
Spring开闭原则的表现-BeanPostProcessor的扩展点-1
通过AnnotationConfigApplicationContext
类,采用注解配置bean
的方式,简单解读Spring源码.
public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
this();
register(componentClasses);
refresh();
}
Spring源码简单解读
一. 创建BeanFactory
AnnotationConfigApplicationContext
继承自父类GenericApplicationContext
private final DefaultListableBeanFactory beanFactory;
...
/**
* Create a new GenericApplicationContext.
* @see #registerBeanDefinition
* @see #refresh
*/
public GenericApplicationContext() {
this.beanFactory = new DefaultListableBeanFactory();
}
父类构造方法中,BeanFactory被实例化
二. 创建一个BeanDefinition读取器,用于添加BeanFactory 后置处理器以及Bean后置处理器
方法入口在AnnotationConfigApplicationContext
无参构造方法,即this()
中
public AnnotationConfigApplicationContext() {
StartupStep createAnnotatedBeanDefReader = this.getApplicationStartup().start("spring.context.annotated-bean-reader.create");
this.reader = new AnnotatedBeanDefinitionReader(this);
createAnnotatedBeanDefReader.end();
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
主要代码
org.springframework.context.annotation.AnnotationConfigUtils#registerAnnotationConfigProcessors
...
Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
}
if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
}
...
ConfigurationClassPostProcessor
会解析加了@Configuration
的配置类,加了@Bean
注解的类,还会解析@ComponentScan
、@ComponentScans
注解扫描的包,以及解析@Import
等注解。
AutowiredAnnotationBeanPostProcessor
会解析加了@Autowired
的类、@Value
的参数。
CommonAnnotationBeanPostProcessor
会解析加了@PostConstruct
、@PreDestroy
标注的方法,以及@Resource
标记的字段或方法。
三. 将上述Bean解析并注册到Spring上下文中
方法入口为register(componentClasses);
主要代码
org.springframework.context.annotation.AnnotatedBeanDefinitionReader#doRegisterBean
...
// 完成条件注解@Conditional的解析和判断
if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
return;
}
...
// 处理类上的通用注解
AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
...
// 把BeanDefination封装为BeanDefinitionHolder
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
// 根据scopedProxyMode为Bean创建相应模式的代理对象
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
// 注册到Spring容器中,即ApplicationContext中
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
四. 容器刷新
refresh();
主要包括配置 BeanFactory、执行BeanFactory后置处理器、执行Bean实例化前的后置处理器、Bean的实例化、执行Bean实例化后的后置处理器、属性赋值、执行Bean初始化前的后置处理器、Bean初始化、执行Bean初始化后的后置处理器、Bean销毁。
4.1 配置BeanFactory,添加一些内置组件,预处理过程
// 获取第一步创建的BeanFactory
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 配置BeanFactory
prepareBeanFactory(beanFactory);
主要代码
org.springframework.context.support.AbstractApplicationContext#prepareBeanFactory
...
//设置Spring el表达式实现
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
...
// 添加bean后置处理器, 如果实现了相应的 Aware 接口,则注入对应的资源
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
...
// 注册可以解析的自动装配类,即可以在任意组件中通过注解自动注入
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
...
// 判断存在AOP beanName ,则添加编译时的 AspectJ
if (!NativeDetector.inNativeImage() && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
...
4.2 执行BeanFactory后置处理器,将Bean添加到Spring容器中
用户自定义的,实现了BeanFactoryPostProcessor
接口的后置处理器,就是在该步骤执行。
用户自定义的bean
,也是在这一步被注册到Spring容器中。
// 执行 BeanFactoryPostProcessor 方法,beanFactory 后置处理器
invokeBeanFactoryPostProcessors(beanFactory);
主要代码
org.springframework.context.support.PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors
代码就不列出来了,主要流程如下:
- 遍历循环所有BeanFactoryPostProcessor集合,首先取出BeanDefinitionRegistryPostProcessor,并且执行接口方法,再放入registryProcessors容器中。
- BeanFactory 中获取所有BeanDefinitionRegistryPostProcessor类型的beanName 数组,遍历循环数据,判断是否有PriorityOrdered接口,加入容器中,并且根据接口重新排序后,遍历容器所有类,执行接口方法,加入registryProcessors容器中。
- 重新获取所有BeanDefinitionRegistryPostProcessor类型的beanName 数组,循环遍历取出实现Ordered接口,按照Orderd顺序排序集合,依次执行接口方法,加入放入registryProcessors容器中.
- 将剩下所有BeanDefinitionRegistryPostProcessor,加入registryProcessors容器中。执行registryProcessors容器中所有BeanFactoryPostProcessor的接口方法。
- BeanFactoryPostProcessor也是按照上面的思路,先过滤排序执行接口方法。
采用注解方式,大部分bean
都是通过ConfigurationClassPostProcessor
后置处理器注册到Spring容器中的。
将bean
注册到Spring容器的主要方法:org.springframework.beans.factory.support.DefaultListableBeanFactory#registerBeanDefinition
在Spring中,所有的bean
被保存在容器的beanDefinitionMap
中,类型是Map<String, BeanDefinition>
.
4.3 Bean的实例化、属性赋值、初始化以及Bean后置处理器的执行
// 初始化所有非延迟加载 单例 bean
finishBeanFactoryInitialization(beanFactory);
往里找,会找到如下方法:
org.springframework.beans.factory.support.DefaultListableBeanFactory#preInstantiateSingletons
Spring Bean的主要生命周期就在这个方法中
主要流程:
4.3.1 执行Bean实例化前的后置处理器
实例化前的后置处理器,在上述图中createBean
方法中执行。
主要方法:
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#resolveBeforeInstantiation
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
// Make sure bean class is actually resolved at this point.
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
Class<?> targetType = determineTargetType(beanName, mbd);
if (targetType != null) {
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}
BeanPostProcessor扩展点,可以通过实现InstantiationAwareBeanPostProcessor
接口,通过重写postProcessBeforeInstantiation
方法,返回自定义的对象或者代理对象。如果返回的bean
不为空,会继续执行bean
初始化后的后置处理器,Spring将不会执行bean
属性的注入,以及bean
的初始化。
4.3.2 Bean的实例化
Bean的实例化,在上述图中createBeanInstance
方法中执行。
根据指定bean
使用对应的策略创建新的实例,如:工厂方法、构造函数注入、简单初始化。
主要代码
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBeanInstance
...
// 确保class不为空,并且访问权限为public
if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
}
// 通过回调方法创建对象,但是其后面的生命周期不影响。
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
return obtainFromSupplier(instanceSupplier, beanName);
}
// 使用工厂方法初始化策略
if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
// 是否有构造函数或者工厂方法
boolean resolved = false;
// 构造器是否有参数
boolean autowireNecessary = false;
if (args == null) {
synchronized (mbd.constructorArgumentLock) {
// spring会将解析、确定好的构造函数缓存到RootBeanDefinition的resolvedConstructorOrFactoryMethod中
// 在下次创建相同的bean时,直接从RootBeanDefiniton中的属性缓存中获取,避免重复解析
if (mbd.resolvedConstructorOrFactoryMethod != null) {
resolved = true;
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}
if (resolved) {
if (autowireNecessary) {
// 使用有参构造函数创建
return autowireConstructor(beanName, mbd, null, null);
}
else {
// 使用默认构造函数创建
return instantiateBean(beanName, mbd);
}
}
// 寻找当前正在实例化的bean中有@Autowired注解的 构造函数
// 自动注入有三种模式:属性、构造方法、普通方法
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
/**
* 以下情况符合其一即可使用有参构造函数创建
* 1.存在可选构造方法
* 2.自动装配模型为构造函数自动装配
* 3.RootBeanDefinition中设置的有构造函数所需参数值
* 4.参与构造函数的参数不为空
*/
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
return autowireConstructor(beanName, mbd, ctors, args);
}
// 找到默认的构造方法
ctors = mbd.getPreferredConstructors();
if (ctors != null) {
return autowireConstructor(beanName, mbd, ctors, null);
}
// 使用默认的无参构造方法进行初始化
return instantiateBean(beanName, mbd);
4.3.3 执行bean实例化后的后置处理器
在上图populateBean
方法中执行
主要代码
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
return;
}
}
}
BeanPostProcessor扩展点,可以通过实现InstantiationAwareBeanPostProcessor
接口,通过重写postProcessAfterInstantiation
方法,完成对bean
的属性赋值,返回false
,不再通过Spring处理属性。
注意:如果返回false
,BeanFactory
后置处理器对bean
属性的操作也会不生效!
4.3.4 属性赋值
在上图populateBean
方法中执行
主要代码
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean
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);
// 根据名称自动注入
if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
// 根据类型自动注入
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;
// 执行实现InstantiationAwareBeanPostProcessor接口的postProcessPropertyValues方法,对属性再进行处理
if (hasInstAwareBpps) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
pvsToUse = bp.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) {
// 将属性值设置到Bean中
applyPropertyValues(beanName, mbd, bw, pvs);
}
BeanPostProcessor扩展点,可以通过实现InstantiationAwareBeanPostProcessor
接口,通过重写postProcessProperties
方法,完成对bean
的属性赋值。
@Autowired
、@Resource
注解修饰的属性,都是在这一步被注入。
4.3.5 执行Bean初始化前的后置处理器
在上图initializeBean
方法中执行
主要代码
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean
...
// 调用BeanNameAware、BeanClassLoaderAware、BeanFactoryAware
// Aware类型的接口的作用就是让我们能够拿到Spring容器中的一些资源。
// Aware之前的名字就是可以拿到什么资源,例如Bean实现EnvironmentAware接口,可以拿到Environment,以此类推。
// 所有的Aware方法都是在初始化阶段之前调用的
invokeAwareMethods(beanName, bean);
...
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
// 执行BeanPostProcessor扩展点的postProcessBeforeInitialization进行修改实例化Bean
// 调用 EnvironmentAware、EmbeddedValueResolverAware、ApplicationContextAware
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInitialization
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessBeforeInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
BeanPostProcessor扩展点,实现BeanPostProcessor
接口中的postProcessBeforeInitialization
方法即可。
@PostConstruct
注解修饰的方法,也是在该扩展点,通过CommonAnnotationBeanPostProcessor
后置处理器执行。
4.3.6 Bean初始化
在上图initializeBean
方法中执行
主要代码
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#invokeInitMethods
...
// 如果当前bean是 InitializingBean类型的
// 并且afterPropertiesSet这个方法没有注册为外部管理的初始化方法
// 回调afterPropertiesSet方法
((InitializingBean) bean).afterPropertiesSet();
...
// 如果设置了initMethod方法的话
// 并且这个类不是 InitializingBean类型
// 并且这个方法不是 afterPropertiesSet方法
// 执行用户配置的初始话方法
invokeCustomInitMethod(beanName, bean, mbd);
...
实现InitializingBean
接口的类,其中的afterPropertiesSet()
方法会在上述afterPropertiesSet()
中执行。
@Bean(initMethod = "xxx")
如果采用这种方式定义bean
的initMethod
方法,该类中的xxx()
方法会在上述invokeCustomInitMethod
方法中执行。
至此,bean
的初始化完成。
4.3.7 执行Bean初始化后的后置处理器
在上图initializeBean
方法中执行
主要代码
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
BeanPostProcessor扩展点,实现BeanPostProcessor
接口中的postProcessAfterInitialization
方法即可。
如果一个bean
被AOP代理,也是在本扩展点创建代理对象!
五、 Bean销毁
方法入口为
org.springframework.context.support.AbstractApplicationContext#close
通过实现DisposableBean
接口的destroy
方法,可以增加Bean
销毁前的处理。
六、 测试
码云地址
有兴趣的朋友,可以在com.example.demo.DemoApplicationTests
中运行代码,看看各个扩展点的执行顺序。
@Test
void contextLoads() {
ApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class);
IMyTest myTest = context.getBean("myTest", IMyTest.class);
myTest.say();
((AnnotationConfigApplicationContext) context).close();
}
转载:https://blog.csdn.net/a770794164/article/details/115863665