มีความแตกต่างระหว่างการใช้@PostConstruct
คำอธิบายประกอบและการประกาศวิธีเดียวกันกับการinit-method
กำหนดค่า Spring XML หรือไม่
มีความแตกต่างระหว่างการใช้@PostConstruct
คำอธิบายประกอบและการประกาศวิธีเดียวกันกับการinit-method
กำหนดค่า Spring XML หรือไม่
คำตอบ:
ไม่จริงฉันไม่คิดว่ามีความแตกต่าง แต่มีลำดับความสำคัญในวิธีการทำงาน @PostConstruct
, init-method
มี BeanPostProcessors
@PostConstruct
เป็นคำอธิบายประกอบ JSR-250 ในขณะที่init-method
Spring เป็นวิธีการเริ่มต้น@PostConstruct
วิธีการนี้จะถูกเรียกก่อนที่จะเรียกวิธีการเริ่มต้นafterPropertiesSet
แรก@PostConstruct
เรียกว่าแล้วแล้วafterPropertiesSet
init-method
สำหรับข้อมูลเพิ่มเติมคุณสามารถตรวจสอบของฤดูใบไม้ผลิเอกสารอ้างอิง
ก่อนหน้าข้อกำหนด JSR 250 การใช้วิธีการเริ่มต้นใน xml เป็นวิธีที่ต้องการเนื่องจากจะแยกคลาสจาวา (ถั่ว) ออกจากคลาส / คำอธิบายประกอบเฉพาะของฤดูใบไม้ผลิดังนั้นหากคุณกำลังสร้างไลบรารีที่ไม่จำเป็นต้องขึ้นอยู่กับโครงสร้างพื้นฐานของสปริงถั่ว จากนั้นจึงแนะนำให้ใช้วิธีการเริ่มต้นในระหว่างวิธีการสร้างคุณสามารถระบุวิธีการที่ต้องการเรียกเป็นวิธีการเริ่มต้น
ตอนนี้ด้วยการแนะนำข้อมูลจำเพาะ JSR 250 ใน Java EE และการรองรับสปริงของคำอธิบายประกอบเหล่านี้การพึ่งพาเฟรมเวิร์กสปริงจึงลดลงในระดับหนึ่ง
แต่ฉันต้องยอมรับว่าการเพิ่มสิ่งเหล่านี้เพิ่มความสามารถในการอ่านโค้ดดังนั้นจึงมีข้อดีและข้อเสียทั้งสองวิธี
ไม่มีความแตกต่างอย่างแท้จริง มันขึ้นอยู่กับว่าคุณต้องการกำหนดค่าระบบของคุณอย่างไรและนั่นเป็นเรื่องของทางเลือกส่วนบุคคล ตัวฉันเองฉันชอบที่จะใช้@PostConstruct
คำอธิบายประกอบสำหรับรหัสของฉันเอง (เนื่องจาก bean ได้รับการกำหนดค่าอย่างถูกต้องหลังจากเรียกเมธอดเท่านั้น) และฉันใช้init-method
เมื่อสร้างอินสแตนซ์ bean จากไลบรารีที่ไม่ทราบถึง Spring (ไม่สามารถใช้คำอธิบายประกอบได้ที่นั่นแน่นอน!) แต่ฉันเข้าใจคนที่ต้องการทำทั้งหมดไม่ทางใดก็ทางหนึ่ง
@postconstruct ไม่ได้เป็นส่วนหนึ่งของฤดูใบไม้ผลิ เป็นส่วนหนึ่งของแพ็คเกจ javax ทั้งสองอย่างเหมือนกัน โดยใช้ init-method เราจำเป็นต้องเพิ่มในไฟล์ xml หากคุณใช้ @postconstruct การเพิ่มใน xml ไม่จำเป็น ตรวจสอบบทความด้านล่าง
ที่คุณสามารถดูในแผนภาพด้านล่างของBean สร้างวงจรชีวิตโทรกลับ
3 ขั้นตอนนี้เกิดขึ้นใน Bean Creation Life-Cycle Callback:
@PostConstruct
จะเรียกว่าInitializingBean
มีการใช้งานแล้วafterPropertiesSet()
จะเรียกinit-method
หรือ@Bean(initmethod="..")
เรียกใช้เมธอด initแผนภาพนี้มาจากPro Spring 5: An In-Depth Guide to Spring Framework and its Tools
มีอาจจะมีความแตกต่างระหว่าง@PostConstruct
และinit-method
เพราะ @PostConstruct
มีการจัดการในpostProcessAfterInitialization
ขั้นตอนของการเริ่มต้นถั่ว ( AbstractAutowireCapableBeanFactory.initializeBean()
วิธีการ) โดยCommonAnnotationBeanPostProcessor
ในขณะที่init
วิธีการได้รับเรียกว่าหลังจากเสร็จสิ้นการpostProcessBeforeInitialization
เฟส (และสำหรับเรื่องนี้ก่อนที่จุดเริ่มต้นของpostProcessAfterInitialization
เฟส)
แก้ไข : ดังนั้นลำดับคือ 1) postProcessBeforeInitialization
เฟส 2) init
วิธีการถูกเรียก 3) postProcessAfterInitialization
เฟสซึ่งเรียก@PostConstruct
เมธอด
(ในฐานะบันทึกด้านข้างคำแถลงจากคำตอบที่ยอมรับ
@PostConstruct, init-method คือ BeanPostProcessors
ไม่ได้ถูกต้องมาก: @PostConstruct
จะถูกจัดการโดยBeanPostProcessor
, init
วิธีการไม่ได้).
มีจะมีความแตกต่างถ้าบาง (อาจกำหนดเอง) BeanPostProcessor
ซึ่งถูกกำหนดค่าด้วย ( Ordered.getOrder()
) ที่จะดำเนินการหลังจากที่CommonAnnotationBeanPostProcessor
จะทำบางสิ่งบางอย่างร้ายแรงในของpostProcessBeforeInitialization
วิธีการ
มีไม่มีความแตกต่างกับการกำหนดค่าฤดูใบไม้ผลิเริ่มต้นของใด ๆBeanPostProcessors
เพราะทุกBeanPostProcessors
ที่มีการกำหนดค่าที่จะดำเนินการหลังจากที่CommonAnnotationBeanPostProcessor
ไม่ได้ทำอะไรในpostProcessBeforeInitialization
วิธีการ
สรุปได้ว่าคำตอบที่ยอมรับและคำตอบที่คล้ายกันนั้นถูกต้อง ... ใน 99% ของกรณีและโพสต์นี้เป็นเพียงการแสดงความเคารพต่อแนวคิด "ปีศาจอยู่ในรายละเอียด"
รหัสเต็มที่นี่: https://github.com/wkaczurba/so8519187 ( spring-boot )
การใช้คำอธิบายประกอบ:
@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
}
}
รับเรา:
กำลังรีเฟรช org.springframework.context ...
MyComponent ในตัวสร้าง: [null]
MyComponent ใน postConstruct: [Magic]
MyComponent ใน afterPropertiesSet: [Magic]
... การ
ลงทะเบียนถั่วสำหรับการเปิดรับ JMX เมื่อเริ่มต้น
เริ่มต้น DemoApplication ใน 0.561 วินาที (JVM ทำงานเป็นเวลา 1.011) การ
ปิด org.springframework.context .. . กำลังยกเลิกการลงทะเบียนถั่วที่สัมผัส JMX เมื่อปิดเครื่อง
...
MyComponent ใน preDestroy: [Magic]