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-method
là BeanPostProcessors.
@PostConstruct
là một chú thích JSR-250 trong khi init-method
Spring là cách có một phương thức khởi tạo.@PostConstruct
phươ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à afterPropertiesSet
và 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 @PostConstruct
cá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-method
khi 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:
@PostConstruct
sẽ được gọi.InitializingBean
được thực hiện, sau đó afterPropertiesSet()
sẽ được gọi.init-method
hoặ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 @PostConstruct
và init-method
bởi vì @PostConstruct
được xử lý trong postProcessAfterInitialization
giai đoạn khởi tạo bean ( AbstractAutowireCapableBeanFactory.initializeBean()
phương thức) bởi CommonAnnotationBeanPostProcessor
, trong khi init
phương thức được gọi sau khi hoàn thành postProcessBeforeInitialization
giai đoạn (và, đối với vấn đề này, trước khi bắt đầu postProcessAfterInitialization
giai đoạn).
CHỈNH SỬA : Vì vậy, trình tự là: 1) postProcessBeforeInitialization
pha, 2) init
phương thức được gọi, 3) postProcessAfterInitialization
pha, gọi @PostConstruct
phươ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
, init
phươ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 postProcessBeforeInitialization
phươ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 BeanPostProcessors
bởi vì tất cả BeanPostProcessors
cấ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 postProcessBeforeInitialization
phươ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]