Vodič za pokretanje logike pri pokretanju u proljeće

1. Uvod

U ovom ćemo se članku usredotočiti na to kako pokrenuti logiku pri pokretanju Spring aplikacije.

2. Pokretanje logike pri pokretanju

Pokretanje logike tijekom / nakon pokretanja aplikacije Spring je uobičajeni scenarij, ali onaj koji uzrokuje višestruke probleme.

Da bismo imali koristi od Inverse of Control, moramo se prirodno odreći djelomične kontrole nad protokom aplikacije u spremnik - zbog čega instanciranje, logika postavljanja pri pokretanju itd. Trebaju posebnu pažnju.

Ne možemo jednostavno uključiti našu logiku u konstruktore graha ili metode poziva nakon instanciranja bilo kojeg objekta; mi jednostavno nemamo kontrolu tijekom tih procesa.

Pogledajmo primjer iz stvarnog života:

@Component javna klasa InvalidInitExampleBean {@Autowired private Environment env; javni InvalidInitExampleBean () {env.getActiveProfiles (); }}

Ovdje pokušavamo pristupiti automatski ožičen polje u konstruktoru. Kada se pozove konstruktor, grah Spring još nije u potpunosti inicijaliziran. To je problematično jer pozivanje još neinicijaliziranih polja naravno će rezultirati NullPointerExceptions.

Proljeće nam daje nekoliko načina za upravljanje ovom situacijom.

2.1. The @PostConstruct Bilješka

Javaxova @PostConstruct anotacija se može koristiti za bilježenje metode koju treba pokrenuti jednom odmah nakon inicijalizacije graha. Imajte na umu da će se anotirana metoda izvršiti do proljeća čak i ako nema što ubrizgati.

Evo @PostConstruct u akciji:

@Component javna klasa PostConstructExampleBean {privatni statički konačni LOGER LOG = Logger.getLogger (PostConstructExampleBean.class); @Autowired privatno okruženje okoliša; @PostConstruct javni void init () {LOG.info (Arrays.asList (environment.getDefaultProfiles ())); }}

U gornjem primjeru možete vidjeti da Okoliš primjer je sigurno ubrizgan, a zatim pozvan u @PostConstruct anotirana metoda bez bacanja a NullPointerException.

2.2. The InitializingBean Sučelje

The InitializingBean pristup djeluje prilično slično prethodnom. Umjesto bilježenja metode, morate implementirati InitializingBean sučelje i afterPropertiesSet () metoda.

Ovdje možete vidjeti prethodni primjer implementiran pomoću InitializingBean sučelje:

@Component javna klasa InitializingBeanExampleBean implementira InitializingBean {private static final Logger LOG = Logger.getLogger (InitializingBeanExampleBean.class); @Autowired privatno okruženje okoliša; @Override public void afterPropertiesSet () baca izuzetak {LOG.info (Arrays.asList (environment.getDefaultProfiles ())); }}

2.3. An ApplicationListener

Ovaj se pristup može koristiti za pokretanje logike nakon što je inicijaliziran kontekst Spring, tako da se ne fokusiramo na bilo koji grah, već čekamo da se svi inicijaliziraju.

Da biste to postigli morate stvoriti grah koji implementira ApplicationListener sučelje:

@Component javna klasa StartupApplicationListenerExample implementira ApplicationListener {private static final Logger LOG = Logger.getLogger (StartupApplicationListenerExample.class); javni statički brojač int; @Override public void onApplicationEvent (ContextRefreshedEvent event) {LOG.info ("Brojač povećanja"); brojač ++; }} 

Isti se rezultati mogu postići korištenjem novo predstavljenog @EventListener napomena:

@Component javna klasa EventListenerExampleBean {private static final Logger LOG = Logger.getLogger (EventListenerExampleBean.class); javni statički int brojač; @EventListener javna praznina onApplicationEvent (događaj ContextRefreshedEvent) {LOG.info ("Brojač povećanja"); brojač ++; }}

U ovom smo primjeru odabrali ContextRefreshedEvent. Svakako odaberite odgovarajući događaj koji odgovara vašim potrebama.

2.4. The @Grah Atribut Initmethod

The initMethod svojstvo se može koristiti za izvršavanje metode nakon inicijalizacije graha.

Evo kako grah izgleda:

javna klasa InitMethodExampleBean {privatni statički konačni zapisnik LOG = Logger.getLogger (InitMethodExampleBean.class); @Autowired privatno okruženje okoliša; javna void init () {LOG.info (Arrays.asList (environment.getDefaultProfiles ())); }}

Možete primijetiti da nisu implementirana posebna sučelja niti su korištene posebne napomene.

Zatim grah možemo definirati pomoću @Grah napomena:

@Bean (initMethod = "init") public InitMethodExampleBean initMethodExampleBean () {return new InitMethodExampleBean (); }

A ovako izgleda definicija graha u XML konfiguraciji:

2.5. Injektiranje konstruktora

Ako ubrizgavate polja pomoću Constructor Injection, možete jednostavno uključiti svoju logiku u konstruktor:

@Component javna klasa LogicInConstructorExampleBean {private static final Logger LOG = Logger.getLogger (LogicInConstructorExampleBean.class); privatno konačno okolišno okruženje; @Autowired javni LogicInConstructorExampleBean (Okoliš okoliša) {this.environment = okruženje; LOG.info (Arrays.asList (environment.getDefaultProfiles ())); }}

2.6. Proljetni čizme CommandLineRunner

Proljetna čizma pruža a CommandLineRunner sučelje s povratnim pozivom trčanje() metoda koja se može pozvati pri pokretanju aplikacije nakon instanciranja konteksta aplikacije Spring.

Pogledajmo primjer:

@Component javna klasa CommandLineAppStartupRunner implementira CommandLineRunner {private static final Logger LOG = LoggerFactory.getLogger (CommandLineAppStartupRunner.class); javni statički int brojač; @ Override public void run (String ... args) baca iznimku {LOG.info ("Brojač povećanja"); brojač ++; }}

Bilješka: Kao što je spomenuto u dokumentaciji, višestruko CommandLineRunner grah se može definirati u istom kontekstu aplikacije i može se naručiti pomoću @ Naručeno sučelje ili @Narudžba bilješka.

2.7. Proljetni čizme ApplicationRunner

Slično CommandLineRunner, Proljetna čizma također nudi ApplicationRunner sučelje s a trčanje() metoda koja se poziva pri pokretanju aplikacije. Međutim, umjesto sirovog Niz argumenti prosljeđeni metodi povratnog poziva, imamo primjerak Argumenti primjene razred.

The Argumenti primjene sučelje ima metode za dobivanje vrijednosti argumenata koje su opcije i obične vrijednosti argumenata. Argument koji ima prefiks - - argument je opcije.

Pogledajmo primjer:

@Component javna klasa AppStartupRunner implementira ApplicationRunner {private static final Logger LOG = LoggerFactory.getLogger (AppStartupRunner.class); javni statički int brojač; @Override public void run (ApplicationArguments args) baca iznimku {LOG.info ("Aplikacija je započeta s imenima opcija: {}", args.getOptionNames ()); LOG.info ("Brojač prirasta"); brojač ++; }}

3. Kombinirajući mehanizmi

Da biste postigli potpunu kontrolu nad svojim grahom, možda biste željeli kombinirati gore navedene mehanizme.

Redoslijed izvršenja je sljedeći:

  1. Konstruktor
  2. the @PostConstruct anotirane metode
  3. InitializingBean's afterPropertiesSet () metoda
  4. metoda inicijalizacije navedena kao init-metoda u XML-u

Stvorimo proljetni grah koji kombinira sve mehanizme:

@Component @Scope (value = "prototype") javna klasa AllStrategiesExampleBean implementira InitializingBean {private static final Logger LOG = Logger.getLogger (AllStrategiesExampleBean.class); public AllStrategiesExampleBean () {LOG.info ("Konstruktor"); } @Override public void afterPropertiesSet () baca iznimku {LOG.info ("InitializingBean"); } @PostConstruct javna void postConstruct () {LOG.info ("PostConstruct"); } javna void init () {LOG.info ("init-metoda"); }}

Ako pokušate instancirati ovaj grah, moći ćete vidjeti zapisnike koji odgovaraju gore navedenom redoslijedu:

[main] INFO o.b.startup.AllStrategiesExampleBean - Konstruktor [main] INFO o.b.startup.AllStrategiesExampleBean - PostConstruct [main] INFO o.b.startup.AllStrategiesExampleBean - InitializingBeanES.instartBeanBeanBean.installingBeanAb.installingBean.in.startBean.in.startBean.

4. Zaključak

U ovom smo članku ilustrirali više načina izvršavanja logike pri pokretanju Springove aplikacije.

Uzorci koda mogu se naći na GitHubu.