spring注解开发——说说bean的生命周期

说说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在初始化之后调用。大家可以去自行测试一下,这里不再赘述。

猜你喜欢

转载自blog.csdn.net/chenshufeng115/article/details/100084695