SpringBoot 初始化资源

1 、使用接口ApplicationRunner和CommandLineRunner

这两个接口都是在容器运行后执行的,如下图示

 如果项目需要在系统启动时,初始化资源,可以继承这两个接口,实现诸如缓存预热、DB连接等。

实现ApplicationRunner接口

@Component
public class MyApplicationRunner implements ApplicationRunner {
    @Override
    public void run(ApplicationArguments args) throws Exception {
        System.out.println("缓存预热~");
        System.out.println("DB连接~");
        System.out.println("日志系统初始化~");
        System.out.println("资源文件初始化~");
        System.out.println("常驻后台线程的资源初始化~");

    }
}
View Code

实现CommandLineRunner接口

@Component
public class MyCommandLineRunner implements CommandLineRunner {

    @Override
    public void run(String... args) throws Exception {
        System.out.println("缓存预热~");
        System.out.println("DB连接~");
        System.out.println("日志系统初始化~");
        System.out.println("资源文件初始化~");
        System.out.println("常驻后台线程的资源初始化~");
    }
}
View Code

2、监听spring事件ApplicationListener<>

ApplicationContext事件的实现机制是观察者模式,通过两个接口ApplicationEvent和ApplicationListener来实现。

spring容器在初始化时,会在不同的阶段,发布ApplicationEvent事件,因此,可以通过ApplicationListener监听各个阶段的事件来实现不同的功能。

spring提供了以下ApplicationEvent事件:

  1. ContextStartedEvent 上下文启动事件,此 Start 事件是当Spring容器启动时发布,即调用 start() 方法是执行,意味着所有Lifecyc Bean 都监听到了 start 事件。
  2. ContextRefreshedEvent 上下文刷新事件 

    此 Refreshed 事件是当容器实例化时发布,即执行 refresh() 方法,此时所有的 Bean 都已加载,后置处理器被激活,容器中所有的对象就可以使用,如果容器支持热重载,则 refresh 可以被触发多次(XmlWebApplicatonContext支持热刷新,而GenericApplicationContext则不支持)。

  3. ContextStoppedEvent  上下文停止事件 当使用 ConfigurableApplicationContext 接口中的 stop() 停止 ApplicationContext 时,发布这个事件。你可以在接受到这个事件后做必要的清理的工作。
  4. ContextClosedEvent 上下文关闭事件 当使用 ConfigurableApplicationContext 接口中的 close() 方法关闭 ApplicationContext 时,该事件被发布。一个已关闭的上下文到达生命周期末端;它不能被刷新或重启。
  5. RequestHandledEvent 请求处理完成事件 此 Request handled 事件只在使用spring的DispatcherServlet时有效,当一个请求被处理完成时发布。

基于以上事件类型,我们可以监听ContextRefreshedEvent事件,初始化系统资源,以及监听ContextStoppedEvent事件来清理资源。

初始化资源:

@Component
public class MyApplicationListener implements ApplicationListener<ContextRefreshedEvent> {
    @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {
        System.out.println("做一些初始化的工作,比如缓存预热~");
        ApplicationContext ct= event.getApplicationContext();
        System.out.println(ct);
    }
}
View Code

清理资源:

@Component
public class MyApplicationStopListener implements ApplicationListener<ContextStoppedEvent> {
    @Override
    public void onApplicationEvent(ContextStoppedEvent event) {
        System.out.println("做一些清理资源的工作,比如缓存清理,DB连接清理~");
        ApplicationContext ct= event.getApplicationContext();
        System.out.println(ct);
    }

    @Override
    public boolean supportsAsyncExecution() {
        return ApplicationListener.super.supportsAsyncExecution();
    }
}
View Code

3、@PostConstruct、@PreDestroy注解

@PostConstruct注解时针对Bean初始化完成后,要执行的方法,@PreDestroy注解时Bean销毁时执行。

@Component
public class RedisInit {
    @PostConstruct
    public void init(){
        System.out.println("缓存预热~");
    }
    @PreDestroy
    public void destroy(){
        System.out.println("缓存清理~");
    }
}
View Code

 

4、InitializingBean、DisposableBean接口

InitializingBean、DisposableBean 接口也是针对的Bean的。

@Component
public class RedisInitializingBean implements InitializingBean, DisposableBean {
    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("缓存预热~");
    }

    @Override
    public void destroy() throws Exception {
        System.out.println("缓存清理~");
    }
}
View Code

5、配置Bean时,指定Bean的init和destroy方法

@Bean(name = "redisInit",initMethod = "init",destroyMethod = "")
    public RedisInit redisInit(){
        return new RedisInit();
    }
View Code