Câu trả lời:
Không thực tế, tôi không nghĩ rằng có bất kỳ sự khác biệt nào nhưng có những ưu tiên trong cách họ làm việc. @PostConstruct, init-methodlà BeanPostProcessors.
@PostConstructlà một chú thích JSR-250 trong khi init-methodSpring là cách có một phương thức khởi tạo.@PostConstructphương thức, nó sẽ được gọi trước khi các phương thức khởi tạo được gọi.afterPropertiesSet, đầu tiên @PostConstructđược gọi, sau đó là afterPropertiesSetvà sau đó init-method.Để biết thêm thông tin, bạn có thể kiểm tra tài liệu tham khảo của Spring .
Trước khi có thông số kỹ thuật JSR 250, cách sử dụng init-method trong xml được ưu tiên hơn, vì nó tách các lớp java (bean) khỏi bất kỳ lớp / chú thích cụ thể nào của mùa xuân. thì việc sử dụng phương thức init được ưu tiên hơn. Trong quá trình tạo phương thức, u có thể chỉ định phương thức cần được gọi là phương thức khởi tạo.
Bây giờ với việc giới thiệu các thông số kỹ thuật JSR 250 trong Java EE và hỗ trợ mùa xuân của các chú thích này, sự phụ thuộc vào khuôn khổ mùa xuân đã được giảm thiểu ở một mức độ nhất định.
Nhưng tôi phải thừa nhận rằng việc bổ sung những thứ này làm tăng khả năng đọc mã. Vì vậy, cả hai cách tiếp cận đều có những ưu và khuyết điểm.
Không có sự khác biệt thực sự. Nó phụ thuộc vào cách bạn muốn cấu hình hệ thống của mình và đó là vấn đề của sự lựa chọn cá nhân. Bản thân tôi, tôi thích sử dụng @PostConstructcác chú thích cho mã của riêng mình (vì bean chỉ được định cấu hình chính xác sau khi phương thức được gọi) và tôi sử dụng init-methodkhi khởi tạo các bean từ các thư viện không phải là Spring (tất nhiên không thể áp dụng các chú thích ở đó!) nhưng tôi hoàn toàn có thể hiểu mọi người muốn làm theo cách này hay cách khác.
@postconstruct không phải là một phần của mùa xuân. Nó là một phần của gói javax. Cả hai đều giống nhau. bằng cách sử dụng init-method, chúng tôi cần thêm vào tệp xml. Nếu bạn sử dụng @postconstruct, việc thêm trong xml là không bắt buộc. Kiểm tra bài viết dưới đây.
Như bạn có thể thấy trong sơ đồ bên dưới của Gọi lại vòng đời tạo Bean .
Bước 3 này xảy ra trong Gọi lại Vòng đời Tạo Bean:
@PostConstructsẽ được gọi.InitializingBeanđược thực hiện, sau đó afterPropertiesSet()sẽ được gọi.init-methodhoặc @Bean(initmethod="..")thì nó gọi phương thức init.Sơ đồ này là từ Pro Spring 5: Hướng dẫn chuyên sâu về Spring Framework và các công cụ của nó
Có thể có sự khác biệt giữa @PostConstructvà init-methodbởi vì @PostConstructđược xử lý trong postProcessAfterInitializationgiai đoạn khởi tạo bean ( AbstractAutowireCapableBeanFactory.initializeBean()phương thức) bởi CommonAnnotationBeanPostProcessor, trong khi initphương thức được gọi sau khi hoàn thành postProcessBeforeInitializationgiai đoạn (và, đối với vấn đề này, trước khi bắt đầu postProcessAfterInitializationgiai đoạn).
CHỈNH SỬA : Vì vậy, trình tự là: 1) postProcessBeforeInitializationpha, 2) initphương thức được gọi, 3) postProcessAfterInitializationpha, gọi @PostConstructphương thức
(Như một lưu ý phụ, một tuyên bố từ câu trả lời được chấp nhận
@PostConstruct, init-method là BeanPostProcessors
không hoàn toàn đúng: @PostConstructđược xử lý bởi một BeanPostProcessor, initphương thức thì không.)
Sẽ có sự khác biệt nếu một số (có thể tùy chỉnh) BeanPostProcessor, được cấu hình với ( Ordered.getOrder()) để được thực thi sau đó CommonAnnotationBeanPostProcessor, đang thực hiện một điều gì đó nghiêm trọng trong postProcessBeforeInitializationphương thức của nó .
Không có bất kỳ sự khác biệt nào với cấu hình Spring mặc định BeanPostProcessorsbởi vì tất cả BeanPostProcessorscấu hình được cấu hình để được thực thi sau đó CommonAnnotationBeanPostProcessor, không thực hiện bất kỳ điều gì trong postProcessBeforeInitializationphương thức.
Tóm lại, câu trả lời được chấp nhận và câu trả lời tương tự là đúng ... trong 99% trường hợp, và bài đăng này chỉ để tôn vinh một khái niệm "ma quỷ là chi tiết"
Mã đầy đủ tại đây: https://github.com/wkaczurba/so8519187 ( spring-boot )
Sử dụng chú thích:
@Slf4j
@Component
public class MyComponent implements InitializingBean {
@Value("${mycomponent.value:Magic}")
public String value;
public MyComponent() {
log.info("MyComponent in constructor: [{}]", value); // (0) displays: Null
}
@PostConstruct
public void postConstruct() {
log.info("MyComponent in postConstruct: [{}]", value); // (1) displays: Magic
}
@Override // init-method; overrides InitializingBean.afterPropertiesSet()
public void afterPropertiesSet() {
log.info("MyComponent in afterPropertiesSet: [{}]", value); // (2) displays: Magic
}
@PreDestroy
public void preDestroy() {
log.info("MyComponent in preDestroy: [{}]", value); // (3) displays: Magic
}
}
Cho chúng tôi:
Đang làm mới org.springframework.context ...
MyComponent trong constructor: [null]
MyComponent trong postConstruct: [Magic]
MyComponent trong afterPropertiesSet: [Magic]
...
Đăng ký bean để hiển thị JMX khi khởi động Đã
bắt đầu DemoApplication trong 0,561 giây (JVM chạy cho 1.011)
Đóng org.springframework.context .. . Hủy đăng ký đậu tiếp xúc với JMX khi tắt máy
...
MyComponent trong preDestroy: [Magic]