原创不易,如需转载,请注明出处http://www.javashuo.com/article/p-zqnnuvrr-cx.html,谢谢支持哈!!! html
在平时的业务模块开发过程当中,不免会须要作一些全局的任务、缓存、线程等等的初始化工做,那么如何解决这个问题呢?方法有多种,但具体又要怎么选择呢?git
按照前面的分析,Spring-boot容器启动流程整体可划分为2部分:github
由上可知,咱们只要实现这两个中的任何一个接口即可以完成咱们的资源初始化任务,能够看到它们的加载是在容器彻底启动以前。它两的区别是:前者的run方法参数是String...args,直接传入字符串,后者的参数是ApplicationArguments,对参数进行了封装。功能上是同样的。同时也可使用 @Order注解来实现资源加载的前后顺序,值越小,优先级越高。实例以下:spring
@Component @Order(1) public class MyCommandLineRunner implements CommandLineRunner { @Override public void run(String... args) throws Exception { System.out.println("...init resources by implements CommandLineRunner"); } } @Component @Order(2) public class MyApplicationRunner implements ApplicationRunner { @Override public void run(ApplicationArguments applicationArguments) throws Exception { System.out.println("...init resources by implements ApplicationRunner"); } }
在具体Bean的实例化过程当中执行,@PostConstruct注解的方法,会在构造方法以后执行,顺序为Constructor > @Autowired > @PostConstruct > 静态方法,因此这个注解就避免了一些须要在构造方法里使用依赖组件的尴尬(与之对应的还有@PreDestroy,在对象消亡以前执行,原理差很少)。使用特色以下:segmentfault
此方法只会被执行一次缓存
@Component public Class AAA { @Autowired private BBB b; public AAA() { System.out.println("此时b还未被注入: b = " + b); } @PostConstruct private void init() { System.out.println("此时b已经被注入: b = " + b); } }
InitializingBean 是 Spring 提供的一个接口,只包含一个方法 afterPropertiesSet()。凡是实现了该接口的类,当其对应的 Bean 交由 Spring 管理后,当其必要的属性所有设置完成后,Spring 会调用该 Bean 的 afterPropertiesSet()。在Bean在实例化的过程当中执执行顺序为:Constructor > @PostConstruct > InitializingBean > init-methodspringboot
public class InitSequenceBean implements InitializingBean { public InitSequenceBean() { System.out.println("InitSequenceBean: constructor"); } @PostConstruct public void postConstruct() { System.out.println("InitSequenceBean: postConstruct"); } public void initMethod() { System.out.println("InitSequenceBean: init-method"); } @Override public void afterPropertiesSet() throws Exception { System.out.println("InitSequenceBean: afterPropertiesSet"); } }
ApplicationListener 就是spring的监听器,可以用来监听事件,典型的观察者模式。若是容器中有一个ApplicationListener Bean,每当ApplicationContext发布ApplicationEvent时,ApplicationListener Bean将自动被触发。这种事件机制都必须须要程序显示的触发。其中spring有一些内置的事件,当完成某种操做时会发出某些事件动做。好比监听ContextRefreshedEvent事件,当全部的bean都初始化完成并被成功装载后会触发该事件,实现ApplicationListener
@Component public class DataSourceInitListener implements ApplicationListener<ContextRefreshedEvent> {//ContextRefreshedEvent为启动事件 private static final Logger LOGGER = LoggerFactory.getLogger(DataSourceInitListener.class); @Autowired private SystemConfigService systemConfigService; @Autowired private ItemService itemService; @Autowired private SystemResultService systemResultService; @Override public void onApplicationEvent(ContextRefreshedEvent event) { if(event.getApplicationContext().getParent() == null) {//判断是否执行过,执行过则再也不执行 LOGGER.info("初始化systemConfig数据"); systemConfigService.initConfig(); LOGGER.info("初始化返回消息数据"); systemResultService.initResult(); LOGGER.info("系统初始化结束..........."); } } }
我的博客地址:ide
csdn:https://blog.csdn.net/tiantuo6513post
segmentfault:https://segmentfault.com/u/baixianlong