说说Bean的生命周期
bean的生命周期大家可能都知道,我这里主要说说在bean生命周期的各个阶段我们可以做些什么
-
@Bean单例模式下
这里我们定义一个ColorRed类作为简单的bean,在类中增加两个方法,init()作为初始化bean时调用,destroy()作为销毁bean时调用
public class ColorRed { public ColorRed() { System.out.println("===> colorRed bean created..."); } public void init() { System.out.println("===> colorRed bean init..."); } public void destroy() { System.out.println("===> colorRed bean destroy..."); } }
注入IOC容器:在注入时我们指定bean初始化和销毁时调用的方法
@Configuration public class AnnotationContextConfig { // @Scope("prototype") @Bean(initMethod = "init", destroyMethod = "destroy") public ColorRed colorRed() { return new ColorRed(); } }
测试:
public class BeanLifeCycleTest { @Test public void testAnnotationBean() { AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AnnotationContextConfig.class); System.out.println("===> Ioc container created..."); applicationContext.close(); } }
看下结果:我们可以看到单例bean在IOC容器创建的时候就会创建,并且初始化,在容器关闭的时候bean会被销毁
===> colorRed bean created... ===> colorRed bean init... ===> Ioc container created... ===> colorRed bean destroy...
-
@Bean多例模式
在配置文件中将bean上的@Scope(“prototype”)注释打开,由于多例模式下获取bean的时候bean才会被创建,所以测试方法增加如下:
public class BeanLifeCycleTest { @Test public void testAnnotationBean() { AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AnnotationContextConfig.class); System.out.println("===> Ioc container created..."); ColorRed bean1 = applicationContext.getBean(ColorRed.class); ColorRed bean2 = applicationContext.getBean(ColorRed.class); System.out.println(bean1 == bean2); applicationContext.close(); } }
结果:可以看到获取两次bean,调用了两次初始化方法,但是,关闭容器的时候并没有调用我们在@bean里面设置的销毁方法destroyMethod = “destroy”,也就是说多例模式下容器只管创建初始化bean,而不会去销毁bean。
===> Ioc container created... ===> colorRed bean created... ===> colorRed bean init... ===> colorRed bean created... ===> colorRed bean init... false
-
使用接口InitializingBean,DisposableBean,我们新建一个bean,实现这两个接口:
public class ColorGreen implements InitializingBean, DisposableBean { public ColorGreen() { System.out.println("===> colorGreen bean created..."); } @Override public void destroy() throws Exception { System.out.println("===> colorGreen bean destroyed..."); } @Override public void afterPropertiesSet() throws Exception { System.out.println("===> colorGreen bean initializing..."); } }
可以看到InitializingBean有个afterPropertiesSet()方法,在bean创建并且都赋值好后会被调用,DisposableBean有个destroy()方法,在bean销毁的时候会被调用。单例模式下和@Bean注解一样,我们看看多例模式
注册bean:
@Scope("prototype") @Bean public ColorGreen colorGreen() { return new ColorGreen(); }
测试方法:
@Test public void testInterfaceBean() { AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AnnotationContextConfig.class); System.out.println("===> Ioc container created..."); ColorGreen bean = applicationContext.getBean(ColorGreen.class); ColorGreen bean2 = applicationContext.getBean(ColorGreen.class); applicationContext.close(); }
打印结果:不好意思,还是和@bean一样,多例模式下spring只管创建,不管销毁。。。
===> Ioc container created... ===> colorGreen bean created... ===> colorGreen bean initializing... ===> colorGreen bean created... ===> colorGreen bean initializing...
-
使用@PostConstruct和@Predestroy注解,定义bean:
public class ColorBlue { public ColorBlue() { System.out.println("===> colorBlue bean created..."); } @PostConstruct public void init() { System.out.println("===> colorBlue bean initializing..."); } @PreDestroy public void destroy() { System.out.println("===> colorBlue bean destroy...."); } }
配置多例模式
@Bean @Scope("prototype") public ColorBlue colorBlue() { return new ColorBlue(); }
测试:单例模式跟上面所有方式相同,多例模式下貌似也相同:不管销毁。。。
@Test public void testBeanPostPre() { AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AnnotationContextConfig.class); System.out.println("===> Ioc container created..."); ColorBlue bean = applicationContext.getBean(ColorBlue.class); ColorBlue bean2 = applicationContext.getBean(ColorBlue.class); applicationContext.close(); System.out.println("===> Ioc container closed..."); }
-
最后一种:BeanPostProcessor接口,我们看看接口的定义:
public interface BeanPostProcessor { @Nullable default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { return bean; } @Nullable default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { return bean; } }
从两个方法名可以看出,postProcessBeforeInitialization在初始化之前调用,postProcessAfterInitialization在初始化之后调用。大家可以去自行测试一下,这里不再赘述。