侧边栏壁纸
博主头像
张种恩博主等级

一个能运维的 JPG 搬运工

  • 累计撰写 703 篇文章
  • 累计创建 60 个标签
  • 累计收到 24 条评论

Spring注解驱动开发(2)之监听bean的生命周期变化

张种恩
2018-02-03 / 0 评论 / 0 点赞 / 376 阅读 / 0 字 / 正在检测是否收录...
温馨提示:
本文最后更新于 2020-02-25,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

@Bean 的 initMethod&destroyMethod 属性

通过 @Bean 注解的 initMethod 属性来指定 bean 的初始化方法,destroyMethod 属性来指定 bean 的销毁方法。

示例

1、创建测试 POJO:

// com.springanno.pojo.User
public class User {
    public User() {
    }

    public User(String name, Integer age) {
        System.out.println("User 构造方法");
        this.name = name;
        this.age = age;
    }

    private String name;
    private Integer age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public void init(){
        System.out.println("User 初始化方法");
    }

    public void destroy(){
        System.out.println("User 销毁方法");
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

2、通过 @Bean 的属性指定注册 bean 的初始化和销毁监听方法:

// com.springanno.config.MainConfig
import com.springanno.pojo.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MainConfig {

    /*
    通过 @Bean 注解的 initMethod 属性来指定 bean 的初始化方法,destroyMethod 属性来指定 bean 的销毁方法

    构造方法:
        单实例 bean 在容器启动的时候执行
        多实例 bean 在每次获取 bean 的时候执行
    初始化方法:
        构造方法执行后执行
    销毁方法:
        单实例 bean 在容器关闭时执行
        多实例时,容器不会管理这个 bean ,所以不会调用销毁方法
     */
    @Bean(initMethod = "init", destroyMethod = "destroy")
    public User user(){
        return new User("tom", 12);
    }
}

3、测试:

ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
((AnnotationConfigApplicationContext) applicationContext).close();
/*
User 构造方法
User 初始化方法
User 销毁方法
 */

@PostConstruct & @PreDestroy 注解

通过将 @PostConstruct@PreDestroy 注解标注在 bean 的方法上让其在 bean 初始化之后和销毁之前执行。

1、创建测试 Bean,使用注解:

// com.springanno.pojo.User
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

public class User {
    public User() {
    }

    public User(String name, Integer age) {
        System.out.println("User 构造方法");
        this.name = name;
        this.age = age;
    }

    private String name;
    private Integer age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @PostConstruct
    public void init() throws Exception {
        System.out.println("User init");
    }

    @PreDestroy
    public void destroy() throws Exception {
        System.out.println("User destroy");
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

2、注册 bean 到容器:

// com.springanno.config.MainConfig
import com.springanno.pojo.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MainConfig {

    @Bean
    public User user(){
        return new User("tom", 12);
    }
}

3、测试:

ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
((AnnotationConfigApplicationContext) applicationContext).close();
/*
User 构造方法
User init
User destroy
 */

实现 InitializingBean & DisposableBean 接口

通过让 Bean 实现 InitializingBean 来定义初始化逻辑,实现 DisposableBean 来定义销毁逻辑。

示例

1、创建测试 Bean,实现上述两个接口:

// com.springanno.pojo.User
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;

public class User implements InitializingBean, DisposableBean {
    public User() {
    }

    public User(String name, Integer age) {
        System.out.println("User 构造方法");
        this.name = name;
        this.age = age;
    }

    private String name;
    private Integer age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public void afterPropertiesSet() throws Exception {
        System.out.println("User afterPropertiesSet");
    }

    public void destroy() throws Exception {
        System.out.println("User destroy");
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

2、注册到容器:

// com.springanno.config.MainConfig
import com.springanno.pojo.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MainConfig {

    @Bean
    public User user(){
        return new User("tom", 12);
    }
}

3、测试:

ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
((AnnotationConfigApplicationContext) applicationContext).close();
/*
User 构造方法
User afterPropertiesSet
User destroy
 */

实现 BeanPostProcessor 接口

定义一个类实现 BeanPostProcessor 接口,将其注册到容器中后它便可以监听容器中所有 bean 的初始化前和初始化后操作。

1、创建实现了 BeanPostProcessor 接口的类:

// com.springanno.config.MyBeanPostProcessor
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;

@Component
public class MyBeanPostProcessor implements BeanPostProcessor {
    /**
     * 初始化操作执行之前执行
     */
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println(beanName + "---->postProcessBeforeInitialization");
        return bean;
    }

    /**
     * 初始化操作执行之后执行
     */
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println(beanName + "---->postProcessAfterInitialization");
        return bean;
    }
}

2、创建测试 Bean:

// com.springanno.pojo.User
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

public class User {
    public User() {
    }

    public User(String name, Integer age) {
        System.out.println("User 构造方法");
        this.name = name;
        this.age = age;
    }

    private String name;
    private Integer age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @PostConstruct
    public void init() throws Exception {
        System.out.println("User init");
    }

    @PreDestroy
    public void destroy() throws Exception {
        System.out.println("User destroy");
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

3、测试:

ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
((AnnotationConfigApplicationContext) applicationContext).close();
/*
User 构造方法
user---->postProcessBeforeInitialization
User init
user---->postProcessAfterInitialization
User destroy
 */

Spring 底层给 bean 赋值、@Autowried 注入、生命周期注解等功能都是通过 BeanPostProcessor 完成的。

# BeanPostProcessor的子接口及实现类
ScheduledAnnotationBeanPostProcessor (org.springframework.scheduling.annotation)
AdvisorAdapterRegistrationManager (org.springframework.aop.framework.adapter)
BeanPostProcessorChecker in PostProcessorRegistrationDelegate (org.springframework.context.support)
ImportAwareBeanPostProcessor in ConfigurationClassPostProcessor (org.springframework.context.annotation)
LoadTimeWeaverAwareProcessor (org.springframework.context.weaving)
AbstractAdvisingBeanPostProcessor (org.springframework.aop.framework)
    AbstractBeanFactoryAwareAdvisingPostProcessor (org.springframework.aop.framework.autoproxy)
DestructionAwareBeanPostProcessor (org.springframework.beans.factory.config)
    InitDestroyAnnotationBeanPostProcessor (org.springframework.beans.factory.annotation)
    ApplicationListenerDetector in PostProcessorRegistrationDelegate (org.springframework.context.support)
ApplicationContextAwareProcessor (org.springframework.context.support)
MergedBeanDefinitionPostProcessor (org.springframework.beans.factory.support)
    InitDestroyAnnotationBeanPostProcessor (org.springframework.beans.factory.annotation)
    RequiredAnnotationBeanPostProcessor (org.springframework.beans.factory.annotation)
    AutowiredAnnotationBeanPostProcessor (org.springframework.beans.factory.annotation)
    ApplicationListenerDetector in PostProcessorRegistrationDelegate (org.springframework.context.support)
BeanValidationPostProcessor (org.springframework.validation.beanvalidation)
InstantiationAwareBeanPostProcessor (org.springframework.beans.factory.config)
    SmartInstantiationAwareBeanPostProcessor (org.springframework.beans.factory.config)
CommonAnnotationBeanPostProcessor (org.springframework.context.annotation)
0

评论区