小枫叶
一,实例化
1.1Bean工厂后处理器 – BeanFactoryPostProcessor

1.1.1修改Bean
修改已经经过加载xml配置文件,解析获取配置中的每个的信息,封装成一个个的BeanDefinition对象====》存储在名为beanDefinitionMap的Map<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 工厂后处理器 – BeanDefinitionRegistryPostProcessor Spring 提供了一个 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后处理)
//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 );
- UserService 实例化对象,但尚未初始化,将UserService存储到三级缓存;
- UserService 属性注入,需要UserDao,从缓存中获取,没有UserDao;
- UserDao实例化对象,但尚未初始化,将UserDao存储到到三级缓存;
4.将出现矛盾的两个Bean,其中一个Bean(UserDao)要走另一条路径,完成自己的初始化。 从三级缓存到二级,最终到一级缓存, 供UserService调用。最终缓存到名为singletonObjects 单例池。
三,调用
getBean方法可以获取到serviceBean。getBean最终得到的都是完整的Bean