首先来说说javax.annotation-api下的@PostConstruct【这里声明一个问题,和@PostConstruct对应的还有个@PreDestroy,很多文章都写成@PreConstruct,没有这个注解哈,这个是一个小问题,这里提一下】
在Spring中,构造器Constructor,@Autowired,@PostConstruct三者的执行顺序,首先说@PostConstruct修饰的方法是在构造函数执行之后执行的,那么构造函数Constructor肯定就优先于@PostConstruct函数执行,那么@Autowired呢,@Autowired是用于注入对象使用的,那么肯定本对象已经有了才能注入依赖的对象,所以构造器Constructor优先于@Autowired执行,接下来就是分析
@Autowired和@PostConstruct,可以看看@PostConstruct的描述,必须在所有的依赖都注入,所以@Autowired是优先于@PostConstruct执行的
所以三者的顺序是:
Constructor > @Autowired > @PostConstruct
接下来说说使用@PostConstruct初始化
如果想在生成对象时候完成某些初始化操作,而偏偏这些初始化操作又依赖于依赖注入,那么就无法在构造函数中实现。为此,可以使用@PostConstruct注解一个方法来完成初始化,@PostConstruct注解的方法将会在依赖注入完成后被自动调用。
简单说明:在Spring中一个类作为组件,同时在启动时会纳入Spring IOC中,那么在Servlet容器启动的时候就会生成对象,如果有方法【这些方法有一定的限制,参考@PostConstruct的说明】被@PostConstruct,那么就会自动执行,如果没有作为Spring组件,在Servlet容器启动时也是不会执行的,那么就只能在创建对象时执行,简单来说就是创建了对象被@PostConstruct修饰的方法才会执行
可以参考:https://blog.csdn.net/weixin_42465125/article/details/88417718
接下来说说SpringBoot提供的两个类:CommandLineRunner、ApplicationRunner
下面直接贴代码:代码中有详细解释
@SpringBootApplication
public class SpringbootMailApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootMailApplication.class, args);
}
@Autowired
private RedisTemplate<String, Object> redisTemplate;
@Autowired
private StringRedisTemplate stringRedisTemplate;
ListOperations<String, Object> opsForList;
ValueOperations<String, String> opsForString;
/**
* CommandLineRunner、ApplicationRunner 接口是在容器启动成功后的最后一步回调(类似开机自启动)
*
* 接口被用作将其加入spring容器中时执行其run方法。多个CommandLineRunner可以被同时执行在同一个spring上下文中并且执行顺序是以order注解的参数顺序一致。
*/
// 启动后执行的功能,可以用来初始化一些东西,这种情况下面明显使用@Bean来玩就比较方便,
// 比起去创建一个新的类实现CommandLineRunner来说更方便[继承的使用方法参考:https://www.jianshu.com/p/5d4ffe267596,https://www.jianshu.com/p/5d4ffe267596]
@Bean
CommandLineRunner commandLineRunner(RedisTemplate<String, Object> redisTemplate) {
return new CommandLineRunner() {
@Override
public void run(String... args) throws Exception {
opsForList = redisTemplate.opsForList();
}
};
}
// 启动后执行的功能,可以用来初始化一些东西,这种情况下面明显使用@Bean来玩就比较方便,比起去创建一个新的类实现CommandLineRunner来说更方便,借助Lamdab更爽
@Bean
CommandLineRunner commandLineRunnerId01(RedisTemplate<String, Object> redisTemplate) {
return args -> {
opsForList = redisTemplate.opsForList();
opsForString = stringRedisTemplate.opsForValue();
};
}
@Bean
ApplicationRunner applicationRunner() {
return new ApplicationRunner() {
@Override
public void run(ApplicationArguments args) throws Exception {
opsForList = redisTemplate.opsForList();
}
};
}
}
********************************* 不积跬步无以至千里,不积小流无以成江海 *********************************