IOC中Bean的生命周期

生命周期的各个阶段:

可以分为三个阶段:产生-使用-销毁

又可以分四个阶段:四个阶段  实例化 ->属性注入->初始化 ->销毁

实例化后到使用的初始化过程: 属性赋值 ->处理各种Aware接口->实现BeanPostProcessor的before方法->nitializingBean接口的初始化方法回调->实现BeanPostProcessor的after方法

Bean实例化流程概述:

Spring 容器在进行初始化时,会将 xml 配置的的信息封装成一个  BeanDefinition  对象,所有的
BeanDefinition 存储到一个名为 beanDefinitionMap Map 集合中去, Spring 框架在对该 Map 进行遍 历,使用反射创建Bean 实例对象,创建好的 Bean 对象存储在一个名为 singletonObjects Map 集合 中,当调用getBean 方法时则最终从该 Map 集合中取出 Bean 实例对象返回

扫描配置信息:

        在启动之处,Spring会加载Bean定义 loadBeanDefinitions方法,用xml,注解扫描等各种方式,将定义的所有Bean全部找到,存放到一个BeanDifinitionMap中去。

实例化Bean:

         通过工厂后处理器的接口,实现对Bean的修改或注册

  ApplicaContext通过遍历BeanDifinitionMap来创建对象。

        我们可以在BeanDefinitionMap 填充完毕, Bean 实例化之前,通过实现接口 BeanFactoryPostProcessor:来对实例化的类进行修改或者注册。
        
        
        如下代码所示,我们自己创建类MyBeanFactoryPostPro 实现 BeanFactoryPostProcessor,并且重写了里面的postProcessBeanFactory方法,成功对BeanDifinitionMap中,Key为user,Value为User的map修改为,Key为user,value为Student,实现了对类的修改
public class MyBeanFactoryPostPro implements BeanFactoryPostProcessor {
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {


//                通过ConfigurableListableBeanFactory 的getBeanDefinition方法获取beanDefinition对象,修改beanClassname,完成实例化对象的修改
       
   BeanDefinition    beanDefinition     =               
   configurableListableBeanFactory.getBeanDefinition("user");
        beanDefinition.setBeanClassName("com.apersource.test.Student");

    }
}

同理,我们在如下代码中,通过是实现BeanDefinitionRegistryPostProcessor接口,并且重写了里面的方法,来注册了一个Bean到BeanDifinitionMap中去。

public class MyBeanFactoryPostProcessor2 implements BeanDefinitionRegistryPostProcessor {
    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {

        //进行注册
        RootBeanDefinition definition = new RootBeanDefinition();
        definition.setBeanClassName("com.apersource.test.Student");
        beanDefinitionRegistry.registerBeanDefinition("stu2",definition);
    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {

    }
}

属性注入

通过populateBean方法为Bean内部所需的属性进行赋值填充,这些属性通常为@Autowired注解修饰的这些变量,Spring会通过三级缓存机制来进行属性填充,避免依赖闭环。

        我认为三级缓存的核心思想便是将实例化与属性赋值分开,将不完整的Bean先拿来使用,实现对依赖闭环的突破,再重新对每个Bean对象完成属性赋值(拙见)。

感知实现的Aware接口,并进行处理

 */
public class User implements BeanNameAware, InitializingBean {
    public String name;

    public User() {
        System.out.println("实例化~");
    }

    public void setName(String name) {
        System.out.println("属性赋值");
        this.name = name;
    }

    @Override
    public void setBeanName(String s) {
        System.out.println("各种aware接口的使用");
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("来自接口系统的初始化方法");
    }

    public void doinit(){
        System.out.println("自定义属性的初始化方法");
    }
}

如上代码所演示举例,我们获得一个不完整的Bean之后,对他进行属性赋值,之后首先Spring要处理的就是Aware接口的各种方法,如上实现了 BeanNameAware 接口,我们在其中输出一段语句,获取Bean时便可以清楚的看到执行顺序;

BeanPostProcessor

然后我们开始处理BeanPostProcessor的before和after方法,顾名思义分别在初始化前和初始化之后

public class MyPostProcessor implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("初始化前的后处理器");
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("初始化后的后处理器");
        return bean;
    }
}

初始化的方法:

BeanPostProcessor的before和after方法之间

我们通过实现 InitializingBean 接口,重写里面的 afterPropertiesSet方法,实现了来自接口的初始化方法,在这之后我们如果有自定义的初始化方法并且声明在了配置文件中,会在基于接口的初始化方法之后执行,。

到此为止,一个完整的Bean对象将创建完成了,创建好的Bean对象存储在一个名为singletonObjectsMap集合

然后就是使用和销毁了;

  • 21
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值