在日常开发中难免会经常遇到这样的应用场景,在项目初始化时执行指定的代码实现一些功能,或者在项目启动后执行一些代码实现功能。这个时候就需要用到Spring提供的一些接口、注解了。本文都是以SpringBoot为基础。
1.Spring容器启动前执行
1.1接口类InitializingBean
直接在代码中实现该接口afterPropertiesSet方法,并在该方法中执行代码。
值得注意的是 在该接口执行时Spring 容器是还没有初始化完成的。在这里取spring容器中的对象可能会被抛出空指针异常。
@Component
public class TestConfigInitializingBean implements InitializingBean {
private static final Logger LOGGER = LoggerFactory.getLogger(TestConfigInitializingBean.class);
@Override
public void afterPropertiesSet() throws Exception {
LOGGER.info("--------------------------------------------");
LOGGER.info("-----正在执行InitializingBean实现类代码-----");
LOGGER.info("--------------------------------------------");
}
}
1.2 注解实现@PostConstruct
这种方式相对于InitializingBean接口实现要方便一些。直接在需要的方法上添加该注解即可。
这种方式与上面InitializingBean接口一样都是在spring容器初始化前执行,所有在该注解方法中获取容器内对象可能存在空指针异常
@Component
public class TestPostConstruct {
private static final Logger LOGGER = LoggerFactory.getLogger(TestPostConstruct.class);
@PostConstruct
public void initPostConstruct() {
LOGGER.info("--------------------------------------------");
LOGGER.info("-----正在执行@PostConstruct实现类代码-----");
LOGGER.info("--------------------------------------------");
}
}
2 Spring容器初始化完成后执行
2.1 实现监听器 ApplicationListener<ApplicationEvent>
关于这个接口,很多人可能会遇到多次执行该方法。其实这是正常现象,我在执行这段代码时,被重复调用了3次
通过debug调试观察发现,3次执行参数ApplicationEvent event都是不同的。
第一次参数内source是AnnotationConfigEmbeddedWebApplicationContext
第二次参数内source是TomcatEmbeddedServletContainer
第三次参数内source是SpringApplication
我个人的理解为springboot web容器加载时触发该方法一次,springboot自带tomcat容器初始化时触发容器一次
第三次是springApplication 创建并初始化Spring上下文时再次触发该监听
直接上代码
@Component
public class TestConfigApplicationListener implements ApplicationListener<ApplicationEvent> {
private static final Logger LOGGER = LoggerFactory.getLogger(TestConfigApplicationListener.class);
@Override
public void onApplicationEvent(ApplicationEvent event) {
LOGGER.info("--------------------------------------------");
LOGGER.info("-----正在执行ApplicationListener实现类代码-----");
LOGGER.info