SpringBoot应用启动服务要执行一些初始化操作的可用方法@PostConstruct与CommandLineRunner、ApplicationRunner

首先来说说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();
			}
		};
	}
}

********************************* 不积跬步无以至千里,不积小流无以成江海 *********************************

猜你喜欢

转载自blog.csdn.net/weixin_42465125/article/details/88560320