Bean 实例化
Spring容器在进行初始化时,会将xml配置的的信息封装成一个BeanDefinition对象,所有的BeanDefinition存储到一个名为beanDefinitionMap的Map集合中去,Spring框架在对该Map进行遍历,使用反射创建Bean实例对象,创建好的Bean对象存储在一个名为singletonObjects的Map集合中,当调用getBean方法时则最终从该Map集合中取出Bean实例对象返回。
Bean 实例化的基本流程
- 加载xml配置文件,解析获取配置中的每个的信息,封装成一个个的BeanDefinition对象;
- 将BeanDefinition存储在一个名为beanDefinitionMap的Map<String,BeanDefinition>中;
- ApplicationContext底层遍历beanDefinitionMap,创建Bean实例对象;
- 创建好的Bean实例对象,被存储到一个名为singletonObjects的Map<String,Object>中;
- 当执行applicationContext.getBean(beanName)时,从singletonObjects去匹配Bean实例返回
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 注入bean-->
<bean class="com.apesource.bean.Student" id="student"></bean>
<bean class="com.apesource.bean.User" id="user"></bean>
</beans>
Spring Bean的生命周期是指从 Bean 实例化之后(通过反射创建出对象之后),到Bean成为一个完整对象,最终存储到单例池中,这个过程被称为Spring Bean的生命周期。Spring Bean的生命周期大体上分为三个阶段:
- Bean的实例化阶段:Spring框架会取出BeanDefinition的信息进行判断当前Bean的范围是否是singleton的, 是否不是延迟加载的,是否不是FactoryBean等,最终将一个普通的singleton的Bean通过反射进行实例化;
- Bean的初始化阶段:Bean创建之后还仅仅是个"半成品",还需要对Bean实例的属性进行填充、执行一些Aware 接口方法、执行BeanPostProcessor方法、执行InitializingBean接口的初始化方法、执行自定义初始化init方法等。该阶段是Spring最具技术含量和复杂度的阶段;
- Bean的完成阶段:经过初始化阶段,Bean就成为了一个完整的Spring Bean,被存储到单例池singletonObjects中去了,即完成了Spring Bean的整个生命周期。
Spring Bean的初始化
Spring Bean的初始化过程涉及如下几个过程:
- Bean实例的属性填充
- BeanPostProcessor的before()方法回调
- 自定义初始化方法init回调
- InitializingBean接口的初始化方法回调
- BeanPostProcessor的after()方法回调
- Aware接口属性注入
springBean的销毁
通过requiresDestruction()判断该Bean是否需要销毁,对需要销毁的Bean通过适配器模式生成DisposableBeanAdapter对象,最后调用registerDisposableBean()将DisposableBeanAdapter对象放入disposableBeans缓存中,当Spring容器关闭的时候,可以直接从该缓存中取出销毁调用,调用它们的销毁方法。
- 自定义的销毁方法回调
- DisposableBean接口的销毁方法
举例:
bean:
public class User implements InitializingBean, DisposableBean, BeanFactoryAware, BeanNameAware, ApplicationContextAware {
private String name;
public User() {
System.out.println("user创建了 实例化完结");
}
// 属性赋值
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
'}';
}
// 初始化方法1(自定义的)
public void initDo(){
System.out.println("自定义的初始化");
}
// 初始化(系统)
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("系统初始化");
}
// 销毁方法(系统)
@Override
public void destroy() throws Exception {
System.out.println("系统销毁");
}
// 销毁
public void doDefout(){
System.out.println("自定义销毁");
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println("beanFactory: "+beanFactory+"实现BeanFactoryAware接口");
}
@Override
public void setBeanName(String s) {
System.out.println("BeanName: "+s+"实现BeanNameAware接口");
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.println("applicationContext: "+applicationContext+"实现ApplicationContextAware接口");
}
}
applocationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 注入bean-->
<!-- <bean class="com.apesource.bean.Student" id="student"></bean>-->
<!-- 自定义的初始方法: init-method="initDo" 销毁方法 destroy-method="doDefout"-->
<bean class="com.apesource.bean.User" id="user" init-method="initDo" destroy-method="doDefout">
<property name="name" value="王五"></property>
</bean>
<!-- //bean工厂的后处理器
// 方式一BeanFactoryPostProcessor-->
<!-- <bean class="com.apesource.FactoryBean.StudentFactory" id="factory"></bean>-->
<!--//bean工厂的后处理器
<!- 方式二BeanDefinitionRegistryPostProcessor是BeanFactoryPostProcessor的子类-->
<bean class="com.apesource.FactoryBean.StidentFactory2" id="factory"></bean>
<!-- bean的后处理器 -->
<bean class="com.apesource.FactoryBean.StudentBeanPostProcessor" id="beanPostProcessor"></bean>
</beans>
Bean的后置处理器:
//BeanPostProcessor又叫Bean的后置处理器,是Spring框架中IOC容器提供的一个扩展接口,在Bean初始化的前后进行一些处理工作。
public class StudentBeanPostProcessor implements BeanPostProcessor {
// bean实例化之前
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("postProcessBeforeInitialization的bean实例化之前");
return bean;
}
//bean 实例化之后
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("postProcessAfterInitialization的bean 实例化之后");
return bean;
}
}
bean工厂的后处理器:
// 方式一BeanFactoryPostProcessor
public class StudentFactory implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("BeanFactoryPostProcessor的工厂");
// 修改创建的类
// BeanDefinition student = beanFactory.getBeanDefinition("student");
// student.setBeanClassName("com.apesource.bean.User");
// 注册其他类
BeanDefinition beanDefinition = new RootBeanDefinition();
beanDefinition.setBeanClassName("com.apesource.bean.User");
// 强转
DefaultListableBeanFactory beanFactory1 = (DefaultListableBeanFactory) beanFactory;
beanFactory1.registerBeanDefinition("user",beanDefinition);
}
}
// 方式二BeanDefinitionRegistryPostProcessor是BeanFactoryPostProcessor的子类
public class StidentFactory2 implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {
// 注册其他类
// BeanDefinition beanDefinition = new RootBeanDefinition();
// beanDefinition.setBeanClassName("com.apesource.bean.Student");
// beanDefinitionRegistry.registerBeanDefinition("student",beanDefinition);
System.out.println("BeanDefinitionRegistryPostProcessor是BeanFactoryPostProcessor的子类创建bean的工厂后处理器");
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
}
}
测试:
public class Test01 {
public static void main(String[] args) {
ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("applocationContext.xml");
User user = (User) classPathXmlApplicationContext.getBean("user");
System.out.println("业务操作"+"将获取到的user对象进行打印:"+user);
classPathXmlApplicationContext.close();
}
}
结果: