我想在spring-boot应用程序开始监视目录更改之后运行代码。
我已经尝试运行一个新线程,但@Autowired服务还没有设置在那一点。
我已经能够找到ApplicationPreparedEvent,它在@Autowired注释设置之前触发。理想情况下,我希望事件在应用程序准备好处理http请求时触发。
是否有更好的事件可以使用,或者在应用程序在spring-boot中激活后运行代码的更好方法?
我想在spring-boot应用程序开始监视目录更改之后运行代码。
我已经尝试运行一个新线程,但@Autowired服务还没有设置在那一点。
我已经能够找到ApplicationPreparedEvent,它在@Autowired注释设置之前触发。理想情况下,我希望事件在应用程序准备好处理http请求时触发。
是否有更好的事件可以使用,或者在应用程序在spring-boot中激活后运行代码的更好方法?
当前回答
你有几个选择:
使用CommandLineRunner或ApplicationRunner作为Bean定义:
Spring Boot在应用程序启动过程的末尾执行这些命令。在大多数情况下,CommandLineRunner将完成这项工作。下面是一个用Java 8实现CommandLineRunner的例子:
@Bean
public CommandLineRunner commandLineRunner() {
return (args) -> System.out.println("Hello World");
}
请注意,args是参数的字符串数组。你也可以提供这个接口的实现,并将其定义为Spring组件:
@Component
public class MyCommandLineRunner implements CommandLineRunner {
@Override
public void run(String... args) throws Exception {
System.out.println("Hello World");
}
}
如果需要更好的参数管理,可以使用ApplicationRunner。ApplicationRunner接受一个具有增强参数管理选项的ApplicationArguments实例。
你也可以使用Spring的@Order注释来排序CommandLineRunner和ApplicationRunner bean:
@Bean
@Order(1)
public CommandLineRunner commandLineRunner() {
return (args) -> System.out.println("Hello World, Order 1");
}
@Bean
@Order(2)
public CommandLineRunner commandLineRunner() {
return (args) -> System.out.println("Hello World, Order 2");
}
使用Spring Boot的ContextRefreshedEvent:
Spring Boot在启动时发布几个事件。这些事件表示应用程序启动过程中某个阶段的完成。你可以监听ContextRefreshedEvent并执行自定义代码:
@EventListener(ContextRefreshedEvent.class)
public void execute() {
if(alreadyDone) {
return;
}
System.out.println("hello world");
}
ContextRefreshedEvent被发布了几次。因此,确保检查代码执行是否已经完成。
其他回答
在春季> 4.1中使用SmartInitializingSingleton bean
@Bean
public SmartInitializingSingleton importProcessor() {
return () -> {
doStuff();
};
}
作为备选方案,CommandLineRunner bean可以实现,也可以使用@PostConstruct注释bean方法。
我非常喜欢@cahen (https://stackoverflow.com/a/44923402/9122660)对EventListener注释的使用建议,因为它非常干净。不幸的是,我不能让它在Spring + Kotlin设置中工作。对Kotlin有效的方法是将类作为方法参数添加:
@EventListener
fun doSomethingAfterStartup(event: ApplicationReadyEvent) {
System.out.println("hello world, I have just started up");
}
为Dave Syer的回答提供了一个例子,这就像一个魅力:
@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));
}
}
您可以使用ApplicationRunner扩展类,重写run()方法并在那里添加代码。
import org.springframework.boot.ApplicationRunner;
@Component
public class ServerInitializer implements ApplicationRunner {
@Override
public void run(ApplicationArguments applicationArguments) throws Exception {
//code goes here
}
}
尝试这个方法,它将在应用程序上下文完全启动时运行您的代码。
@Component
public class OnStartServer implements ApplicationListener<ContextRefreshedEvent> {
@Override
public void onApplicationEvent(ContextRefreshedEvent arg0) {
// EXECUTE YOUR CODE HERE
}
}