SpringBean生命周期

SpringBean生命周期(~)

BeanDefinition的相关知识

Bean和BeanDefinition的关系
BeanDefinition就是Bean的一个元数据 由BeanDefinition得到的Bean
BeanDefinition是Bean在spring中的定义形态

BeanDefinition 存放到 BeanDefinitionMap的过程
在启动后 通过调用 Refresh方法,得到BeanDefinition对象,
然后通过调用refresh()方法中的invokeBeanFactoryPostProcessors(beanFactory)方法;通过拿到BeanFactory的后置处理器
拿到BeanFactory,然后通过实现BeanDefinitionRegistry中的registerBeanDefinition方法将BeanDefinition通过点put到BeanDefinitionMap中
原视频链接
源码

BeanDefinition 存放到 BeanDefinitionMap的过程 源码解析
    public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
        Set<String> processedBeans = new HashSet();
        ArrayList regularPostProcessors;
        ArrayList registryProcessors;
        int var9;
        ArrayList currentRegistryProcessors;
        String[] postProcessorNames;
        if (beanFactory instanceof BeanDefinitionRegistry) {
            /**将beanFactory强转成BeanDefinitionRegistry*/
            BeanDefinitionRegistry registry = (BeanDefinitionRegistry)beanFactory;
            regularPostProcessors = new ArrayList();
            registryProcessors = new ArrayList();
            Iterator var6 = beanFactoryPostProcessors.iterator();

            while(var6.hasNext()) {
                BeanFactoryPostProcessor postProcessor = (BeanFactoryPostProcessor)var6.next();
                if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
                    BeanDefinitionRegistryPostProcessor registryProcessor = (BeanDefinitionRegistryPostProcessor)postProcessor;
                    /**通过这个方法去调用里面的registry方法去调用BeanDefinitionRegistry接口中的registerBeanDefinition方法*/
registryProcessor.postProcessBeanDefinitionRegistry(registry);
                    registryProcessors.add(registryProcessor);
                } else {
                    regularPostProcessors.add(postProcessor);
                }
            }
    }

简述:

实例化(instantiateBean) —— 属性赋值(populateBean)—— 初始化(init) —— 销毁(destroy)

详细:

创建bean

如何扫描创建bean的?

  1. run()
  2. refreshContext()
  3. refresh()
  4. preInstantiateSingletons() 也就是bean对象的一个提前初始化
  5. doGetBean()
  6. createBean()

  1. 通过xml/注解@(Bean)。。等等方式注册bean
    他们都是在spring的 **application中的refresh方法**中用loadBeanDefinitions进行加载
//SpringApplication下的
import org.springframework.boot.SpringApplication; 
SpringApplication类中 refresh方法
protected void refresh(ConfigurableApplicationContext applicationContext) {
        applicationContext.refresh();
    }
底层调用的是 public abstract class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext {} 中的refresh方法
  1. 通过BeanDefinitionRegistry里面的BeanFactory和Registry进行后置处理
    获得一个SpringBean的一个BeanDefinition对象
    (有两个关键的属性:BeanName和BeanType
  2. 进行提前初始化调用getBean()方法

实例化(instantiateBean)

传入一个BeanName 通过 beanname去找到Bean对应的BeanType,通过反射 返回一个Object对象——也就是bean对象

BeanPostProcessors 代理 的注册功能,方便后期bean的一个拓展 (他是一个拓展点)

// Give BeanPostProcessors a chance to neturn a proxy instead of the target bean instance.
给BeanPostProcessors一个机会,将代理替换为目标bean实例。
			Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
			if (bean != null) {
				return bean;
			}

// 拓展点,如何替换之前的bean?

  1. 通过BeanDefinitionRegistry

    我们通过拿到BeanDefinitionRegistry对象,然后remove掉之前的bean的BeanDefinition对象,然后去注册我们自己的一个实现类的BeanDefinition
    
  2. 通过PostProcessors

通过PostProcessors判断是不是我们的beanname,然后return一个代理类

属性赋值 populateBean

  • set
  • construct
  • @Resource autowireByName
  • @AutoWire autowireByType
    • 如果通过@AutoWire注入的时候有两个想同类型的bean,我们就要结合@Qualifier("BeanName")注入想要的bean
  • 三级缓存解决循环依赖的问题
    • 有aop的前提。

初始化(initializeBean)

调用三个aware方法

  • BeanNameAware
  • BeanFactoryAware
  • ApplicationContextAware

BeanPostProcessor处理(拓展点)

而该接口下有两个方法
一个是前置处理postProcessBeforeInitialization
一个是后置处理postProcessAfterInitialization

里面的Init-Method (去实现相关接口)

其中 InitializingBeanj接口就是属于InitMethod

销毁(destroy)

与初始化相似

实现DisposableBean接口

调用destroy-method方法 (去实现相关接口)

注:

其中很多中间件框架的一些代码实现都是在实现InitializingBeanDisposableBean两个接口的时候进行

Bean生命周期

详细可以看这篇文章:spring生命周期详解
spring源码讲解

SpringBean的生命周期详解

  1. 进入到刷新的refresh方法

----------------------以下过程都是在finishBeanFactoryInitialization()方法中的preInstantiateSingletons()方法中进行------------------------------

  1. finishBeanFactoryInitialization(),完成bean工厂的初始化,初始化所有非懒加载bean

** 实例化 **

  1. preInstantiateSingletons(),实例化所有单例bean
  2. getBean()---->doGetBean(),判断该对象是否有初始化过,如果没有,就注入到IOC容器中
  3. 会使用BeanDifinition的isSingleton()方法对BeanDefinition进行判断,如果对象是单例情况下,调用createBean()
  4. resolveBeforeInstantiation()的applyBeanPostProcessorsBeforeInstantiation(),在实例化对象之前做增强
  5. 通过调用 doCreateBean() 里面的 createBeanInstance() 方法,利用反射实例化对象,拿到Bean的一个实例 BeanInstance
  6. createBeanInstance(),

** 属性赋值 **

  1. populateBean()的ibp.postProcessAfterInstantiation(),在实例化对象之后做增强
  2. populateBean()的applyPropertyValue()给对象的set方法赋值,autowireByName,autowireByType 属性赋值

** 初始化 **

  1. 执行doCreateBean()的 / initializeBean() /
  2. initializeBean()的invokeAwareMethods(),判断bean是否实现Aware的相关接口,如果实现了,则执行回调
  3. initializeBean()的applyBeanPostProcessorsBeforeInitialization(),需实现BeanPostProcessor接口,对初始化方法的前置增强
  4. invokeAwareInterfaces()检查是否实现ApplicationContextAware接口,如果有则回调bean的setApplicationContext()
  5. initializeBean()的invokeInitMethods()执行bean的初始化方法afterPropertiesSet(),需要实现InitializingBean接口。类似地,如果bean使用init-method声明了初始化方法,该方法也会被调用
  6. initializeBean()的applyBeanPostProcessorsAfterInitialization(),需实现BeanPostProcessor接口,对初始化方法的后置增强

** 销毁 **
17. bean已经准备就绪,可以被应用程序使用了,它们将一直驻留在应用上下文中,直到该应用上下文被销毁
18. 如果bean实现了DisposableBean接口,Spring将调用它的destroy()接口方法。同样,如果bean使用destroy-method声明了销毁方法,该方法也会被调用

obtainFreshBeanFactory() 方法总结

里面就调用了registerBeanDefinitions方法

  • 该方法会解析所有 spring 配置文件(通常我们会放在 resources 目录下),将所有 配置文件中的 bean 定义封装成 BeanDefinition,加载到 BeanFactory 中
  • 常见的,如果解析到 <context:component-scan base-package="" /> 注解时,会扫描 base-package 指定的目录,将该目录下使用指定注解(@Controller、@Service、@Component、@Repository)的bean 定义也同样封装成 BeanDefinition,加载到 BeanFactory 中
    原文链接
posted @ 2023-02-08 21:37  没有烦恼的猫猫  阅读(53)  评论(0编辑  收藏  举报