วงจรชีวิตของ Spring Bean
Spring Bean เป็นส่วนที่สำคัญมากของ Spring Application ทั้งหลาย ซึ่ง Spring ApplicationContext จะรับผิดชอบในการเริ่มต้น Spring Bean ที่กำหนดใน Spring Bean Configuration
Spring Context ยังมีหน้าที่รับผิดชอบการ Injection Dependency ใน Bean อีกด้วย ทั้งผ่าน Setter method หรือ Constructor ด้วย Autowired
annotation
วงจรชีวิตของ Spring Bean
เริ่มจากโหลด Bean Definitions จาก Bean Configuration แล้วทำการสร้าง Bean และ inject dependency ต่างๆ ของ Bean หลังจากนั้นก็จะเป็น Bean Post Processor ก็จะได้ Bean ที่พร้อมใช้งาน และเมื่อ Spring Context หยุดการทำงานก็จะ Dispose Bean นั้นทิ้ง
บางครั้งเราต้องการที่จะ initialize resource ในคลาส Bean ด้วยตัวเราเอง ตัวอย่างเช่นสร้าง database connection หรือ validate third party service ในตอนที่เริ่มต้นก่อนที่จะมีการ request จาก client
Spring Framework มีหลากหลายวิธีที่ทำให้เราสามารถสร้าง post-initialization หลักจากที่สร้าง Bean เสร็จแล้วและ pre-destroy ก่อนที่จะทำลาย Bean ของเราเองในวงจรชีวิตของ Spring Bean ได้
- ใช้ InitializingBean และ DisposableBean interface
- สร้าง init-method และ destroy-method ในไฟล์ configuration
- ใช้ PostConstruct และ PreDestroy annotation
InitializingBean/DisposableBean
ใช้ implement InitializingBean
ด้วย afterPropertiesSet
method หลังจากที่สร้าง Bean เสร็จเรียบร้อยแล้ว และ DisposableBean
ด้วย destroy
method ก่อนที่จะทำลาย Bean
@Component
public class DemoBean implements InitializingBean, DisposableBean {
@Override
public void destroy() throws Exception {
log.info("DemoBean going to destroy");
}
@Override
public void afterPropertiesSet() throws Exception {
log.info("DemoBean was initialized");
}
}
Init-method/destroy-method
กำหนด init-method
สำหรับดำเนินการหลังจากที่สร้าง Bean แล้ว และ destroy-method
ก่อนที่จะทำลาย Bean ใน Bean Configuration ซึ่งอาจจะเป็น XML หรือ Java (ใช้ annotation parameter initMethod
และ destroyMethod
) ก็ได้
@Component
public class DemoBean {
public void destroy() throws Exception {
log.info("DemoBean going to destroy");
}
public void init() throws Exception {
log.info("DemoBean was initialized");
}
}
Bean Configuration
@Configuration
public class BeanConfig {
@Bean(initMethod = "init", destroyMethod = "destroy")
public DemoBean getDemoBean() {
return new DemoBean();
}
}
@PostConstruct/@PreDestroy
สำหรับวิธีนี้ใช้ annotation @PostConstruct
หลังจากสร้าง Bean เสร็จเรียบร้อยแล้ว และ @PreDestroy
ก่อนที่จะทำลาย Bean
@Component
public class DemoBean {
@PreDestroy
public void destroy() throws Exception {
log.info("DemoBean going to destroy");
}
@PostConstruct
public void init() throws Exception {
log.info("DemoBean was initialized");
}
}
ซึ่งทั้งหมดจะได้ output ประมาณนี้ ซึ่งจะเห็นได้ว่ามีการเรียก post-initialization หลังจากสร้าง Bean แล้ว และเรียก pre-destroy ก่อนที่ Spring Context จะปิดลง
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.1.0.RELEASE)
... c.i.d.DemoBeanApplication : Starting DemoBeanApplication
... com.iphayao.demobean.DemoBean : DemoBean was initialized
... c.i.demobean.DemoBeanApplication : Started DemoBeanApplication
... com.iphayao.demobean.DemoBean : DemoBean going to destroy
นอกจานี้แล้วยังสามรถใช้ Spring *Awear interface ในการจัดการกับ Bean ได้อีกด้วยซึ่งบทความนี้จะไม่ได้ครอบคลุม