Spring注解驱动第八讲--容器中bean的生命周期
bean的生命周期指的就是bean在容器中的:
创建-->初始化-->销毁;
以上的过程都是由容器来进行管理.
我们可以自定义初始化和销毁方法,的那个进行到当前bean的生命周期的时候,调用我们自己定义的初始化方法和销毁方法.那么自定义初始化和销毁方法有以下四种方式:
1,指定初始化和销毁方法:
在以往使用xml配置文件的时候可以在<bean>标签中加上"init-method"和"destory-method"属性来指定自定义的初始化和销毁方法,本文将不进行详细介绍;
2,使用@Bean注解的initMethod属性和destoryMethod属性来指定初始化方法和销毁方法
创建主配置类
@Configuration public class MyconfigOfLifeCycle { @Bean(initMethod="init",destroyMethod="destory")//指定销毁和初始化方法,初始化方法是在创建对象之后执行,销毁方法是在容器关闭时执行 public Mouse mouse() { return new Mouse() ; } }
创建Mouse的类
public class Mouse { public Mouse() { System.out.println("构造器创建Mouse..........."); } public void init() { System.out.println("初始化Mouse..........."); } public void destory() { System.out.println("销毁Mouse..........."); } }
测试类:
public class IOCTest_lifeCycle { @Test public void test01(){ AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyconfigOfLifeCycle.class); System.out.println("容器创建完成........."); applicationContext.close();//关闭容器,关闭容器时,才会调用destory方法 } }
运行结果:
七月 23, 2019 9:15:52 下午 org.springframework.context.annotation.AnnotationConfigApplicationContext prepareRefresh 信息: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@311d617d: startup date [Tue Jul 23 21:15:52 CST 2019]; root of context hierarchy 构造器创建Mouse........... 初始化Mouse........... 容器创建完成......... 七月 23, 2019 9:15:52 下午 org.springframework.context.annotation.AnnotationConfigApplicationContext doClose 信息: Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@311d617d: startup date [Tue Jul 23 21:15:52 CST 2019]; root of context hierarchy 销毁Mouse...........
可以观察到,容器先去创建bean实体,然后进行初始化方法,当容器销毁时,对象也随之销毁.
注:在多实例的情况下,容器不会去创建bean,只有在调用时才会执行,创建方法和初始化方法,而关闭容器时容器也不会销毁对象实例.
2,将Bean的类实现InitializingBean和DisposableBean接口.
/** * InitializingBean接口中含有afterPropertiesSet方法,即在bean进行创建之后开始执行 * DisposableBean接口中含有destroy方法,即在BeanFatory销毁的时候开始执行销毁方法 * */ @Component//让容器可以扫描到 public class Cat implements InitializingBean,DisposableBean{ public Cat() { System.out.println("创建Cat............"); } public void destroy() throws Exception { System.out.println("初始化Cat............"); } public void afterPropertiesSet() throws Exception { System.out.println("销毁Cat............"); } }
在主配置类中通过@ComponentScan注解扫描包下的bean
再一次执行测试类,运行结果如下:
创建Cat............ 销毁Cat............ 构造器创建Mouse........... 初始化Mouse........... 容器创建完成......... 七月 23, 2019 9:31:27 下午 org.springframework.context.annotation.AnnotationConfigApplicationContext doClose 信息: Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@311d617d: startup date [Tue Jul 23 21:31:26 CST 2019]; root of context hierarchy 销毁Mouse........... 初始化Cat............
细心的读者可以发现,我竟然把吧打印的语句写反了^~^!!!!
3,可以使用JSR250提供的@PostConstruct在bean创建完成并属性值赋值完成后执行;@PreDestory在容器销毁bean之前执行.(两个注解都是加在方法上)
创建bean
@Component public class Dog { public Dog() { System.out.println("Dog创建......."); } @PostConstruct public void init() { System.out.println("Dog初始化.....@PostConstruct.."); } @PreDestroy public void destory() { System.out.println("Dog销毁.....@PreDestroy.."); } }
运行结果:
创建Cat............ 销毁Cat............ Dog创建....... Dog初始化.....@PostConstruct.. 构造器创建Mouse........... 初始化Mouse........... 容器创建完成......... 七月 23, 2019 9:58:30 下午 org.springframework.context.annotation.AnnotationConfigApplicationContext doClose 信息: Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@311d617d: startup date [Tue Jul 23 21:58:30 CST 2019]; root of context hierarchy 销毁Mouse........... Dog销毁.....@PreDestroy.. 初始化Cat............
4,BeanPostProcessor:bean的后置处理器,在bean的初始化前后进行一些处理工作
首先创建自定义的类实现BeanPostProcessor接口
@Component public class MyBeanPostProcessor implements BeanPostProcessor{ /** * 该方法在初始化之前执行 * beanName:初始化当前bean对象的名字, * bean:初始化当前的bean对象 * * 返回的Object为初始化前在该方法中经过处理之后的对象(可原样返回) */ public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { System.out.println("postProcessBeforeInitialization...." +beanName + "=>" + bean); return bean; } /** * 该方法在初始化之后执行 * beanName:初始化当前bean对象的名字, * bean:初始化当前的bean对象 * * 返回的Object为初始化之后在该方法中经过处理之后的对象(可原样返回) */ public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out.println("postProcessAfterInitialization...." +beanName + "=>" + bean); return bean; } }
之后在执行测试类,观察运行结果
创建Cat............ postProcessBeforeInitialization....cat=>com.wxj.bean.Cat@731f8236 初始化Cat............ postProcessAfterInitialization....cat=>com.wxj.bean.Cat@731f8236 Dog创建....... postProcessBeforeInitialization....dog=>com.wxj.bean.Dog@4f9a3314 Dog初始化.....@PostConstruct.. postProcessAfterInitialization....dog=>com.wxj.bean.Dog@4f9a3314 构造器创建Mouse........... postProcessBeforeInitialization....mouse=>com.wxj.bean.Mouse@75f9eccc 初始化Mouse........... postProcessAfterInitialization....mouse=>com.wxj.bean.Mouse@75f9eccc 容器创建完成......... 七月 23, 2019 10:57:35 下午 org.springframework.context.annotation.AnnotationConfigApplicationContext doClose 信息: Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@311d617d: startup date [Tue Jul 23 22:57:35 CST 2019]; root of context hierarchy 销毁Mouse........... Dog销毁.....@PreDestroy.. 销毁Cat............
通过观察结果可以看到,在每个bean初始化之前,都会先执行postProcessBeforeInitialization方法,而在初始化完成之后,会执行postProcessAfterInitialization方法.
注意:如果后置器处理中返回的为null,那么容器不会把使用@Bean注解的bean,加载到容器中