wake-up-neo.net

Laufender Code nach dem Start von Spring Boot

Ich möchte Code ausführen, nachdem meine spring-boot app ein Verzeichnis auf Änderungen überwacht. 

Ich habe versucht, einen neuen Thread auszuführen, aber die @Autowired-Dienste wurden zu diesem Zeitpunkt noch nicht festgelegt.

Ich konnte ApplicationPreparedEvent finden, das ausgelöst wird, bevor die @Autowired-Annotationen gesetzt werden. Im Idealfall möchte ich, dass das Ereignis ausgelöst wird, sobald die Anwendung zur Verarbeitung von http-Anforderungen bereit ist.

Gibt es ein besseres Ereignis oder eine bessere Möglichkeit, Code auszuführen, nachdem die Anwendung in spring-boot live ist?

118
stewsters

Versuchen:

@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
    }
}
79
Anton Bessonov

So einfach ist das: 

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

Getestet auf Version 1.5.1.RELEASE

165
cahen

Haben Sie ApplicationReadyEvent ausprobiert? 

@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 von: http://blog.netgloo.com/2014/11/13/run-code-at-spring-boot-startup/

Dies ist, was die Dokumentation über die Startereignisse erwähnt:

...

Anwendungsereignisse werden in der folgenden Reihenfolge gesendet, wenn Ihre Anwendung ausgeführt wird:

Ein ApplicationStartedEvent wird zu Beginn eines Laufs gesendet, jedoch vor jegliche Verarbeitung mit Ausnahme der Registrierung von Hörern und Initialisierern.

Ein ApplicationEnvironmentPreparedEvent wird gesendet, wenn die im Kontext zu verwendende Umgebung bekannt ist, jedoch vor dem Kontext geschaffen.

Ein ApplicationPreparedEvent wird direkt vor dem Start der Aktualisierung gesendet, aber nachdem Bean-Definitionen geladen wurden.

Nach der Aktualisierung wird ein ApplicationReadyEvent gesendet, und alle zugehörigen Rückrufe wurden verarbeitet, um anzuzeigen, dass die Anwendung für .__ bereit ist. Serviceanfragen.

Ein ApplicationFailedEvent wird gesendet, wenn beim Start eine Ausnahme vorliegt.

...

76
raspacorp

Warum erstellen Sie nicht einfach eine Bean, die Ihren Monitor bei der Initialisierung startet, etwa:

@Component
public class Monitor {
    @Autowired private SomeService service

    @PostConstruct
    public void init(){
        // start your monitoring in here
    }
}

die init-Methode wird erst aufgerufen, wenn für das Bean Autowiring ausgeführt wird.

76
cjstehno

Die "Spring Boot" Methode ist die Verwendung einer CommandLineRunner. Fügen Sie einfach Bohnen dieses Typs hinzu und schon können Sie loslegen. In Spring 4.1 (Boot 1.2) gibt es auch eine SmartInitializingBean, die einen Callback erhält, nachdem alles initialisiert wurde. Und es gibt SmartLifecycle (ab Spring 3).

57
Dave Syer

Sie können eine Klasse mit ApplicationRunner erweitern, die run()-Methode überschreiben und den Code dort hinzufügen. 

import org.springframework.boot.ApplicationRunner;

@Component
public class ServerInitializer implements ApplicationRunner {

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

        //code goes here

    }
}
29
Gimhani

ApplicationReadyEvent ist wirklich nur nützlich, wenn die Aufgabe, die Sie ausführen möchten, keine Voraussetzung für den korrekten Serverbetrieb ist. Das Starten einer asynchronen Task zur Überwachung von Änderungen ist ein gutes Beispiel.

Wenn sich Ihr Server jedoch nicht im Status 'nicht bereit' befindet, bis die Task abgeschlossen ist, sollten Sie SmartInitializingSingleton implementieren, da Sie den Rückruf erhalten, bevor Ihr REST - Port geöffnet wurde und Ihr Server ist offen für das geschäft.

Seien Sie nicht versucht, @PostConstruct für Aufgaben zu verwenden, die nur einmal vorkommen sollten. Sie werden eine unhöfliche Überraschung erleben, wenn Sie feststellen, dass es mehrmals aufgerufen wird ...

15
Andy Brown

Mit Federkonfiguration:

@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");
  }
}
15
freemanpolys

Verwenden Sie im Frühjahr eine SmartInitializingSingleton-Bohne> 4.1

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

}

Alternativ kann eine CommandLineRunner-Bean implementiert oder eine Bean-Methode mit @PostConstruct kommentiert werden.

9
Jeff

Ein Beispiel für die Antwort von Dave Syer, die wie ein Zauber wirkt:

@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));
    }
}
3
Paulo Pedroso

implementieren Sie einfach CommandLineRunner für die Spring-Boot-Anwendung .

public classs SpringBootApplication implements CommandLineRunner{

    @Override
        public void run(String... arg0) throws Exception {
        // write your logic here 

        }
}
1
prasad kp

Probieren Sie es aus und es wird Ihr Code ausgeführt, wenn der Anwendungskontext vollständig gestartet wurde.

 @Component
public class OnStartServer implements ApplicationListener<ContextRefreshedEvent> {

    @Override
    public void onApplicationEvent(ContextRefreshedEvent arg0) {
                // EXECUTE YOUR CODE HERE 
    }
}
1
Kalifornium

Die beste Möglichkeit, einen Codeblock auszuführen, nachdem die Spring Boot-Anwendung gestartet wurde, ist die Verwendung von PostConstruct-Annotation. Sie können auch den Befehlszeilen-Runner verwenden.

1. Verwenden der PostConstruct-Annotation

@Configuration
public class InitialDataConfiguration {

    @PostConstruct
    public void postConstruct() {
        System.out.println("Started after Spring boot application !");
    }

}

2. Verwenden von Command Line Runner Bean

@Configuration
public class InitialDataConfiguration {

    @Bean
    CommandLineRunner runner() {
        return args -> {
            System.out.println("CommandLineRunner running in the UnsplashApplication class...");
        };
    }
}
0
Naresh

Mir gefällt der Vorschlag zur Verwendung der EventListener-Annotation von @cahen ( https://stackoverflow.com/a/44923402/9122660 ) sehr gut, da sie sehr sauber ist. Leider konnte ich dies in einem Spring + Kotlin-Setup nicht zum Laufen bringen. Was für Kotlin funktioniert, ist das Hinzufügen der Klasse als Methodenparameter:

@EventListener 
fun doSomethingAfterStartup(event: ApplicationReadyEvent) {
    System.out.println("hello world, I have just started up");
}
0
Ostecke