如何在 Spring Boot 启动的时候运行一些特定的代码? ApplicationRunner & CommandLineRunner

如何在 Spring Boot 启动的时候运行一些特定的代码?

可以实现接口 ApplicationRunner 或者 CommandLineRunner,这两个接口实现方式一样,它们都只提供了一个 run 方法

1. ApplicationRunner
  • 在项目中,可能会遇到这样一个问题:在项目启动完成之后,紧接着执行一段代码。
    在SpringBoot中,提供了一个接口:ApplicationRunner。该接口中,只有一个run方法,他执行的时机是:spring容器启动完成之后,就会紧接着执行这个接口实现类的run方法。
  • 实现了ApplicationRunner接口的类,并重写run方法,在springBoot项目启动后就是调用执行一次run方法
@Component
@Order(1)
public class TestImplApplicationRunner implements ApplicationRunner {
    @Override
    public void run(ApplicationArguments args) throws Exception {
    //do something
        System.out.println("测试ApplicationRunner接口1");

    }
}
  • @Component注解
    这个实现类,要注入到spring容器中,这里使用了@Component注解;
    在同一个项目中,可以定义多个ApplicationRunner的实现类,他们的执行顺序通过注解@Order注解或者再实现Ordered接口来实现。

  • run方法的参数:ApplicationArguments可以获取到当前项目执行的命令参数。(比如把这个项目打成jar执行的时候,带的参数可以通过ApplicationArguments获取到);由于该方法是在容器启动完成之后,才执行的,所以,这里可以从spring容器中拿到其他已经注入的bean。

  • @Order注解
    如果有多个实现类,而你需要他们按一定顺序执行的话,可以在实现类上加上@Order注解。@Order(value=整数值)。SpringBoot会按照@Order中的value值从小到大依次执行。
    @order,使用注解方式使bean的加载顺序得到控制,@Order标记定义了组件的加载顺序,值越小拥有越高的优先级,可为负数。值越小,越先被加载。

  • @Order(-1)优先于@Order(0)
    @Order(1)优先于@Order(2)

2. CommandLineRunner

背景

项目启动之前,预先加载数据。比如,权限容器、特殊用户数据等。通常我们可以使用监听器、事件来操作。但是,springboot提供了一个简单的方式来实现此类需求,即,CommandLineRunner。

先了解一下这个类

import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;

/**
 * Interface used to indicate that a bean should <em>run</em> when it is contained within
 * a {@link SpringApplication}. Multiple {@link CommandLineRunner} beans can be defined
 * within the same application context and can be ordered using the {@link Ordered}
 * interface or {@link Order @Order} annotation.
 * <p>
 * If you need access to {@link ApplicationArguments} instead of the raw String array
 * consider using {@link ApplicationRunner}.
 *
 * @author Dave Syer
 * @see ApplicationRunner
 */
@FunctionalInterface
public interface CommandLineRunner {

	/**
	 * Callback used to run the bean.
	 * @param args incoming main method arguments
	 * @throws Exception on error
	 */
	void run(String... args) throws Exception;

}

文档中,我们可以知道以下几点。

  • 这是一个接口,用户可以自定义实现该接口,具体实现run方法
  • 任何在上下文容器之内的bean都可以实现run方法
  • 如果在上下文中,存在多个该接口实现类,可以通过@order注解,指定加载顺序

所以我们基本上大概已经了解了这个接口的作用以及用法。

案例说明
分别定义一个数据加载类MyStartupRunner1,排序为2;另一个数据加载类MyStartupRunner2,排序为1。看看它们记载数据的顺序。

	@Component
	@Order(value = 2)
	public class MyStartupRunner1 implements CommandLineRunner{
    @Override
    public void run(String... strings) throws Exception {
        System.out.println(">>>>>>>>>>服务启动执行,执行加载数据等操作 MyStartupRunner1 order 2 <<<<");
	    }
	}

	@Component
	@Order(value = 1)
	public class MyStartupRunner2 implements CommandLineRunner {
	@Override
		public void run(String... strings) throws Exception {
    		System.out.println(">>>>服务启动执行,执行加载数据等操作 MyStartupRunner2 order 1 <<<<<<<");
    	}
	}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值