欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

【源码Spring系列】——Bean的生命周期(上)

程序员文章站 2022-06-24 19:09:22
文章目录前言一、BeanFactory1.创建BeanFactory2.准备BeanFactory二、BeanDefinition总结前言本文主要是从源码的角度讲解Spring中bean的生命周期,主要讲解bean完整的初始化过程,文中不包含bean的销毁过程。下图绘制为bean在spring启动过程涉及到关键节点。以后的讲解主要围绕下图的流程展开。//样例代码public static void main(String[] args) {AnnotationConfigApplicat...


前言

本文主要是从源码的角度讲解Spring中bean的生命周期,主要讲解bean完整的初始化过程,文中不包含bean的销毁过程。下图绘制为bean在spring启动过程涉及到关键节点。以后的讲解主要围绕下图的流程展开。
【源码Spring系列】——Bean的生命周期(上)

//样例代码
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的创建会在下篇博客中给出具体内容,求大佬们关注啊。

本文地址:https://blog.csdn.net/jiadajing267/article/details/110783506