我想在spring-boot应用程序开始监视目录更改之后运行代码。

我已经尝试运行一个新线程,但@Autowired服务还没有设置在那一点。

我已经能够找到ApplicationPreparedEvent,它在@Autowired注释设置之前触发。理想情况下,我希望事件在应用程序准备好处理http请求时触发。

是否有更好的事件可以使用,或者在应用程序在spring-boot中激活后运行代码的更好方法?


当前回答

我非常喜欢@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");
}

其他回答

如果你的意思是在应用程序启动后运行一次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>

如果这对你有帮助,给它一个重击!

您可以使用ApplicationRunner扩展类,重写run()方法并在那里添加代码。

import org.springframework.boot.ApplicationRunner;

@Component
public class ServerInitializer implements ApplicationRunner {

    @Override
    public void run(ApplicationArguments applicationArguments) throws Exception {

        //code goes here

    }
}

“Spring Boot”方式是使用CommandLineRunner。只需添加该类型的bean,就可以了。在Spring 4.1 (Boot 1.2)中,也有一个SmartInitializingBean,它在所有东西初始化后得到一个回调。还有SmartLifecycle(来自Spring 3)。

我非常喜欢@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");
}

你试过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/

下面是文档中提到的启动事件:

... 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. ...