Metode init di Spring Controller (versi anotasi)

105

Saya mengonversi pengontrol ke versi anotasi yang lebih baru. Di versi lama saya digunakan untuk menentukan metode init di springmvc-servlet.xml menggunakan:

<beans>
    <bean id="myBean" class="..." init-method="init"/>
</beans>

Bagaimana cara menentukan metode init menggunakan versi anotasi?

Krt_Malta
sumber

Jawaban:

238

Kamu bisa memakai

@PostConstruct
public void init() {
   // ...
}
Johan Sjöberg
sumber
1
Anda benar, "Anotasi Umum 1.0", Java1.7 juga akan berfungsi.
Grim
Jika Anda perlu menggunakan User dari SecurityContextHolder, pada saat PostConstruct itu belum diinisialisasi. Ini perlu digunakan seperti metode tanpa kewarganegaraan. (getUser () ... {return Security ... user ();}
Joao Polo
publik atau swasta
anshulkatta
20

Alternatifnya Anda bisa meminta kelas Anda mengimplementasikan InitializingBeanantarmuka untuk menyediakan fungsi callback ( afterPropertiesSet()) yang akan dipanggil oleh ApplicationContext ketika kacang dibuat.

matt b
sumber
4

Ada beberapa cara untuk menghentikan proses inisialisasi di Spring. Jika Anda harus menginisialisasi semua kacang dan melakukan autowire / menyuntikkannya, setidaknya ada dua cara yang saya ketahui yang akan memastikan hal ini. Saya hanya punya testet yang kedua tapi saya percaya keduanya bekerja sama.

Jika Anda menggunakan @Bean, Anda bisa mereferensikan dengan initMethod, seperti ini.

@Configuration
public class BeanConfiguration {

  @Bean(initMethod="init")
  public BeanA beanA() {
    return new BeanA();
  }
}

public class BeanA {

  // method to be initialized after context is ready
  public void init() {
  }

} 

Jika Anda menggunakan @Component, Anda dapat membuat anotasi dengan @EventListener seperti ini.

@Component
public class BeanB {

  @EventListener
  public void onApplicationEvent(ContextRefreshedEvent event) {
  }
}

Dalam kasus saya, saya memiliki sistem warisan di mana saya sekarang menggunakan IoC / DI di mana Spring Boot adalah kerangka kerja yang dipilih. Sistem lama membawa banyak dependensi melingkar ke tabel dan oleh karena itu saya harus banyak menggunakan ketergantungan penyetel. Itu membuat saya pusing karena saya tidak bisa mempercayai @PostConstruct karena autowiring / injeksi oleh penyetel belum dilakukan. Urutannya adalah konstruktor, @PostConstruct lalu penyetel yang dipasang secara otomatis. Saya menyelesaikannya dengan anotasi @EventListener yang akan berjalan terakhir dan pada waktu yang "sama" untuk semua kacang. Contoh tersebut juga menunjukkan implementasi InitializingBean.

Saya memiliki dua kelas (@Component) dengan ketergantungan satu sama lain. Kelas terlihat sama untuk tujuan contoh ini hanya menampilkan salah satu dari mereka.

@Component
public class BeanA implements InitializingBean {
  private BeanB beanB;

  public BeanA() {
    log.debug("Created...");
  }

  @PostConstruct
  private void postConstruct() {
    log.debug("@PostConstruct");
  }

  @Autowired
  public void setBeanB(BeanB beanB) {
    log.debug("@Autowired beanB");
    this.beanB = beanB;
  }

  @Override
  public void afterPropertiesSet() throws Exception {
    log.debug("afterPropertiesSet()");
  }

  @EventListener
  public void onApplicationEvent(ContextRefreshedEvent event) {
    log.debug("@EventListener");
  } 
}

Ini adalah keluaran log yang menunjukkan urutan panggilan saat penampung dimulai.

2018-11-30 18:29:30.504 DEBUG 3624 --- [           main] com.example.demo.BeanA                   : Created...
2018-11-30 18:29:30.509 DEBUG 3624 --- [           main] com.example.demo.BeanB                   : Created...
2018-11-30 18:29:30.517 DEBUG 3624 --- [           main] com.example.demo.BeanB                   : @Autowired beanA
2018-11-30 18:29:30.518 DEBUG 3624 --- [           main] com.example.demo.BeanB                   : @PostConstruct
2018-11-30 18:29:30.518 DEBUG 3624 --- [           main] com.example.demo.BeanB                   : afterPropertiesSet()
2018-11-30 18:29:30.518 DEBUG 3624 --- [           main] com.example.demo.BeanA                   : @Autowired beanB
2018-11-30 18:29:30.518 DEBUG 3624 --- [           main] com.example.demo.BeanA                   : @PostConstruct
2018-11-30 18:29:30.518 DEBUG 3624 --- [           main] com.example.demo.BeanA                   : afterPropertiesSet()
2018-11-30 18:29:30.607 DEBUG 3624 --- [           main] com.example.demo.BeanA                   : @EventListener
2018-11-30 18:29:30.607 DEBUG 3624 --- [           main] com.example.demo.BeanB                   : @EventListener

Seperti yang Anda lihat, @EventListener dijalankan terakhir setelah semuanya siap dan dikonfigurasi.

Avec
sumber
-2
public class InitHelloWorld implements BeanPostProcessor {

   public Object postProcessBeforeInitialization(Object bean,
             String beanName) throws BeansException {
       System.out.println("BeforeInitialization : " + beanName);
       return bean;  // you can return any other object as well
   }

   public Object postProcessAfterInitialization(Object bean,
             String beanName) throws BeansException {
       System.out.println("AfterInitialization : " + beanName);
       return bean;  // you can return any other object as well
   }

}
Yasir Shabbir Choudhary
sumber