Spring注解开发4 --- Bean的生命周期

目录

一、Bean的生命周期:

1.方式一在注解@bean 添加属性实现bean的初始化和销毁

2.方式二 实现InitializingBean,DisposableBean两个接口来初始化和销毁对象

3.方式三 @PostContruct, @PreDestroy注解实现

4.BeanPostProcessor 后置处理器


一、Bean的生命周期:

          bean创建--初始化--使用--销毁 的过程

创建:

  • 单实例:IOC容器启动的时候创建对象;
  • 多实例:调用一次创建一个对象

初始化:

  •    对象创建好后并赋值后,调用初始化方法

销毁:

  • 单实例:容器关闭的时候销毁对象;
  • 多实例:容器不会管理多实例的,需要手动调用destroy方法

1.方式一在注解@bean 添加属性实现bean的初始化和销毁

        以前学习的在xml配置有一个init-method,destroy-method方法实现bean创建和销毁时调用的方法,这里使用init和destory属性。@Bean(value = "user",initMethod = "init",destroyMethod = "destroy")  //这里实现和xml配置相似

例子:

     1.1对象类:   

@Data
@Builder
@AllArgsConstructor
public class User {
    private String name;
    private Integer age;

    public void init(){
        System.out.println("init....");
    }
    public void destroy(){
        System.out.println("destroy...");
    }
}

  1.2 配置类

@Configuration
public class MainLifyCycleConfig {

    //@Scope("prototype") 
    @Bean(value = "user",initMethod = "init",destroyMethod = "destroy")  //这里
    public User user(){
        return  new User("vison",23);
    }
}

1.3 测试类

public class IOCTest {

    public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainLifyCycleConfig.class);
        Object user = applicationContext.getBean("user");
        System.out.println(user);
        applicationContext.close();
    }
}

结果可以看到在调用user的时候调用了init方法,在容器销毁的时候对调用destroy方法。但是如果@Scope("prototype")注解打开后,就不会调用destroy方法。

2.方式二 实现InitializingBean,DisposableBean两个接口来初始化和销毁对象

 InitializingBean 只有一个方法afterPropertiesSet()表示对象的初始化;DisposableBean哟一个方法destroy表示对象的销毁

例子,这里通过扫描的方式来注册bean:

2.1对象类

@Component
public class Task implements InitializingBean,DisposableBean {
    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("Task init ...");
    }
    @Override
    public void destroy() throws Exception {
        System.out.println("Task destory.....");
    }

}

2.2 配置类:

@ComponentScan(value = "com.wusu.annotation.lifecycle")
@Configuration
public class MainLifyCycleConfig {

    @Bean(value = "user",initMethod = "init",destroyMethod = "destroy")
    public User user(){
        return  new User("vison",23);
    }
}

2.3 测试

public class IOCTest {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainLifyCycleConfig.class);
        applicationContext.close();
    }
}

结果分别调用了相应的方法:

Task init ...
 user init....
九月 22, 2018 10:27:25 上午 org.springframework.context.annotation.AnnotationConfigApplicationContext doClose
信息: Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@20ad9418: startup date [Sat Sep 22 10:27:25 CST 2018]; root of context hierarchy
user destroy...
Task destory.....

3.方式三 @PostContruct, @PreDestroy注解实现

            在JSR250规范

             @PostContruct:在创建完对象,并且对象属性赋值完后,来执行初始化方法

              @PreDestroy:在容器销毁bean之前通知我们做清理工作

例子:

3.1 对象类:

@Component
public class Scheduler {
    @PostConstruct
    public void init(){
        System.out.println("scheduler postConstruct...");
    }
    @PreDestroy
    public void destroy(){
        System.out.println("scheduler preDestroy...");
    }
}

同样适用上面的配置和测试类,结果同样实现上面两个相同的功能。

4.BeanPostProcessor 后置处理器

        bean的后置处理器,在bean初始化前后处理一些工作,就是在上面三种初始化(init,@PostConstruct,InitializingBean接口)调用的前后做一些工作的处理.。通过这个方法可以对bean进行一些包装和处理

源码:

public interface BeanPostProcessor {
    //在任何初始化方法(例如上面的三种方式,定义的init方法,@PostConstruct,接口InitializingBean的方法)调用之前工作
    Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;
    //这个是在上面的初始化方法调用之后工作
    Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
}

例子:

4.1 实现这个接口的类,同样需要放入IOC容器中

@Component
public class MyBeanPostProcessor implements BeanPostProcessor {

    //这个bean表示刚刚创建的bean,beanName就是这个bean的名字,所以在这里可以包装bean
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("PostBefore bean:"+bean+",beanName:"+beanName);
        return bean;
    }
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("PostAfter bean:"+bean+",beanName:"+beanName);
        return bean;
    }
}

4.2 同样的配置和测试方法结果显示

user 构建中constrctor......
PostBefore bean:User(name=vison, age=23),beanName:user
 user init....
PostAfter bean:User(name=vison, age=23),beanName:user
user destroy...

重点---Spring底层对于BeanPostProcessor的使用:

     bean赋值,注入其他组件,@AutoWired,生命周期功能,@Async,xxxBeanPostProcess都是使用这个接口的功能来实现。

猜你喜欢

转载自blog.csdn.net/weixin_40792878/article/details/82811673