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

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

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

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


当前回答

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

其他回答

为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));
    }
}

你可以使用@Component

@RequiredArgsConstructor
@Component
@Slf4j
public class BeerLoader implements CommandLineRunner {
    //declare 

    @Override
    public void run(String... args) throws Exception {
        //some code here 

    }

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

你有几个选择:

使用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 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...");
        };
    }
}