【源码Spring系列】——Bean的生命周期(上)
前言
本文主要是从源码的角度讲解Spring中bean的生命周期,主要讲解bean完整的初始化过程,文中不包含bean的销毁过程。下图绘制为bean在spring启动过程涉及到关键节点。以后的讲解主要围绕下图的流程展开。
//样例代码
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
UserService userService = applicationContext.getBean("userService", UserService.class);
userService.test();
}
一、BeanFactory
1.创建BeanFactory
此时创建的BeanFactory是通过父类继承,在构造函数中默认初始化的
public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
// 1. 创建BeanFactory
// 2. 生成AnnotatedBeanDefinitionReader
// 3. 生成ClassPathBeanDefinitionScanner
this();
}
public AnnotationConfigApplicationContext() {
//public class AnnotationConfigApplicationContext extends GenericApplicationContext implements AnnotationConfigRegistry
// 在执行这个构造方法之前,会先执行父类GenericApplicationContext的构造方法,会初始化一个beanFactory = new DefaultListableBeanFactory()
// 生成并注册5个BeanDefinition
// org.springframework.context.annotation.AnnotationConfigUtils#registerAnnotationConfigProcessors(org.springframework.beans.factory.support.BeanDefinitionRegistry)
// 1.ConfigurationClassPostProcessor
// 2.AutowiredAnnotationBeanPostProcessor
// 3.CommonAnnotationBeanPostProcessor
// 4.EventListenerMethodProcessor
// 5.DefaultEventListenerFactory
this.reader = new AnnotatedBeanDefinitionReader(this);
// 注册默认的includeFilter
// org.springframework.context.annotation.ClassPathBeanDefinitionScanner#ClassPathBeanDefinitionScanner(org.springframework.beans.factory.support.BeanDefinitionRegistry, boolean, org.springframework.core.env.Environment, org.springframework.core.io.ResourceLoader)
// 添加includeFilters,Spring扫描的时候需要利用includeFilters,Spring扫描到某个类时如果能通过includeFilters的验证就证明这个类是一个Bean
// 默认注册一个@Component注解对应的Filter
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
在org.springframework.context.support.AbstractApplicationContext#refresh中开始对BeanFactory进行创建初始化后置处理器
org.springframework.context.support.AbstractApplicationContext#prepareBeanFactory
2.准备BeanFactory
- 设置BeanFactory的类加载器、表达式解析器、类型转化注册器
- 添加三个BeanPostProcessor,注意是具体的BeanPostProcessor实例对象
- 记录ignoreDependencyInterface
spring中属性注入默认是通过反射调用setXxx实现的
ignoredDependencyTypes :使用ByType类型注入时,如果提前设置了ignoredDependencyTypes(ABC.class),那么其他类中如果仅使用byType的方式注入ABC对象作为属性时是获取不到的。但是Autowired是先byType后byName,所以通过反射调set还是会注入成功的。
ignoreDependencyInterface:现忽略ABC作为属性注入:如果如果工厂提前设置了ignoredDependencyTypes(IgnoreABC.class),那么凡是想通过setABC方法反射注入的方式注入属性都将被忽略,即忽略该接口实现类中存在依赖外部的bean属性注入。也就是当有忽略的接口类,自动装配会忽略这部分类的初始化装配,因为某种情况下,此时的接口实现类不能初始化,列如BeanNameAware,要想装配这个接口的实现对象,可以实现这个接口,通过实现的set方法进行装配。 - 记录ResolvableDependency
要理解该逻辑的原理,先看场景:有个接口InterFaceA,它有2个实现类A1和A2 那么,如果一个类C 依赖了InterFaceA,此时sprig不知道要注入哪个实现类:
解决方案三种
4.1 使用@primary注解 该注解的作用是告诉spring,当遇到这种情况时,优先使用哪个实现类,在你要指定的实现类加上该注解即可。
4.2 使用@Qualifier 注解,明确指定使用哪个实现类
4.3 registerResolvableDependency
beanFactory.registerResolvableDependency(InterFaceA.class,beanFactory.getBean(“a1”)); //意思是,当遇到需要注入InterFaceA.class的地方,优先使用A1的对象,记得,第二个参数是对象 - 添加三个单例Bean
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// Tell the internal bean factory to use the context's class loader etc.
beanFactory.setBeanClassLoader(getClassLoader());
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
// Configure the bean factory with context callbacks.
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
// 如果一个属性对应的set方法在ignoredDependencyInterfaces接口中被定义了,则该属性不会进行自动注入(是Spring中的自动注入,不是@Autowired)
beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
// BeanFactory interface not registered as resolvable type in a plain factory.
// MessageSource registered (and found for autowiring) as a bean.
// 相当于直接把ApplicationContext对象放入Bean工厂中,当getBean(type)时,如果type就是这四个type,则直接返回所设置的实例
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
// Register early post-processor for detecting inner beans as ApplicationListeners.
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
// Detect a LoadTimeWeaver and prepare for weaving, if found.
if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
// Set a temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
// Register default environment beans.
if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
}
if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
}
if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
}
}
BeanFactory准备好了之后,执行BeanFactoryPostProcessor,开始对BeanFactory进行处理
默认情况下:
此时beanFactory的beanDefinitionMap中有6个BeanDefinition,5个基础BeanDefinition+AppConfig的BeanDefinition
而这6个中只有一个BeanFactoryPostProcessor:ConfigurationClassPostProcessor
这里会执行ConfigurationClassPostProcessor进行@Component的扫描,扫描得到BeanDefinition,并注册到beanFactory中
注意:扫描的过程中可能又会扫描出其他的BeanFactoryPostProcessor,那么这些BeanFactoryPostProcessor也得在这一步执行
org.springframework.context.support.AbstractApplicationContext#invokeBeanFactoryPostProcessors
二、BeanDefinition
public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
// 1. 创建BeanFactory
// 2. 生成AnnotatedBeanDefinitionReader
// 3. 生成ClassPathBeanDefinitionScanner
this();
// 利用reader把componentClasses注册为一个BeanDefinition
register(componentClasses);
}
public void register(Class<?>... componentClasses) {
for (Class<?> componentClass : componentClasses) {
registerBean(componentClass);
}
}
public void registerBean(Class<?> beanClass) {
doRegisterBean(beanClass, null, null, null, null);
}
下面方法是注册一个bean最底层的方法,参数很多
beanClass表示bean的类型
name表示bean的名字
qualifiers表示资格限定器,如果某个类上没有写@Lazy注解,但是在调用registerBean方法时传递了Lazy.class,那么则达到了一样的效果
supplier表示实例提供器,如果指定了supplier,那么bean的实例是有这个supplier生成的
customizers表示BeanDefinition自定义器,可以通过customizers对BeanDefinition进行自定义修改
private <T> void doRegisterBean(Class<T> beanClass, @Nullable String name,
@Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier,
@Nullable BeanDefinitionCustomizer[] customizers) {
// 直接生成一个AnnotatedGenericBeanDefinition
AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
// 判断当前abd是否被标注了@Conditional注解,并判断是否符合所指定的条件,如果不符合,则跳过,不进行注册
if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
return;
}
// 设置supplier、scope属性,以及得到beanName
abd.setInstanceSupplier(supplier);
// @Scope注解的元数据信息
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
abd.setScope(scopeMetadata.getScopeName());
String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
// 获取Lazy、Primary、DependsOn、Role、Description注解信息并设置给abd
AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
if (qualifiers != null) {
for (Class<? extends Annotation> qualifier : qualifiers) {
if (Primary.class == qualifier) {
abd.setPrimary(true);
}
else if (Lazy.class == qualifier) {
abd.setLazyInit(true);
}
else {
abd.addQualifier(new AutowireCandidateQualifier(qualifier));
}
}
}
// 使用自定义器修改BeanDefinition
if (customizers != null) {
for (BeanDefinitionCustomizer customizer : customizers) {
customizer.customize(abd);
}
}
// BeanDefinition中是没有beanName的,BeanDefinitionHolder中持有了BeanDefinition,beanName,alias
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
// 解析Scope中的ProxyMode属性,默认为no,不生成代理对象
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
// 注册到registry中
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}
总结
主要讲了在bean真正创建之前的准备工作,涉及到BeanFactory的创建以及BeanFactoryBeanPostProcessor的初始化过程。在执行BeanFactoryBeanPostProcessor的时候同时扫描文件将class文件转成BeanDefinition。
ps:关于spring中bean的创建会在下篇博客中给出具体内容,求大佬们关注啊。
本文地址:https://blog.csdn.net/jiadajing267/article/details/110783506
上一篇: 华为matebookXPro2021是如何修改账户名的?
下一篇: java多线程交替打印
推荐阅读
-
Spring中Bean的生命周期使用解析
-
spring5 源码深度解析----- 被面试官给虐懵了,竟然是因为我不懂@Configuration配置类及@Bean的原理
-
spring源码分析系列5:ApplicationContext的初始化与Bean生命周期
-
spring-boot-2.0.3不一样系列之源码篇 - run方法(三)之createApplicationContext,绝对有值得你看的地方
-
Spring 的 Bean 生命周期,11 张高清流程图及代码,深度解析
-
Spring中bean对象的生命周期
-
谈谈我对Spring Bean 生命周期的理解
-
Spring 框架基础(02):Bean的生命周期,作用域,装配总结
-
spring源码深度解析— IOC 之 开启 bean 的加载
-
bean装载到Spring应用上下文的生命周期