Guide til at køre logik ved opstart om foråret

1. Introduktion

I denne artikel vil vi fokusere på, hvordan man gør det køre logik ved opstart af en Spring-applikation.

2. Kører logik ved opstart

Kørsel af logik under / efter opstart af Spring-applikationen er et almindeligt scenarie, men en, der forårsager flere problemer.

For at drage fordel af Inverse of Control er vi naturligvis nødt til at give afkald på delvis kontrol over applikationsstrømmen til containeren - det er grunden til, at instantiering, installationslogik ved opstart osv. Har brug for særlig opmærksomhed.

Vi kan ikke bare inkludere vores logik i bønnernes konstruktører eller opkaldsmetoder efter instantiering af ethvert objekt; vi er simpelthen ikke i kontrol under disse processer.

Lad os se på det virkelige eksempel:

@Komponent offentlig klasse InvalidInitExampleBean {@Autowired private Environment env; public InvalidInitExampleBean () {env.getActiveProfiles (); }}

Her forsøger vi at få adgang til en autotråd felt i konstruktøren. Når konstruktøren kaldes, er Spring Bean endnu ikke initialiseret fuldt ud. Dette er problematisk, fordi opkald til endnu ikke initialiserede felter vil naturligvis resultere i NullPointerExceptions.

Foråret giver os et par måder at håndtere denne situation på.

2.1. Det @PostConstruct Kommentar

Javax's @PostConstruct annotation kan bruges til at kommentere en metode, der skal køres en gang straks efter bønnens initialisering. Husk, at den annoterede metode udføres af Spring, selvom der ikke er noget at injicere.

Her er @PostConstruct i aktion:

@Komponent offentlig klasse PostConstructExampleBean {privat statisk endelig Logger LOG = Logger.getLogger (PostConstructExampleBean.class); @Autowired privat miljø miljø; @PostConstruct offentlig ugyldig init () {LOG.info (Arrays.asList (miljø.getDefaultProfiles ())); }}

I eksemplet ovenfor kan du se, at Miljø tilfælde blev sikkert injiceret og derefter kaldt i @PostConstruct kommenteret metode uden at kaste en NullPointerException.

2.2. Det InitialisererBønne Interface

Det InitialisererBønne tilgang fungerer stort set på samme måde som den foregående. I stedet for at kommentere en metode skal du implementere InitialisererBønne interface og afterPropertiesSet () metode.

Her kan du se det foregående eksempel implementeret ved hjælp af InitialisererBønne grænseflade:

@Komponent offentlig klasse InitializingBeanExampleBean implementerer InitializingBean {privat statisk endelig Logger LOG = Logger.getLogger (InitializingBeanExampleBean.class); @Autowired privat miljø miljø; @ Overstyr offentlig ugyldighed efterPropertiesSet () kaster undtagelse {LOG.info (Arrays.asList (environment.getDefaultProfiles ())); }}

2.3. En ApplicationListener

Denne tilgang kan bruges til kører logik efter forårssammenhæng er initialiseret, så vi fokuserer ikke på nogen bestemt bønne, men venter på, at de alle initialiseres.

For at opnå dette skal du oprette en bønne, der implementerer ApplicationListener grænseflade:

@Komponent offentlig klasse StartupApplicationListenerExample implementerer ApplicationListener {privat statisk endelig Logger LOG = Logger.getLogger (StartupApplicationListenerExample.class); offentlig statisk tæller; @ Overstyr offentlig ugyldighed påApplicationEvent (ContextRefreshedEvent event) {LOG.info ("Increment counter"); tæller ++; }} 

De samme resultater kan opnås ved hjælp af den nyindførte @EventListener kommentar:

@Komponent offentlig klasse EventListenerExampleBean {privat statisk endelig Logger LOG = Logger.getLogger (EventListenerExampleBean.class); offentlig statisk tæller; @EventListener offentligt ugyldigt påApplicationEvent (ContextRefreshedEvent event) {LOG.info ("Increment counter"); tæller ++; }}

I dette eksempel valgte vi ContextRefreshedEvent. Sørg for at vælge en passende begivenhed, der passer til dine behov.

2.4. Det @Bønne Initmetode Attribut

Det initMethod egenskab kan bruges til at udføre en metode efter initialisering af en bønne.

Sådan ser en bønne ud:

offentlig klasse InitMethodExampleBean {privat statisk endelig Logger LOG = Logger.getLogger (InitMethodExampleBean.class); @Autowired privat miljø miljø; offentlig ugyldig init () {LOG.info (Arrays.asList (environment.getDefaultProfiles ())); }}

Du kan bemærke, at der ikke er implementeret nogen specielle grænseflader eller nogen specielle kommentarer.

Derefter kan vi definere bønnen ved hjælp af @Bønne kommentar:

@Bean (initMethod = "init") offentlig InitMethodExampleBean initMethodExampleBean () {returner ny InitMethodExampleBean (); }

Og sådan ser en bønnedefinition ud i en XML-konfiguration:

2.5. Konstruktørinjektion

Hvis du indsprøjter felter ved hjælp af Constructor Injection, kan du blot inkludere din logik i en konstruktør:

@Komponent offentlig klasse LogicInConstructorExampleBean {privat statisk endelig Logger LOG = Logger.getLogger (LogicInConstructorExampleBean.class); privat endeligt miljømiljø; @Autowired offentlig LogicInConstructorExampleBean (miljømiljø) {dette.miljø = miljø; LOG.info (Arrays.asList (miljø.getDefaultProfiles ())); }}

2.6. Spring Boot CommandLineRunner

Fjedersko giver en CommandLineRunner interface med et tilbagekald løb() metode, der kan påberåbes ved opstart af applikationen, efter at Spring-applikationskonteksten er instantificeret.

Lad os se på et eksempel:

@Komponent offentlig klasse CommandLineAppStartupRunner implementerer CommandLineRunner {privat statisk endelig Logger LOG = LoggerFactory.getLogger (CommandLineAppStartupRunner.class); offentlig statisk tæller; @ Override offentlig ugyldig kørsel (String ... args) kaster undtagelse {LOG.info ("Increment counter"); tæller ++; }}

Bemærk: Som nævnt i dokumentationen, flere CommandLineRunner bønner kan defineres inden for samme applikationskontekst og kan bestilles ved hjælp af @Bestilt interface eller @Bestille kommentar.

2.7. Spring Boot ApplicationRunner

Svarende til CommandLineRunner, Spring boot giver også en ApplicationRunner interface til en løb() metode, der skal påberåbes ved opstart af applikationen. Imidlertid i stedet for rå Snor argumenter, der sendes til tilbagekaldsmetoden, har vi en forekomst af ApplicationArguments klasse.

Det ApplicationArguments interface har metoder til at få argumentværdier, der er valgmuligheder og almindelige argumentværdier. Et argument, der er forud for - - er et valgargument.

Lad os se på et eksempel:

@Komponent offentlig klasse AppStartupRunner implementerer ApplicationRunner {privat statisk endelig Logger LOG = LoggerFactory.getLogger (AppStartupRunner.class); offentlig statisk tæller; @Override public void run (ApplicationArguments args) kaster undtagelse {LOG.info ("Application started with option names: {}", args.getOptionNames ()); LOG.info ("Increment counter"); tæller ++; }}

3. Kombination af mekanismer

For at opnå fuld kontrol over dine bønner, kan du kombinere ovenstående mekanismer sammen.

Ordren med henrettelse er som følger:

  1. Konstruktøren
  2. det @PostConstruct annoterede metoder
  3. initialiseringsbønnerne afterPropertiesSet () metode
  4. initialiseringsmetoden specificeret som init-metode i XML

Lad os oprette en springbønne, der kombinerer alle mekanismer:

@Component @Scope (værdi = "prototype") offentlig klasse AllStrategiesExampleBean implementerer InitializingBean {privat statisk endelig Logger LOG = Logger.getLogger (AllStrategiesExampleBean.class); offentlige AllStrategiesExampleBean () {LOG.info ("Konstruktør"); } @ Override offentlig ugyldighed efterPropertiesSet () kaster undtagelse {LOG.info ("InitializingBean"); } @ PostConstruct offentlig ugyldig postConstruct () {LOG.info ("PostConstruct"); } offentlig ugyldig init () {LOG.info ("init-metode"); }}

Hvis du forsøger at instantiere denne bønne, kan du se logfiler, der matcher rækkefølgen angivet ovenfor:

[main] INFO o.b.startup.AllStrategiesExampleBean - Konstruktør [main] INFO o.b.startup.AllStrategiesExampleBean - PostConstruct [main] INFO o.b.startup.AllStrategiesExampleBean - InitializingBean [main] INFO o.b.startup.AllStrateg

4. Konklusion

I denne artikel illustrerede vi flere måder at udføre logik på Spring's applikationsstart.

Kodeprøver kan findes på GitHub.


$config[zx-auto] not found$config[zx-overlay] not found