其实这是很实用的一个事儿:在很多时候可能需要在项目发版的时候就立刻初始化一些数据,关于数据初始化其实从配置xml到注解有很多实现的方式,但是其中执行时机和内容需要对Spring加载的过程有一定人之才可以。其实xml方式的配置相较于注解较为繁杂,但究其原理是一致的,只介绍注解模式
1.@PostConstruct
一般情况下工具类和数据源作为最基层的Bean是不会涉及到调用,所以其初始化一般不会有其他依赖,所以选在在Spring加载Servlet时就可以使用PostConstruct注解来加载一些工具类,而当这写工具类/组件在内部调用了其他组件/服务层的话则需要在执行的类上增加@DependsOn注解。例如:
// 每天凌晨3点更新 @Scheduled(cron = "0 0 3 * * ?") @PostConstruct public void excute(){ quiltyCacheJob.excute(); }
但是在job的excute()方法当中也调用到了其他的Dao/Component/Services,所以得添加:
// 每天凌晨3点更新 @Scheduled(cron = "0 0 3 * * ?") @PostConstruct @DependsOn(value = {"aBean","bBean"}) public void excute(){ quiltyCacheJob.excute(); }
@DependsOn的Bean的Name,当不去使用@Bean注解重新定义name属性的时候,默认为首字母小写的类名。注意:PostConstruct执行的时机在构造方法后,init()方法之前,而且被注解的方法得是Services层或者Component。
2.implements ApplicationListener<ContextRefreshedEvent>
这种方式就比较灵活且多变,事件监听的模式让这种方式就比较好操控
@Component public class GuideQualityJob implements ApplicationListener<ContextRefreshedEvent> { @Autowired private QualityGuideCacheJob quiltyCacheJob; /** * 0 45 * * * ? */ // 每天凌晨3点更新 @Scheduled(cron = "0 0 3 * * ?") public void excute(){ quiltyCacheJob.excute(); } @Override public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) { if (contextRefreshedEvent.getApplicationContext().getParent() == null){ quiltyCacheJob.excute(); } } }
这里我指的是数据初始化,由于Root ApplicationContext 就是老大,不会有父容器,所以上面的写法是指执行一次。而执行的时机则是初始化Spring容器结束之后。
3.implements InitializingBean
@Component public class GuideQualityJob implements InitializingBean { @Autowired private QualityGuideCacheJob quiltyCacheJob; /** * 0 45 * * * ? */ // 每天凌晨3点更新 @Scheduled(cron = "0 0 3 * * ?") public void excute(){ quiltyCacheJob.excute(); } @Override public void afterPropertiesSet() throws Exception { quiltyCacheJob.excute(); } }
这种方式有点类似于@PostConstruct的执行,其执行时间依旧在init()方法之前,但是该方法会在Bean的所有属性初始化完成后调用。所以在使用这个的情况是调用的Services当中并无更深层次的调用时使用。
以上三种方式提供了数据初始化的一些简洁方案,但是深究其涉及还是有很多内容可以了解,这里只记录下惯用的使用方式,关乎底层,再探究。
互访,https://www.sufaith.com 顺便帮点一下页面侧边栏的广告哦~