我想在spring-boot应用程序开始监视目录更改之后运行代码。
我已经尝试运行一个新线程,但@Autowired服务还没有设置在那一点。
我已经能够找到ApplicationPreparedEvent,它在@Autowired注释设置之前触发。理想情况下,我希望事件在应用程序准备好处理http请求时触发。
是否有更好的事件可以使用,或者在应用程序在spring-boot中激活后运行代码的更好方法?
我想在spring-boot应用程序开始监视目录更改之后运行代码。
我已经尝试运行一个新线程,但@Autowired服务还没有设置在那一点。
我已经能够找到ApplicationPreparedEvent,它在@Autowired注释设置之前触发。理想情况下,我希望事件在应用程序准备好处理http请求时触发。
是否有更好的事件可以使用,或者在应用程序在spring-boot中激活后运行代码的更好方法?
当前回答
你可以使用@Component
@RequiredArgsConstructor
@Component
@Slf4j
public class BeerLoader implements CommandLineRunner {
//declare
@Override
public void run(String... args) throws Exception {
//some code here
}
其他回答
你有几个选择:
使用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被发布了几次。因此,确保检查代码执行是否已经完成。
Spring引导提供了一个带有run()方法的ApplicationRunner接口,在应用程序启动时调用该方法。 但是,我们有一个ApplicationArguments类的实例,而不是传递给回调方法的原始String参数。
@Component
public class AppStartupRunner implements ApplicationRunner {
@Override
public void run(ApplicationArguments args) throws Exception {
//some logic here
}
}
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
}
}
如果你的意思是在应用程序启动后运行一次peace of code,你可以如下所示使用CommandLineRunner:
@SpringBootApplication
public class SpringBootApplication
implements CommandLineRunner {
private static Logger LOG = LoggerFactory
.getLogger(SpringBootConsoleApplication.class);
public static void main(String[] args) {
LOG.info("STARTING THE APPLICATION");
SpringApplication.run(SpringBootConsoleApplication.class, args);
LOG.info("APPLICATION FINISHED");
}
@Override
public void run(String... args) {
// enter code you want to run after app loaded here
LOG.info("EXECUTING : command line runner");
for (int i = 0; i < args.length; ++i) {
LOG.info("args[{}]: {}", i, args[i]);
}
}
}
否则,您可以使用DevTools依赖项,它可以帮助您在不手动重新启动应用程序的情况下运行新代码。
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
</dependencies>
不要忘记将这些代码添加到pom.xml中,以避免版本警告:
<properties>
<java.version>17</java.version>
<spring-cloud.version>2021.0.3</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
如果这对你有帮助,给它一个重击!
为什么不创建一个bean,在初始化时启动监视器呢?
@Component
public class Monitor {
@Autowired private SomeService service
@PostConstruct
public void init(){
// start your monitoring in here
}
}
在为bean完成任何自动装配之前,不会调用init方法。