我希望在 spring-boot 应用程序开始监视目录以进行更改后运行代码。
我尝试过运行新线程,但此时尚未设置@Autowired
服务。
我能够找到ApplicationPreparedEvent
,它会在设置@Autowired
注释之前触发。理想情况下,我希望在应用程序准备好处理http请求后触发该事件。
是否有更好的事件要使用,或者在应用程序在 spring-boot 中运行后运行代码的更好方式?
答案 0 :(得分:200)
就这么简单:
@EventListener(ApplicationReadyEvent.class)
public void doSomethingAfterStartup() {
System.out.println("hello world, I have just started up");
}
在版本1.5.1.RELEASE
答案 1 :(得分:88)
尝试:
@Configuration
@EnableAutoConfiguration
@ComponentScan
public class Application extends SpringBootServletInitializer {
@SuppressWarnings("resource")
public static void main(final String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(Application.class, args);
context.getBean(Table.class).fillWithTestdata(); // <-- here
}
}
答案 2 :(得分:82)
您是否尝试过ApplicationReadyEvent?
@Component
public class ApplicationStartup
implements ApplicationListener<ApplicationReadyEvent> {
/**
* This event is executed as late as conceivably possible to indicate that
* the application is ready to service requests.
*/
@Override
public void onApplicationEvent(final ApplicationReadyEvent event) {
// here your code ...
return;
}
}
代码来自:http://blog.netgloo.com/2014/11/13/run-code-at-spring-boot-startup/
这是documentation提到的关于创业活动的内容:
...
应用程序事件在应用程序运行时按以下顺序发送:
ApplicationStartedEvent在运行开始时发送,但之前发送 除了听众和初始化者的注册之外的任何处理。
当要在上下文中使用的环境已知但在上下文之前发送ApplicationEnvironmentPreparedEvent 已创建。
ApplicationPreparedEvent在刷新开始之前发送,但是在加载了bean定义之后发送。
在刷新之后发送ApplicationReadyEvent并且已经处理了任何相关的回调以指示应用程序已准备好 服务请求。
如果启动时发生异常,则会发送ApplicationFailedEvent。
...
答案 3 :(得分:77)
为什么不创建一个在初始化时启动监视器的bean,如:
@Component
public class Monitor {
@Autowired private SomeService service
@PostConstruct
public void init(){
// start your monitoring in here
}
}
在为bean完成任何自动装配之前,不会调用init
方法。
答案 4 :(得分:58)
&#34; Spring Boot&#34;方法是使用CommandLineRunner
。只需添加那种类型的豆子就可以了。在Spring 4.1(Boot 1.2)中,还有一个SmartInitializingBean
在所有内容初始化后获得回调。还有SmartLifecycle
(来自Spring 3)。
答案 5 :(得分:33)
您可以使用ApplicationRunner
扩展一个类,覆盖run()
方法并在那里添加代码。
import org.springframework.boot.ApplicationRunner;
@Component
public class ServerInitializer implements ApplicationRunner {
@Override
public void run(ApplicationArguments applicationArguments) throws Exception {
//code goes here
}
}
答案 6 :(得分:18)
ApplicationReadyEvent
仅在您要执行的任务不是正确的服务器操作要求时才有用。启动异步任务以监视某些更改是一个很好的例子。
但是,如果您的服务器在任务完成之前处于“未就绪”状态,则最好实施SmartInitializingSingleton
,因为您将在 REST端口之前获得回调已打开,您的服务器已开放营业。
不要试图将@PostConstruct
用于只应该发生过一次的任务。当你注意到它被多次调用时,你会得到一个粗鲁的惊喜......
答案 7 :(得分:11)
在春天使用SmartInitializingSingleton
bean&gt; 4.1
@Bean
public SmartInitializingSingleton importProcessor() {
return () -> {
doStuff();
};
}
作为替代方案,可以使用CommandLineRunner
实现@PostConstruct
bean或使用{{1}}注释bean方法。
答案 8 :(得分:4)
为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));
}
}
答案 9 :(得分:3)
尝试这一操作,它将在应用程序上下文完全启动后运行您的代码。
@Component
public class OnStartServer implements ApplicationListener<ContextRefreshedEvent> {
@Override
public void onApplicationEvent(ContextRefreshedEvent arg0) {
// EXECUTE YOUR CODE HERE
}
}
答案 10 :(得分:2)
只需为Spring Boot应用程序实现CommandLineRunner。 您需要实现run方法,
public classs SpringBootApplication implements CommandLineRunner{
@Override
public void run(String... arg0) throws Exception {
// write your logic here
}
}
答案 11 :(得分:2)
Spring Boot应用程序启动后执行代码块的最佳方法是使用PostConstruct批注。或者,也可以使用命令行运行器。
1。使用PostConstruct批注
@Configuration
public class InitialDataConfiguration {
@PostConstruct
public void postConstruct() {
System.out.println("Started after Spring boot application !");
}
}
2。使用命令行流道bean
@Configuration
public class InitialDataConfiguration {
@Bean
CommandLineRunner runner() {
return args -> {
System.out.println("CommandLineRunner running in the UnsplashApplication class...");
};
}
}
答案 12 :(得分:0)
我非常喜欢@cahen(https://stackoverflow.com/a/44923402/9122660)使用@EventListener
fun doSomethingAfterStartup(event: ApplicationReadyEvent) {
System.out.println("hello world, I have just started up");
}
注释的建议,因为它非常干净。不幸的是,我无法在Spring + Kotlin设置中使用它。对于Kotlin起作用的是将类添加为方法参数:
K.clear_session()
答案 13 :(得分:0)
使用CommandLineRunner或ApplicationRunner的最佳方法 两者之间的唯一区别是run()方法 CommandLineRunner接受字符串数组,ApplicationRunner接受ApplicationArugument。
答案 14 :(得分:0)
您可以使用@Component
\r
答案 15 :(得分:0)
您有多种选择:
使用 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 的 CommandLineRunner
注释对 ApplicationRunner
和 @Order
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
已发布多次。因此,确保检查代码执行是否已经完成。