文章目录
一、Bean的生命周期之五步
Bean的生命周期按照粗略的五步的话:
- 第一步:实例化Bean(调用无参数构造方法)
- 第二步:Bean属性赋值(调用set方法)
- 第三步:初始化Bean(调用Bean的init方法,需要自己写自己配)
- 第四步:使用Bean
- 第五步:销毁Bean(调用Bean的destory方法,需要自己写自己配
需要手动关闭spring容器
//销毁Bean 必须手动关闭Spring容器
ClassPathXmlApplicationContext context = (ClassPathXmlApplicationContext) applicationContext;
context.close();
需要手动指定初始化方法和销毁方法
init-method="initBean" destroy-method="destroyBean"
1、准备User类
无参构造 name属性以及set方法
public class User {
private String name;
public void setName(String name) {
System.out.println("第二步:给对象的属性赋值。");
this.name = name;
}
public User() {
System.out.println("第一步:无参数构造方法执行。");
}
public void initBean(){
System.out.println("第三步:初始化Bean。");
}
public void destroyBean(){
System.out.println("第五步:销毁Bean。");
}
}
2、spring配置文件
<?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 id="user" class="com.bjpowernode.spring.bean.User"
init-method="initBean" destroy-method="destroyBean">
<property name="name" value="小白"></property>
</bean>
</beans>
3、测试类
@Test
public void testBeanLifeCircle(){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
User user = applicationContext.getBean("user", User.class);
System.out.println("第四步:使用Bean:"+user);
//销毁Bean 必须手动关闭Spring容器
ClassPathXmlApplicationContext context = (ClassPathXmlApplicationContext) applicationContext;
context.close();
}
4、运行结果
二、Bean的生命周期之七步
在以上的五步中,第三步是初始化Bean,如果还想在初始化前和初始化后添加代码,可以加入”Bean后处理器“ ----”BeanPostProcessor“
Bean生命周期七步:
- 第一步:实例化Bean(调用无参数构造方法)
- 第二步:Bean属性赋值(调用set方法)
- 第三步:执行”Bean后处理器“的before方法
- 第四步:初始化Bean(调用Bean的init方法,需要自己写自己配)
- 第五步:执行”Bean后处理器“的after方法
- 第六步:使用Bean
- 第七步:销毁Bean(调用Bean的destory方法,需要自己写自己配)
1、实现BeanPostProcessor类
编写一个类实现BeanPostProcessor类,并且重写before和after方法:
出现return 报错的现象可能是jdk版本太低 改为1.8即可
public class LogBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("第三步:执行”Bean后处理器“的before方法");
return BeanPostProcessor.super.postProcessBeforeInitialization(bean, beanName);
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("第五步:执行”Bean后处理器“的after方法");
return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
}
}
2、配置文件
需要在配置文件中进行配置
注意:这个Bean后处理器将作用于整个配置文件中所有的Bean
<bean class="com.bjpowernode.spring.bean.LogBeanPostProcessor"></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 class="com.bjpowernode.spring.bean.LogBeanPostProcessor"></bean>
<bean id="user" class="com.bjpowernode.spring.bean.User"
init-method="initBean" destroy-method="destroyBean">
<property name="name" value="小白"></property>
</bean>
</beans>
3、运行结果:
三、Bean的生命周期之十步
比七步添加的三步在哪里?
- 在”Bean后处理器“before方法之前(检查Bean是否实现了Aware的相关接口,并设置相关依赖)
- 在”Bean后处理器“before方法之后(检查Bean是否实现了InitializingBean接口,并调用接口方法)
- 销毁Bean之前或使用Bean之后(检查Bean是否实现了DisposableBean接口,并调用接口方法)
添加的这三步的特点:都是在检查这个Bean是否实现了某些特定的接口,如果实现了这些接口,则spring容器会调用这些接口中的方法
1、点位1
实现BeanNameAware, BeanClassLoaderAware, BeanFactoryAware 接口
public class User implements BeanNameAware, BeanClassLoaderAware, BeanFactoryAware {
private String name;
public void setName(String name) {
System.out.println("第二步:给对象的属性赋值。");
this.name = name;
}
public User() {
System.out.println("第一步:无参数构造方法执行。");
}
public void initBean(){
System.out.println("第四步:初始化Bean。");
}
public void destroyBean(){
System.out.println("第七步:销毁Bean。");
}
@Override
public void setBeanClassLoader(ClassLoader classLoader) {
System.out.println("Bean这个类的加载器:"+classLoader);
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println("生产这个Bean的工厂对象是:"+beanFactory);
}
@Override
public void setBeanName(String name) {
System.out.println("这个Bean的名字是:"+name);
}
}
2、点位2
实现InitializingBean接口
public class User implements BeanNameAware, BeanClassLoaderAware, BeanFactoryAware, InitializingBean {
public void setName(String name) {
System.out.println("第二步:给对象的属性赋值。");
}
public User() {
System.out.println("第一步:无参数构造方法执行。");
}
public void initBean(){
System.out.println("第四步:初始化Bean。");
}
public void destroyBean(){
System.out.println("第七步:销毁Bean。");
}
@Override
public void setBeanClassLoader(ClassLoader classLoader) {
System.out.println("Bean这个类的加载器:"+classLoader);
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println("生产这个Bean的工厂对象是:"+beanFactory);
}
@Override
public void setBeanName(String name) {
System.out.println("这个Bean的名字是:"+name);
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("InitializingBean's afterPropertiesSet执行。");
}
}
3、点位3
实现DisposableBean接口
public class User implements BeanNameAware, BeanClassLoaderAware, BeanFactoryAware, InitializingBean,DisposableBean {
public void setName(String name) {
System.out.println("第二步:给对象的属性赋值。");
}
public User() {
System.out.println("第一步:无参数构造方法执行。");
}
public void initBean(){
System.out.println("第四步:初始化Bean。");
}
public void destroyBean(){
System.out.println("第七步:销毁Bean。");
}
@Override
public void setBeanClassLoader(ClassLoader classLoader) {
System.out.println("Bean这个类的加载器:"+classLoader);
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println("生产这个Bean的工厂对象是:"+beanFactory);
}
@Override
public void setBeanName(String name) {
System.out.println("这个Bean的名字是:"+name);
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("InitializingBean's afterPropertiesSet执行。");
}
@Override
public void destroy() throws Exception {
System.out.println("DisposableBean's destroy执行");
}
}
四、Bean的作用域
- spring容器只对singleton的Bean进行完整的生命周期管理
- 如果是prototype作用域,Spring容器只负责将该Bean初始化完毕,等客户端一旦获取到该Bean之后,Spring容器就不再管理该对象的生命周期了(生出来就不管了)
测试:
在配置文件中加入
scope=“prototype”
客户端获取之后,就不再继续管之后的生命周期了