Init method trong Spring Controller (phiên bản chú thích)


105

Tôi đang chuyển đổi bộ điều khiển sang phiên bản chú thích mới hơn. Trong phiên bản cũ, tôi đã sử dụng để chỉ định phương thức init trong springmvc-servlet.xml bằng cách sử dụng:

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

Làm cách nào để chỉ định phương thức init bằng phiên bản chú thích?


Câu trả lời:


238

Bạn có thể dùng

@PostConstruct
public void init() {
   // ...
}

1
Bạn nói đúng, "Chú thích chung 1.0", Java1.7 của nó cũng sẽ hoạt động.
Grim

Nếu bạn cần sử dụng Người dùng từ SecurityContextHolder, tại thời điểm PostConstruct, nó không được khởi tạo. Nó cần được sử dụng như một phương thức không trạng thái. (getUser () ... {return Security ... user ();}
Joao Polo,

công cộng hay riêng tư
anshulkatta

20

Ngoài ra, bạn có thể yêu cầu lớp của bạn triển khai InitializingBeangiao diện để cung cấp một hàm gọi lại ( afterPropertiesSet()) mà ApplicationContext sẽ gọi khi bean được xây dựng.


4

Có một số cách để chặn quá trình khởi tạo trong Spring. Nếu bạn phải khởi tạo tất cả các bean và autowire / tiêm chúng, có ít nhất hai cách mà tôi biết sẽ đảm bảo điều này. Tôi chỉ có testet thứ hai nhưng tôi tin rằng cả hai đều hoạt động như nhau.

Nếu bạn đang sử dụng @Bean, bạn có thể tham khảo bằng initMethod, như thế này.

@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() {
  }

} 

Nếu bạn đang sử dụng @Component, bạn có thể chú thích bằng @EventListener như thế này.

@Component
public class BeanB {

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

Trong trường hợp của tôi, tôi có một hệ thống kế thừa nơi tôi hiện đang sử dụng IoC / DI trong đó Spring Boot là khung được chọn. Hệ thống cũ mang lại nhiều phụ thuộc vòng tròn cho bảng và do đó tôi phải sử dụng phụ thuộc setter rất nhiều. Điều đó khiến tôi đau đầu vì tôi không thể tin tưởng @PostConstruct vì tính năng autowiring / injection by setter vẫn chưa được thực hiện. Thứ tự là phương thức khởi tạo, @PostConstruct sau đó là bộ thiết lập tự động mong muốn. Tôi đã giải quyết nó bằng chú thích @EventListener sẽ chạy cuối cùng và "cùng một lúc" cho tất cả các bean. Ví dụ cho thấy việc triển khai InitializingBean là tốt.

Tôi có hai lớp (@Component) với sự phụ thuộc vào nhau. Các lớp trông giống nhau vì mục đích của ví dụ này chỉ hiển thị một trong số chúng.

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

Đây là đầu ra nhật ký hiển thị thứ tự của các lệnh gọi khi vùng chứa bắt đầu.

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

Như bạn có thể thấy @EventListener được chạy cuối cùng sau khi mọi thứ đã sẵn sàng và được định cấu hình.


-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
   }

}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.