2017-08-18 17 views
5

Uygulamam başladığında fasulyeleri ilkbahar bağlamında başlatmalıyım; Şu anda, böyle açıklama @Configuration ile bir sınıfta fasulye başlatmak:Uygulama başladıktan sonra fasulyeleri Bahar bağlamında başlatmanın en iyi yolu?

@Configuration 
public class AppConfig { 
    @Inject 
    @Bean 
    public BeanA init(param1, param2, etc...) { 
     --- Code to construct bean A --- 
    } 

    @Inject 
    @Bean 
    public BeanB init(param1, param2, etc...) { 
     --- Code to construct bean B --- 
    } 
} 

Ancak bazı fasulye ben uygulama başlangıcından sonra başlatmak gerekir böylece yaklaşımım bir sınıf ApplicationReadyEvent olay içinde dinlemek oluşturmaktır Bahar ve bu sınıfta fasulye başlatmak için kodu koydu.

@Configuration 
class ApplicationStartingListener implements ApplicationListener<ApplicationReadyEvent>{ 
    ---- Code to init bean here ---- 

    @Override 
    public void onApplicationEvent(ApplicationReadyEvent event) { 
     --- If I put init bean code in here, is it correct? ---- 
    } 
} 

Bu en iyi yol mu? Ya da başka bazı daha iyi çözümler var?

+0

@PostConstruct ile Dene –

+0

@DanielC. PostConstruct ek açıklaması eklediğimde bu hatayı aldım: java.lang.IllegalStateException: Lifecycle yöntemi notu, no-arg yöntemini gerektirir: –

+0

İstediğiniz sonuçları elde etmenize yardımcı olan bazı bağlantılar vardır. Umarım yardımcı olur. [link1] (http://learningviacode.blogspot.com/2012/07/spring-and-events-and-listeners.html) [bağlantı2] (http://www.naturalprogrammer.com/run-code-spring- boot-application-startup /) [link3] (https://stackoverflow.com/questions/38206676/contextstartedevent-not-broadcasted-on-spring-boot) – Tehmina

cevap

3

Fasulyeleri inmek için diğer yaklaşımları sıralayacağım, yaklaşımı Standart Yaklaşım ve Bahar Önyükleme Yaklaşımında gruplandırdım.

Standart Yaklaşım

  1. @PostConstruct: sadece fasulye o giriş parametrelerini izin vermez oluşturmak sonra bir yöntemi tetikleyen bir açıklama olduğunu.
  2. @Bean(init-method="somInitMehotd"): Bu yaklaşım tamamen Spring bean yaşam döngüsü ile ilgilidir ve @PostConstruct ek açıklama ile başka bir yöntem kullanıyorsanız, fasulye yaratıldıktan sonra çağrılır, daha sonra @PostConstruct ilk çağrılır. Bu yaklaşım giriş parametrelerine izin vermez.
  3. ApplicationListener: Bu arabirim, İçerik Yaşam Döngüsü ile ilgili standart olayları dinlemenize olanak tanır, ayrıca özelleştirilmiş olayları da dinleyebilir. Örneğin: bir sınıf MyAppListener oluşturmak ve bu durumda ApplicationListener<ContextRefreshedEvent> uygulayan MyAppListener

    1. THÉ ContextRefreshedEvent

    Bahar Boot Yaklaşım alan bir onApplicationEvent yöntemi uygulayacak koşucular: Her ikisi de ApplicationContext oluşturulduktan sonra çalışacak iki çok yararlı arabirim vardır CommandLineRunner ve ApplicationRunner her ikisi de giriş parametreleri olarak fasulye enjekte sağlar.

  4. Yay önyükleme dinleyicileri: Yay Uygulaması, Uygulama Bağlamından gelen standart olaylardan bazı ek olaylar sağlar. Olaylardan biri ApplicationReadyEvent ve uygulama isteği almaya hazır olduğunda yanıyor. Bu olayları dinleyebilmek için, 'u jenerik olarak kullanarak ApplicationListener'u uygulamanız yeterlidir. Burada

örnektir:

MyBean sınıfı yukarıda listelenen her bir yaklaşım için çağrılır farklı yöntem vardır, her yöntem, bir baskı yöntemi arayacak ve bu yöntem doğrulamak amacıyla bir Thread.sleep var Her dinleyicinin çağrıldığı sıra. İşte

import javax.annotation.PostConstruct; 
public class MyBean { 

    private String myVar=""; 

    public MyBean(){ 

    } 

    @PostConstruct 
    public void postConstructInit(){ 

     this.myVar="Post init called"; 
     print(); 

    } 

    public void beanInit(){ 

     this.myVar="Bean init called"; 
     print(); 
    } 

    public void contextInit(){ 

     this.myVar="Context init called"; 
     print(); 
    } 

    public void runnerInit(){ 

     this.myVar="Runner init called"; 
     print(); 
    } 

    public void bootListenerInit(){ 

     this.myVar="Boot init called"; 
     print(); 
    } 



    public void print(){ 
     System.out.println(this.myVar); 
     try { 
      Thread.sleep(3000); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 
} 

ContextRefreshedEvent dinlemek ve idare edecek ContextRefreshListener sınıftır.

public class ContextRefreshListener implements ApplicationListener<ContextRefreshedEvent> { 
    @Override 
    public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) { 
     contextRefreshedEvent.getApplicationContext().getBean(MyBean.class).contextInit(); 

    } 
} 

Ve Bahar Uygulama geliyor ApplicationReadyEvent alacaktır BootListener olduğunu.

public class MyBootListener implements ApplicationListener<ApplicationReadyEvent> { 
    @Override 
    public void onApplicationEvent(ApplicationReadyEvent applicationReadyEvent) { 
     applicationReadyEvent.getApplicationContext().getBean(MyBean.class).bootListenerInit(); 
    } 
} 

Ve nihayet Bahar Önyükleme Uygulaması

@SpringBootApplication 
public class StackoverflowBootApplication { 


    public static void main(String[] args) { 

     SpringApplication.run(StackoverflowBootApplication.class, args); 

    } 

    @Bean(name = "myBean", initMethod = "beanInit") 
    public MyBean getMyBean(){ 
     return new MyBean(); 
    } 


    @Bean 
    public ContextRefreshListener getContextRefreshedListener(){return new ContextRefreshListener();} 


    @Bean 
    public MyBootListener getBootListener(){return new MyBootListener();} 

    @Bean 
    public CommandLineRunner getRunner(ApplicationContext ctx){ 
     return (args) -> { 
      ctx.getBean(MyBean.class).runnerInit(); 
     }; 
    } 

} 

çıktısı:

Post init called 
Bean init called 
Context init called 
Runner init called 
Boot init called 

Post init called çıkış

@PostConstruct 
public void init(){ 
    this.initByPostconstruct="Post init called"; 

Bean init called fro geliyor

geliyor CommandLineRunner

@Bean 
public CommandLineRunner getRunner(ApplicationContext ctx){ 
    return (args) -> { 
     ctx.getBean(MyBean.class).runnerInit(); 
    }; 
} 

Boot init calledApplicationReadyEvent

gelen gelen

@Bean(name = "myBean", initMethod = "beanInit") 
public MyBean getMyBean(){ 
    return new MyBean(); 
} 
} 

Context init calledContextRefreshedEvent

public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) { 
    contextRefreshedEvent.getApplicationContext().getBean(MyBean.class).contextInit(); 

} 

Runner init called gelen initMethod değerini m gelir

Listelenen tüm senaryolar Spring tarafından tetiklendi, doğrudan olaylardan herhangi birini çağırdım, hepsi Spring Framework tarafından çağrıldı.

+0

Açıklama için teşekkürler. –