【源码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

  1. 设置BeanFactory的类加载器、表达式解析器、类型转化注册器
  2. 添加三个BeanPostProcessor,注意是具体的BeanPostProcessor实例对象
  3. 记录ignoreDependencyInterface
    spring中属性注入默认是通过反射调用setXxx实现的
    ignoredDependencyTypes :使用ByType类型注入时,如果提前设置了ignoredDependencyTypes(ABC.class),那么其他类中如果仅使用byType的方式注入ABC对象作为属性时是获取不到的。但是Autowired是先byType后byName,所以通过反射调set还是会注入成功的。
    ignoreDependencyInterface:现忽略ABC作为属性注入:如果如果工厂提前设置了ignoredDependencyTypes(IgnoreABC.class),那么凡是想通过setABC方法反射注入的方式注入属性都将被忽略,即忽略该接口实现类中存在依赖外部的bean属性注入。也就是当有忽略的接口类,自动装配会忽略这部分类的初始化装配,因为某种情况下,此时的接口实现类不能初始化,列如BeanNameAware,要想装配这个接口的实现对象,可以实现这个接口,通过实现的set方法进行装配。
  4. 记录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的对象,记得,第二个参数是对象
  5. 添加三个单例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的创建会在下篇博客中给出具体内容,求大佬们关注啊。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mandy_i

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值