Spring Boot 入门 - 进阶篇(6)- 启动加载(CommandLineRunner)

启动成功后可以通过以下方法运行自己的初始代码:
  • @PostConstruct注解
  • ApplicationReadyEvent事件
  • CommandLineRunner/ApplicationRunner接口

@Component
public class StartUpInit {

  @Autowired
  private SomeService service;

  @PostConstruct
  public void init(){
     // ...
  }

}


@Component
public class GeneralEventHandler {

    @EventListener
    public void handleApplicationReady(ApplicationReadyEvent event) {
        log.info("The application is ready to service requests..");
    }

}


Spring Boot提供了两个接口:CommandLineRunner、ApplicationRunner,用于启动应用时做特殊处理,这些代码会在SpringApplication的run()方法运行完成之前被执行。
通常用于应用启动前的特殊代码执行、特殊数据加载、垃圾数据清理、微服务的服务发现注册、系统启动成功后的通知等。相当于Spring的ApplicationListener、Servlet的ServletContextListener。

CommandLineRunner 和 ApplicationRunner 的区别是run()方法的参数不同。

(1)CommandLineRunner:参数是字符串数组
@Component
public class CommandLineAppStartupRunner implements CommandLineRunner {
  private static final Logger logger = LoggerFactory.getLogger(CommandLineAppStartupRunner.class);

  @Override
  public void run(String... args) throws Exception {
    logger.info("Application started with command-line arguments: {} . \n To kill this application, press Ctrl + C.", Arrays.toString(args));
  }
}


(2)ApplicationRunner:参数被放入ApplicationArguments
通过getOptionNames()、getOptionValues()、getSourceArgs()获取参数
@Component
public class AppStartupRunner implements ApplicationRunner {
  private static final Logger logger = LoggerFactory.getLogger(AppStartupRunner.class);

  @Override
  public void run(ApplicationArguments args) throws Exception {
    logger.info("Your application started with option names : {}", args.getOptionNames());
  }
}


也可以两个接口同时实现,但是没有必要。
@Component
public class StartupRunner implements CommandLineRunner, ApplicationRunner  {
  private static final Logger logger = LoggerFactory.getLogger(CommandLineAppStartupRunner.class);

  @Override
  public void run(String... args) throws Exception {
    logger.info("Application started with command-line arguments: {} . \n To kill this application, press Ctrl + C.", Arrays.toString(args));
  }
  
  @Override
  public void run(ApplicationArguments args) throws Exception {
    logger.info("Your application started with option names : {}", args.getOptionNames());
  }
}


也可以通过@Bean定义
@Configuration
public class RunnerConfig {

	@Bean
	public CommandLineRunner runner(){
	  return new CommandLineRunner() {
	    public void run(String... args){
	      System.out.println("CommandLineRunner run()");
	    }
	  };
	}

}


(3)通过@Order设置执行顺序
@Component
@Order(3)
public class Runner1 implements CommandLineRunner {
  @Override
  public void run(String... args) throws Exception {
    System.out.println("Runner1 run()");
  }
}

@Component
@Order(2)
public class Runner2 implements CommandLineRunner {
  @Override
  public void run(String... args) throws Exception {
    System.out.println("Runner2 run()");
  }
}

@Component
@Order(1)
public class Runner3 implements CommandLineRunner {
  @Override
  public void run(String... args) throws Exception {
    System.out.println("Runner3 run()");
  }
}


(4)注入Bean
CommandLineRunner在被执行时,Spring内部已经启动完成,可以注入Spring的Bean。
@Component
public class StartupRunner implements CommandLineRunner {

  @Autowired
  private SampleService sampleService;

  @Override
  public void run(String... args) throws Exception {
    sampleService.executeSample();
  }
  
}

猜你喜欢

转载自rensanning.iteye.com/blog/2363313