Spring Bean设置初始化方法

三种方式

  1. 在指定方法上加@PostConstruct@PreDestroy注解去指定该方法是在当前类初始化后还是销毁前执行
  2. 实现InitializingBean接口重写afterPropertiesSet方法去执行初始化后调用方法,或实现DisposableBean接口重写destroy方法去执行销毁前调用方法
  3. 在调用bean的方法上加注解@Bean(initMethod = "initMethod", destroyMethod = "destroyMethod")

代码演示

@Component
public class User implements InitializingBean {
    public User() {
        System.out.println("This is constructor method.");
    }

    public void sayHello() {
        System.out.println("Hello, I'm Lucifer.");
    };

    @PostConstruct
    public void initMethod() {
        System.out.println("This is init method triggered by @PostConstruct annotation.");
    }

    @PreDestroy
    public void destroyMethod() {
        System.out.println("This is destroy method triggered by @PreDestroy annotation.");
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("This is init method triggered by afterPropertiesSet");
    }

    // implements DisposableBean interface
    /*@Override
    public void destroy() throws Exception {
        System.out.println("This is init method triggered by DisposableBean interface");
    }*/
}
@Controller
public class HelloController {
    @Autowired
    User user;

    @RequestMapping("/hello")
    public @ResponseBody String hello(@RequestParam String name) {
        this.test();
        return "hello, " + name;
    }

    @Bean(initMethod = "init", destroyMethod = "destroy")
    private void test() {
        user.sayHello();
    }
}

项目启动后打印日志:

This is constructor method.
This is init method triggered by @PostConstruct annotation.
This is init method triggered by afterPropertiesSet
Hello, I'm Lucifer.

通过http://localhost:8081/hello?name=SpringBoot访问API后打印日志:

Hello, I'm Lucifer.

三种初始化方法执行顺序

Constructor > @PostConstruct > InitializingBean > initMethod

@PostConstruct注解的方法在BeanPostProcessor前置处理器中执行,BeanPostProcessor接口是一个回调作用,Spring容器中每个托管Bean在调用初始化方法之前,都会获得BeanPostProcessor接口实现类的一个回调。而在BeanPostProcessor回调方法中就有一段逻辑判断当前被回调bean的方法中有没有方法被initAnnotationType / destroyAnnotationType注释(即被@PostConstruct / @PreDestroy注解),如果有则添加到 init / destroy 队列中,后续一一执行。

所以@PostConstruct注解的方法先于 InitializingBean 和 initMethod 执行。

实例化bean的过程

  1. 通过构造器newInstance()方法创建bean实例,并对bean实例进行包装
  2. 将bean实例放入三级缓存
  3. 为bean注入属性,如果有依赖其他bean,此时会创建B的实例
  4. 调用相关aware方法: 如果Bean实现了BeanNameAware接口,执行setBeanName()方法;如果Bean实现了BeanFactoryAware接口,执行setBeanFactory()方法
  5. 调用BeanPostProcessor.postProcessBeforeInitialization()方法,@PostConstruct注解的方法就在这里执行
  6. 调用初始化方法,如果Bean实现了InitializingBean接口,调用Bean中的afterPropertiesSet()方法
  7. 调用自定义initMethod方法,@Bean(initMethod = "initMethod", destroyMethod = "destroyMethod"),私有方法依然可以强制访问执行
  8. 调用BeanPostProcessor.postProcessAfterInitialization()方法,AOP在此实现
  9. 如果改Bean是单例,则当容器销毁且实现了DisposableBean接口,则调用destroy()方法;如果Bean是prototype,则将准备好的Bean交给调用者,后续不再管理该Bean的生命周期

你可能感兴趣的:(Spring,spring,java)