• Spring源码解读 - Spring bean 的生命周期


    生产bean 的步骤

    • 实例化前bean后置处理器的注册
    • 实例化
    • 属性赋值
    • 初始化
      • 初始化前执行aware接口
      • 初始化前执行beanPostProcessor前置方法
      • 自定义初始化方法
      • 初始化后执行beanPostProcessor后置方法
    • 销毁
    • 销毁后回调

    实例化前bean后置处理器注册

    • 实例化前, 注册 bean后置处理器到bean工厂,并不执行,也就是一个bean如果实现了BeanPostProcessor接口,会重写其中的两个方法,一个是在初始化之前调用,一个是在初始化之后调用,以此来干涉初始化期间修改bean属性,干涉bean的声明周期。

    在这里插入图片描述

    @Component
    public class MyBeanPostProcessor implements BeanPostProcessor {
    
    	@Override
    	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
    		if (bean instanceof UserComponent) {
    			System.out.println("BeanPostProcessor 开始执行 初始化前..." + beanName);
    			UserComponent userComponent = (UserComponent) bean;
    			userComponent.setUserName("liuzhihang-postProcessBeforeInitialization");
    			return userComponent;
    		}
    		return bean;
    	}
    	@Override
    	public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
    
    		if (bean instanceof UserComponent) {
    			System.out.println("BeanPostProcessor 开始执行 初始化后..." + beanName);
    			UserComponent userComponent = (UserComponent) bean;
    			userComponent.setUserName("liuzhihang-postProcessAfterInitialization");
    			return userComponent;
    		}
    		return bean;
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    实例化 bean

    • 通过反射调用构造方法,进行实例化对象

    属性赋值

    • 这一步,主要解析自动装配,也就是 DI的体现,遍历所有bean,执行bean后置处理器,完成bean的自动装配
    • 自动装配的方式:ByName,ByType,构造器方式
    • 这一步可能出现循环依赖

    自动装配的方式有哪些?

    • ByType
    • ByName
    • 构造器: 通过构造器的参数进而通过byTye方式注入
    • @Autowired

    如何解析 @Autowired注解?

    • 通过反射,获取bean的所有字段,判断字段上是否标注了Awired注解,如果存在这个注解,就可以对当前bean的属性赋值

    初始化流程

    • 属性赋值之后进行初始化,会进入initializeBean方法。在初始化方法中主要执行一下几步骤:
      • 执行实现了Aware接口的方法
      • 执行beanPostProcessor的前置方法
      • 执行自定义初始化方法
      • 执行beanPostProcessor的后置方法
    • 源码
      在这里插入图片描述

    在这里插入图片描述


    初始化之前 - 属性赋值后aware接口回调

    • 如果bean 实现了 xxAware 接口在这个阶段会被调用
      Aware 接口有 :BeanNameAware、BeanClassLoaderAware、BeanFactoryAware接口,其目的也是为了扩展
    @Component
    public class TestBean implements BeanNameAware {
    
        @Override
        public void setBeanName(String s) {
            System.out.println(s);
        }
        
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 源码
      在这里插入图片描述
      在这里插入图片描述

    初始化前 - 执行baen 后置处理器的前置方法

    • 遍历所有的bean后置处理器,然后判断当前bean是否注册了后置处理器,就执行后置处理器的前置方法,这个地方的后置处理器,是在初始化前注册的
    • 在这个地方如果bean 实现了AOP,回去创建动态代理,@PostConstruct 注解会失效,@PostConstruct 在实例化之后执行
    @Component
    public class TestBean implements BeanPostProcessor {
        public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
            return bean;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 源码
      在这里插入图片描述

    初始化

    • 初始化方式有三种
      • @PostConstruct 注解方式
      • 实现 Initalizing 接口
      • @Bean
      • xml 方式

    @PostConstruct 注解方式

    @Component
    public class A1Service{
       @PostConstruct
       public void  init(){
          System.out.println("初始化之后回调。。。");
       }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    实现 InitializingBean 接口

    • 初始化后回调:实现InitializingBean 接口,重写 afterPropestiesSet()
    @Component
    public  class A3Service implements InitializingBean {
       @Override
       public void afterPropertiesSet() throws Exception {
          System.out.println("自定义初始化。。。");
       }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    @Bean 方式

    public class Bean2  {
        public void init(){
            System.out.println("userService 的自定义初始化方法");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    @Configuration

    @ComponentScan
    public class SpringConfig {
        
        @Bean(initMethod = "init")
        public Bean2 getUserServie(){
            return new Bean2();
        }
        
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    xml 方式

    
    
    public class A2Service{
       public void init(){
          System.out.println("自定义初始化。。。"); 
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 源码
      在这里插入图片描述

    • 如果bean 实现了 InitializingBean 接口,就执行重写的方法

    在这里插入图片描述

    初始化后 - 执行bean后置处理器的后置方法

    • 在后置方法里面会执行两种动作:
    • 执行bean后置处理器的后置方法
    • 执行aop

    执行bean后置处理器的后置方法

    • 在实例化前注册到bean工厂后置处理器的bean后置处理器的后置方法,在这个地方执行
    @Component
    public class TestBean implements BeanPostProcessor {
        public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
            return bean;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 源码
      在这里插入图片描述

    销毁

    • 销毁后回调有两种方式
      • 实现DisponseDestory 接口
      • xml 方式
      • @bean 注解方式
  • 相关阅读:
    Android——Theme和Style-由浅入深,全面讲解
    2023高教社杯 国赛数学建模C题思路 - 蔬菜类商品的自动定价与补货决策
    PWN基础:从源文件到可执行文件
    Mysql__安装教程
    VM——“图形收集”显示ROI框及颜色
    Linux基础命令
    32天高效突击:框架+性能优化+微服务+分布式,笔记面试全有
    vue父子组件实现表单双向绑定
    鸿蒙登录页面及页面跳转的设计
    SpringBoot+Vue项目实现高校学生健康打卡系统
  • 原文地址:https://blog.csdn.net/qq_30450563/article/details/126127604