Bean的生命周期

Spring Bean的生命周期是从 Bean 实例化之后,即通过反射创建出对象之后,到Bean成为一个完整对象,最终存储到单例池中,这个过程被称为Spring Bean的生命周期。

一,实例化

1.1Bean工厂后处理器 – BeanFactoryPostProcessor

BeanFactoryPostProcessor是一个接口规范,实现了该接口的类只要交由Spring容器管理的话,那么 Spring就会回调该接口的方法,用于对BeanDefinition注册修改的功能。

1.1.1修改Bean

修改已经经过加载xml配置文件,解析获取配置中的每个的信息,封装成一个个的BeanDefinition对象====》存储在名为beanDefinitionMapMap<String,BeanDefinition>中。

public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {@Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        System.out.println("MyBeanFactoryPostProcessor的postProcessBeanFactory");
        BeanDefinition beanDefinition=beanFactory.getBeanDefinition("user");
        beanDefinition.setBeanClassName("com.apesource.pojo.Student");}
}

applicationcontext.xml中的内容。

<bean class="com.apesource.pojo.User" id="user">
</bean>
<bean class="com.apesource.processor.MyBeanFactoryPostProcessor"></bean>

//运行结果 

MyBeanFactoryPostProcessor的postProcessBeanFactory
com.apesource.pojo.Student@1ed4004b

//结果分析

注册的是user的bean,但是经过BeanFactoryPostProcessor重新将BeanclassName修改过后,变成了student的bean。

1.1.2 注册一个Bean的方法一

如何利用BeanFactoryPostProcessor注册一个Bean

//注册演示
        BeanDefinition beanDefinition1 = new RootBeanDefinition();
        beanDefinition1.setBeanClassName("com.apesource.pojo.Student");
//强转成DefaultListableBeanFactory
        DefaultListableBeanFactory defaultListableBeanFactory =              (DefaultListableBeanFactory) beanFactory;
        defaultListableBeanFactory.registerBeanDefinition("stu2",beanDefinition1);

在xml中并没有注册stu2,但是在getBean的时候,可以得到student的实体类对象

1.1.3 注册一个Bean的方法二 

Bean工厂后处理器 – BeanDefinitionRegistryPostProcessor 

Bean工厂后处理器 – BeanDefinitionRegistryPostProcessorSpring 提供了一个BeanFactoryPostProcessor的子接口BeanDefinitionRegistryPostProcessor专门用于注册BeanDefinition操作。
public class MyBeanFactoryPostProcessor2 implements
BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory
configurableListableBeanFactory) throws BeansException {}
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry
beanDefinitionRegistry) throws BeansException {
BeanDefinition beanDefinition = new RootBeanDefinition();
beanDefinition.setBeanClassName("com.apesource.pojo.Student");
beanDefinitionRegistry.registerBeanDefinition("stu",beanDefinition);
}
}

Bean被实例化后,会经过初始化

二,初始化

2.1BeanPostProcessor(Bean后处理)

BeanPostProcessor,是Bean后处理。
//1.自定义MyBeanPostProcessor
public class MyBeanPostProcessor implements BeanPostProcessor {
/* 参数: bean是当前被实例化的Bean,beanName是当前Bean实例在容器中的名称
返回值:当前Bean实例对象 */
public Object postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException {
System.out.println("BeanPostProcessor的before方法...");
return bean;
}
/* 参数: bean是当前被实例化的Bean,beanName是当前Bean实例在容器中的名称
返回值:当前Bean实例对象 */
public Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException {
System.out.println("BeanPostProcessor的after方法...");
return bean;
}
}
//2.注入配置MyBeanPostProcessor
<bean class="com.apesource.processors.MyBeanPostProcessor"></bean>
//3.测试控制台打印结果如下
User创建了...
BeanPostProcessor的before方法...
User属性填充...
User初始化方法执行...
BeanPostProcessor的after方法...
com.apesource.pojo.User@56ac3a89

2.2属性初始化

2.2.1解决双向对象冲突(三级缓存)

//1、最终存储单例Bean成品的容器,即实例化和初始化都完成的Bean,称之为"一级缓存"
Map<String, Object> singletonObjects = new ConcurrentHashMap(256);
//2、早期Bean单例池,缓存半成品对象,且当前对象已经被其他对象引用了,称之为"二级缓存"
Map<String, Object> earlySingletonObjects = new ConcurrentHashMap(16);
//3、单例Bean的工厂池,缓存半成品对象,对象未被引用,使用时在通过工厂创建Bean,称之为"三级缓存"。
Map<String, ObjectFactory<?>> singletonFactories = new HashMap(16);
  1. UserService 实例化对象,但尚未初始化,将UserService存储到三级缓存;
  2. UserService 属性注入,需要UserDao,从缓存中获取,没有UserDao
  3. UserDao实例化对象,但尚未初始化,将UserDao存储到到三级缓存;
4.将出现矛盾的两个Bean,其中一个Bean(UserDao)要走另一条路径,完成自己的初始化。从三级缓存到二级,最终到一级缓存,供UserService调用。
最终缓存到名为singletonObjects单例池。

三,调用

getBean方法可以获取到serviceBean。getBean最终得到的都是完整的Bean

四,销毁 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值