首页 文章

Spring Boot启动后运行代码

提问于
浏览
106

我想在我的 spring-boot 应用程序开始监视目录以进行更改后运行代码 .

我尝试过运行一个新线程,但此时尚未设置 @Autowired 服务 .

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

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

12 回答

  • 71

    在spring> 4.1中使用 SmartInitializingSingleton bean

    @Bean
    public SmartInitializingSingleton importProcessor() {
        return () -> {
            doStuff();
        };
    
    }
    

    作为替代方案,可以使用 @PostConstruct 实现 CommandLineRunner bean或使用 @PostConstruct 注释bean方法 .

  • 53

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

    尝试这个,它将在应用程序上下文完全启动时运行您的代码 .

    @Component
    public class OnStartServer implements ApplicationListener<ContextRefreshedEvent> {
    
        @Override
        public void onApplicationEvent(ContextRefreshedEvent arg0) {
                    // EXECUTE YOUR CODE HERE 
        }
    }
    
  • 2

    这很简单:

    @EventListener(ApplicationReadyEvent.class)
    public void doSomethingAfterStartup() {
        System.out.println("hello world, I have just started up");
    }
    

    测试版 1.5.1.RELEASE

  • 13

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

    import org.springframework.boot.ApplicationRunner;
    
    @Component
    public class ServerInitializer implements ApplicationRunner {
    
        @Override
        public void run(ApplicationArguments applicationArguments) throws Exception {
    
            //code goes here
    
        }
    }
    
  • 11

    只需为Spring启动应用程序实现CommandLineRunner . 你需要实现run方法,

    public classs SpringBootApplication implements CommandLineRunner{
    
        @Override
            public void run(String... arg0) throws Exception {
            // write your logic here 
    
            }
    }
    
  • 135

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

  • 67

    ApplicationReadyEvent 仅在您要执行的任务不是正确的服务器操作要求时才有用 . 启动异步任务以监视某些更改是一个很好的例子 .

    但是,如果您的服务器处于'not ready'状态,直到任务完成,那么最好实现 SmartInitializingSingleton ,因为您将在REST端口打开并且服务器开放营业之前获得回调 .

    不要试图将 @PostConstruct 用于只应该发生过一次的任务 . 当你注意到它被多次调用时,你会得到一个粗鲁的惊喜......

  • 0

    配 spring 配置:

    @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");
      }
    }
    
  • 26

    为什么不创建一个在初始化时启动监视器的bean,例如:

    @Component
    public class Monitor {
        @Autowired private SomeService service
    
        @PostConstruct
        public void init(){
            // start your monitoring in here
        }
    }
    

    在为bean完成任何自动装配之前,不会调用 init 方法 .

  • 8

    尝试:

    @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
        }
    }
    
  • 0

    "Spring Boot"方式是使用 CommandLineRunner . 只需添加那种类型的 beans 子就可以了 . 在Spring 4.1(Boot 1.2)中,还有一个 SmartInitializingBean ,在所有内容初始化后都会收到回调 . 并且有 SmartLifecycle (从 Spring 季开始) .

相关问题