zoukankan      html  css  js  c++  java
  • spring中的bean的生命周期

    bean的生命周期:bean的创建 —— 初始化 ——销毁的过程

    容器管理bean的生命周期,我们可以自定义初始化和销毁方法,容器在bean进行到当前生命周期就会调用我们的方法

    在xml配置文件中是在bean的标签内使用init-methoddestroy-method

    <bean id="person" class="com.springbean.Person" init-method="" destroy-method="" >

    这里我们使用注解的方法

    第一种指定初始化和销毁方法

    首先创建一个bean

    public class Foo {
    
        public Foo(){
            System.out.println("bean的创建");
        }
    
        public void init(){
            System.out.println("bean的初始化");
        }
    
        public void destroy(){
            System.out.println("bean的销毁");
        }
    } 

    创建一个配置类:

    @Bean注解上指定初始化和销毁方法
    @Configuration
    public class MainBeanConfig  {
    @Bean(initMethod = "init",destroyMethod = "destroy")
    public Foo foo(){
      
    return new Foo();
    }
    }

    测试:

    public class BeanTest {
    
        @Test
        public void  test(){
            ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainBeanConfig.class);
        }
    }

    bean如果没有指定作用域,就是单例的,就在容器加载的时候就会创建bean,所以打印的结果是:

    bean的创建
    bean的初始化

    销毁:当容器关闭的时候,就会调用destroy方法,打印 bean的销毁

    applicationContext.close();

    如果要指定bean的作用域为prototype,就需要在配置类中MainBeanConfig,加上注解@Scope("prototype"),如

    @Bean
    @Scope("prototype")
    public Foo foo(){
    return new Foo();
    }
    指定bean的作用域为@Scope("prototype"),这时候容器加载的时候就不会创建和初始化bean,而是在获取bean的时候。

    容器关闭的时候也不会去调用destroy方法,需要自己手动调用。


    第二种我们通过bean实现InitializingBean(定义初始化逻辑)和DisposableBean(定义销毁逻辑)

    创建一个类Hero,实现InitializingBean,DisposableBean接口,加上注解@Component

    @Component
    public
    class Hero implements InitializingBean,DisposableBean { public Hero(){ System.out.println("创建"); } @Override public void destroy() throws Exception { System.out.println("销毁"); } @Override public void afterPropertiesSet() throws Exception { System.out.println("初始化"); } }

    在配置中加上注解ComponentScan去扫描包,也可以使用@Import来将组件加入容器中

    如:@Import({Hero.class})

    @ComponentScan("com.springbean")
    public class MainBeanConfig {

     测试:

     @Test
        public void  test(){
            AnnotationConfigApplicationContext  applicationContext = new AnnotationConfigApplicationContext(MainBeanConfig.class);
            applicationContext.close();
        }

    打印结果:

    创建
    初始化
    销毁

    第三种使用@PostConstruct(构造器创建之后)和@PreDestroy(容器销毁之前)两个注解,这是JSR250的两个注解。

      @PostConstruct
        public void init(){
            System.out.println("bean的初始化");
        }
    
        @PreDestroy
        public void destroy(){
            System.out.println("bean的销毁");
        }

    第四种使用BeanPostProcessor后置处理器,这个接口中有两个方法postProcessBeforeInitialization和postProcessAfterInitialization:

    public interface BeanPostProcessor {
        Object postProcessBeforeInitialization(Object var1, String var2) throws BeansException;
    
        Object postProcessAfterInitialization(Object var1, String var2) throws BeansException;
    }
    

     分别在bean初始化之前执行这个方法,这个类似aop里面的前后通知,写一个实现类MyBeanPostProcesser

    /**
     *后置处理器,处理前后初始化的工作
     */
    @Component
    public class MyBeanPostProcesser implements BeanPostProcessor {
        @Override
        public Object postProcessBeforeInitialization(Object o, String s) throws BeansException {
            System.out.println(" postProcessBeforeInitialization ...beanname="+s+",bean="+o);
            return o;
        }
    
        @Override
        public Object postProcessAfterInitialization(Object o, String s) throws BeansException {
            System.out.println("postProcessAfterInitialization.... beanname="+s+",bean="+o);
            return o;
        }
    }

    加入到配置类中MainBeanConfig

    
    
    @Configuration
    @Import({Hero.class, MyBeanPostProcesser.class})
    public class MainBeanConfig {
    测试:输出结果,是在bean的初始化的前后操作
     postProcessBeforeInitialization ...beanname=com.springbean.Hero,bean=com.springbean.Hero@4ba2ca36
    初始化
    postProcessAfterInitialization.... beanname=com.springbean.Hero,bean=com.springbean.Hero@4ba2ca36
  • 相关阅读:
    PHP调用WCF提供的方法
    关于git报 warning: LF will be replaced by CRLF in README.md.的警告的解决办法
    vue中引入mui报Uncaught TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them的错误
    微信小程序报Cannot read property 'setData' of undefined的错误
    Vue那些事儿之用visual stuido code编写vue报的错误Elements in iteration expect to have 'v-bind:key' directives.
    关于xampp中无法启动mysql,Attempting to start MySQL service...的解决办法!!
    PHP的环境搭建
    新手PHP连接MySQL数据库出问题(Warning: mysqli_connect(): (HY000/1045): Access denied for user 'root'@'localhost' (using password: YES))
    手机号码、获得当前时间,下拉框,填写限制
    团队作业(五):冲刺总结
  • 原文地址:https://www.cnblogs.com/tdyang/p/11875454.html
Copyright © 2011-2022 走看看