Vòng đời của Bean trong Spring bao gồm khởi tạo, sử dụng và kết thúc. Mặc dù, có một danh sách các hoạt động xảy ra đằng sau thời điểm bắt đầu và trước khi bean bị hủy.
Trong bài này, chúng ta chỉ bàn luận về 2 phương thức liên quan đến việc gọi lại (callback) vòng đời của bean được yêu cầu tại thời điểm khởi tạo (init) và hủy (destroy).
Nội dung chính
Gọi lại phương thức khởi tạo
Interface org.springframework.beans.factory.InitializingBean cung cấp phương thức duy nhất sau:
void afterPropertiesSet() throws Exception;
Vì vậy bạn có thể cung cấp bản cài đặt cho interface trên và hoạt động khởi tạo có thể hoạt động bên trong phương thức afterPropertiesSet() như sau:
public class ExampleBean implements InitializingBean { public void afterPropertiesSet() { // thực hiện hoạt động khởi tạo } }
Trong trường hợp siêu dữ liệu cấu hình dựa trên XML, bạn có thể sử dụng thuộc tính init-method để chỉ định tên của phương thức khởi tạo có kiểu trả về là void và không có đối số.
<bean id = "exampleBean" class = "examples.ExampleBean" init-method = "init"/>
Sau đây là định phương thức init trong lớp:
public class ExampleBean { public void init() { // thực hiện hoạt động khởi tạo } }
Gọi lại phương thức hủy
Interface org.springframework.beans.factory.DisposableBean cung cấp phương thức duy nhất sau:
void destroy() throws Exception;
Vì vậy bạn có thể cung cấp bản cài đặt cho interface trên và hoạt động khởi tạo có thể hoạt động bên trong phương thức afterPropertiesSet() như sau:
public class ExampleBean implements DisposableBean { public void destroy() { // thực hiện hoạt động khởi tạo } }
Trong trường hợp siêu dữ liệu cấu hình dựa trên XML, bạn có thể sử dụng thuộc tính destroy-method để chỉ định tên của phương thức hủy có kiểu trả về là void và không có đối số.
<bean id = "exampleBean" class = "examples.ExampleBean" destroy-method = "destroy"/>
Sau đây là định phương thức init trong lớp:
public class ExampleBean { public void destroy() { // thực hiện hoạt động khởi tạo } }
Nếu bạn đang sử dụng Spring IoC container trong môi trường ứng dụng không phải là ứng dụng web; ví dụ như trong môi trường máy tính để bàn, bạn sẽ đăng ký một yêu cầu shutdown với JVM. Làm như vậy đảm bảo tắt máy một cách chủ động và gọi các phương thức hủy có liên quan đến các bean có scope là singleton để tất cả các tài nguyên được giải phóng.
Chúng tôi đề nghị bạn không implement các interface InitializingBean hoặc DisposableBean để thực hiện gọi lại phương thức init hoặc destroy, vì cấu hình XML cho phép bạn có nhiều tính linh hoạt trong việc đặt tên cho phương thức của bạn.
Ví dụ về vòng đời của Bean trong Spring
Tạo một ứng dụng Spring trong Eclipse như trong ví dụ tạo Maven project trong Eclipse.
Tạo package có tên vn.viettuts trong thư mục src.
Add thư viện Spring cần thiết vào project bằng cách thêm các dependency sau vào file pom.xml. Sau đó update project.
<!-- https://mvnrepository.com/artifact/org.springframework/spring-core --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>4.3.6.RELEASE</version> <scope>provided</scope> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-beans --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>4.3.6.RELEASE</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-context --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.3.6.RELEASE</version> </dependency>
Tạo lớp HelloWorld.java
package vn.viettuts; public class HelloWorld { private String message; public void setMessage(String message) { this.message = message; } public void getMessage() { System.out.println("Your Message : " + message); } public void init() { System.out.println("Init bean."); } public void destroy() { System.out.println("Destroy bean."); } }
Tạo tập tin cấu hình Beans.xml tại thư mục src
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <bean id="helloWorld" class="vn.viettuts.HelloWorld" init-method="init" destroy-method="destroy"> <property name = "message" value = "Hello World!"/> </bean> </beans>
Tạo lớp MainApp.java
Tại đây bạn phải đăng ký một liên kết bằng cách gọi phương thức registerShutdownHook(), phương thức này được khai báo trong lớp AbstractApplicationContext điều này sẽ đảm bảo chương trình được tắt một cách chu đáo và phương thức destroy được gọi.
package vn.viettuts; import org.springframework.context.support.AbstractApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class MainApp { public static void main(String[] args) { AbstractApplicationContext context = new ClassPathXmlApplicationContext( "Beans.xml"); HelloWorld objA = (HelloWorld) context.getBean("helloWorld"); objA.getMessage(); context.registerShutdownHook(); } }
Kết quả:
Init bean. Your Message : Hello World! Destroy bean.
Phương thức mặc định init và destroy
Nếu bạn có quá nhiều bean có các phương thức init và/hoặc destroy có cùng tên, bạn không cần phải khai báo init-method và destroy-method trên mỗi bean đơn lẻ. Thay vào đó, Spring framework cung cấp sự linh hoạt để cấu hình trường hợp như vậy bằng cách sử dụng các thuộc tính default-init-method và default-destroy-method trên phần tử <beans> như sau:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd" default-init-method="init" default-destroy-method="destroy"> <bean id="helloWorld" class="vn.viettuts.HelloWorld"> <!-- cấu hình bean --> </bean> </beans>