Java Spring Boot 启动后运行代码
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/27405713/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Running code after Spring Boot starts
提问by stewsters
I want to run code after my spring-bootapp starts to monitor a directory for changes.
我想在我的spring-boot应用程序开始监视目录更改后运行代码。
I have tried running a new thread but the @Autowired
services have not been set at that point.
我曾尝试运行一个新线程,但此时@Autowired
尚未设置服务。
I have been able to find ApplicationPreparedEvent
, which fires before the @Autowired
annotations are set. Ideally I would like the event to fire once the application is ready to process http requests.
我已经能够找到ApplicationPreparedEvent
, 在设置@Autowired
注释之前触发。理想情况下,我希望在应用程序准备好处理 http 请求后触发该事件。
Is there a better event to use, or a better way of running code after the application is live in spring-boot?
是否有更好的事件可以使用,或者在应用程序在spring-boot中运行后运行代码的更好方法?
采纳答案by Anton Bessonov
Try:
尝试:
@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
}
}
回答by cjstehno
Why not just create a bean that starts your monitor on initialization, something like:
为什么不创建一个在初始化时启动监视器的 bean,例如:
@Component
public class Monitor {
@Autowired private SomeService service
@PostConstruct
public void init(){
// start your monitoring in here
}
}
the init
method will not be called until any autowiring is done for the bean.
在init
为 bean 完成任何自动装配之前,不会调用该方法。
回答by Dave Syer
The "Spring Boot" way is to use a CommandLineRunner
. Just add beans of that type and you are good to go. In Spring 4.1 (Boot 1.2) there is also a SmartInitializingBean
which gets a callback after everything has initialized. And there is SmartLifecycle
(from Spring 3).
“Spring Boot”方式是使用CommandLineRunner
. 只需添加那种类型的豆子,你就可以开始了。在 Spring 4.1 (Boot 1.2) 中,还有SmartInitializingBean
一个在一切都初始化后得到回调。还有SmartLifecycle
(从 Spring 3 开始)。
回答by raspacorp
Have you tried ApplicationReadyEvent?
您是否尝试过 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;
}
}
Code from: http://blog.netgloo.com/2014/11/13/run-code-at-spring-boot-startup/
代码来自:http: //blog.netgloo.com/2014/11/13/run-code-at-spring-boot-startup/
This is what the documentationmentions about the startup events:
这是文档中提到的有关启动事件的内容:
...
Application events are sent in the following order, as your application runs:
An ApplicationStartedEvent is sent at the start of a run, but before any processing except the registration of listeners and initializers.
An ApplicationEnvironmentPreparedEvent is sent when the Environment to be used in the context is known, but before the context is created.
An ApplicationPreparedEvent is sent just before the refresh is started, but after bean definitions have been loaded.
An ApplicationReadyEvent is sent after the refresh and any related callbacks have been processed to indicate the application is ready to service requests.
An ApplicationFailedEvent is sent if there is an exception on startup.
...
...
当您的应用程序运行时,应用程序事件按以下顺序发送:
ApplicationStartedEvent 在运行开始时发送,但在除注册侦听器和初始化程序之外的任何处理之前发送。
当要在上下文中使用的环境已知时,但在创建上下文之前,将发送 ApplicationEnvironmentPreparedEvent。
ApplicationPreparedEvent 在刷新开始之前发送,但在 bean 定义加载之后。
刷新后发送 ApplicationReadyEvent 并且处理任何相关的回调以指示应用程序已准备好为请求提供服务。
如果启动时出现异常,则发送 ApplicationFailedEvent。
...
回答by Gimhani
You can extend a class using ApplicationRunner
, override the run()
method and add the code there.
您可以使用 扩展类ApplicationRunner
,覆盖该run()
方法并在那里添加代码。
import org.springframework.boot.ApplicationRunner;
@Component
public class ServerInitializer implements ApplicationRunner {
@Override
public void run(ApplicationArguments applicationArguments) throws Exception {
//code goes here
}
}
回答by Paulo Pedroso
Providing an example for Dave Syer answer, which worked like a charm:
为 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));
}
}
回答by Jeff
Use a SmartInitializingSingleton
bean in spring > 4.1
SmartInitializingSingleton
在 spring > 4.1 中使用bean
@Bean
public SmartInitializingSingleton importProcessor() {
return () -> {
doStuff();
};
}
As alternative a CommandLineRunner
bean can be implemented or annotating a bean method with @PostConstruct
.
作为替代方案,CommandLineRunner
可以实现 bean 或使用 注释 bean 方法@PostConstruct
。
回答by cahen
It is as simple as this:
就这么简单:
@EventListener(ApplicationReadyEvent.class)
public void doSomethingAfterStartup() {
System.out.println("hello world, I have just started up");
}
Tested on version 1.5.1.RELEASE
在版本上测试 1.5.1.RELEASE
回答by freemanpolys
With spring configuration :
弹簧配置:
@Configuration
public class ProjectConfiguration {
private static final Logger log =
LoggerFactory.getLogger(ProjectConfiguration.class);
@EventListener(ApplicationReadyEvent.class)
public void doSomethingAfterStartup() {
log.info("hello world, I have just started up");
}
}
回答by Andy Brown
ApplicationReadyEvent
is really only useful if the task you want to perform is not a requirement for correct server operation. Starting an async task to monitor something for changes is a good example.
ApplicationReadyEvent
只有当您要执行的任务不是正确服务器操作的要求时,才真正有用。启动异步任务来监视某些更改是一个很好的例子。
If, however your server is in a 'not ready' state until the task is completed then it's better to implement SmartInitializingSingleton
because you'll get the callback beforeyour REST port has been opened and your server is open for business.
但是,如果您的服务器在任务完成之前处于“未准备好”状态,那么最好实施,SmartInitializingSingleton
因为您将在REST 端口打开并且您的服务器开始营业之前收到回调。
Don't be tempted to use @PostConstruct
for tasks that should only happen once ever. You'll get a rude surprise when you notice it being called multiple times...
不要试图@PostConstruct
用于只应该发生一次的任务。当你注意到它被多次调用时,你会得到一个粗鲁的惊喜......