Trong Spring, Bean Wiring là thuật ngữ dùng để chỉ quá trình các thành phần được liên kết với nhau qua Spring. Có 2 để liên kết các bean với nhau là thủ công (Manually) và tự động (Autowiring).
Manual wiring: Sử dụng thuộc tính ref
trong thẻ <property> hoặc <constructor>
Với cơ chế này chúng ta sử dụng thuộc tính ‘ref’ để tham chiếu đến chính xác bean cần liên kết. Ví dụ:
<bean id="student" class="vn.viettuts.autowiring.no.Student" autowire="no"> <property name="address" ref="address" /> </bean> <bean id="address" class="vn.viettuts.autowiring.no.StudentAddress"> <property name="city" value="Ha Noi" /> </bean>
Autowiring: sử dụng thuộc tính autowire
trong thẻ <bean>
Với cơ chế Bean Autowiring, việc liên kết giữa các thành phần sẽ diễn ra hoàn toàn tự động. Cơ chế tự động được thực hiện bởi Spring container dựa vào một trong 4 cách thức sau:
-
autowire="no":
Đây là kiểu mặc định, không liên kết tự động, liên kết thủ công thì phải sử dụng thuộc tính 'ref'. -
autowire="byName":
Tự động liên kết một thuộc tính đến một thành phần có tên trùng với tên của thuộc tính đó. -
autowire="byType":
Tự động liên kết một thuộc tính đến một thành phần có kiểu khớp với kiểu của thuộc tính đó. -
autowire="constructor":
Tự động liên kết một thuộc tính đến một thành phần có kiểu khớp với kiểu của tham số trong constructor.
Nội dung chính
Ví dụ Spring Beans Auto-wiring (XML Configuration)
1. autowire="no"
Tạo bean
package vn.viettuts.autowiring.no; public class StudentAddress { private String city; public String getCity() { return city; } public void setCity(String city) { this.city = city; } @Override public String toString() { return "Address [city = " + city + "]"; } }
package vn.viettuts.autowiring.no; public class Student { private StudentAddress address; public StudentAddress getAddress() { return address; } public void setAddress(StudentAddress address) { this.address = address; } @Override public String toString() { return "Student [address = " + address + "]"; } }
Tạo file cấu hình student-bean.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"> <bean id="student" class="vn.viettuts.autowiring.no.Student" autowire="no"> <property name="address" ref="address" /> </bean> <bean id="address" class="vn.viettuts.autowiring.no.StudentAddress"> <property name="city" value="Ha Noi" /> </bean> </beans>
Chú ý khi chúng ta thiết định autowire="no"
thì student sẽ không liên kết được với address. Do vậy cần phải thêm thuộc tính 'ref' để liên kết adress tới student, nếu không thuộc tính address sẽ = null.
Run app
package vn.viettuts.autowiring; import org.springframework.context.support.AbstractApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import vn.viettuts.autowiring.no.Student; public class MainApp { public static void main(String[] args) { AbstractApplicationContext context; //autowire="no" context = new ClassPathXmlApplicationContext("student-bean.xml"); Student student = (Student) context.getBean("student"); System.out.println(student); } }
Output:
Student [address = Address [city = Ha Noi]]
2. autowire="byName"
Tạo bean
package vn.viettuts.autowiring.byname; public class ApplicationUser { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "ApplicationUser [name=" + name + "]"; } }
package vn.viettuts.autowiring.byname; public class Application { private ApplicationUser applicationUser; public ApplicationUser getApplicationUser() { return applicationUser; } public void setApplicationUser(ApplicationUser applicationUser) { this.applicationUser = applicationUser; } @Override public String toString() { return "Application [applicationUser=" + applicationUser + "]"; } }
Tạo file cấu hình application-bean.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"> <!-- byName example --> <bean id="application" class="vn.viettuts.autowiring.byname.Application" autowire="byName" /> <bean id="applicationUser" class="vn.viettuts.autowiring.byname.ApplicationUser"> <property name="name" value="superUser" /> </bean> </beans>
Trong quá trình khởi tạo các thành phần của Spring container, thuộc tính applicationUser của bean application sẽ tự động liên kết với bean có cùng tên.
Run app
package vn.viettuts.autowiring; import org.springframework.context.support.AbstractApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import vn.viettuts.autowiring.byname.Application; import vn.viettuts.autowiring.no.Student; public class MainApp { public static void main(String[] args) { AbstractApplicationContext context; //autowire="byName" context = new ClassPathXmlApplicationContext("application-bean.xml"); Application application = (Application) context.getBean("application"); System.out.println(application); } }
Output:
Application [applicationUser=ApplicationUser [name=superUser]]
3. autowire="byType"
Tạo bean
package vn.viettuts.autowiring.bytype; public class EmployeeAddress { private String Street; private String city; public String getStreet() { return Street; } public void setStreet(String street) { Street = street; } public String getCity() { return city; } public void setCity(String city) { this.city = city; } @Override public String toString() { return "EmployeeAddress [Street=" + Street + ", city=" + city + "]"; } }
package vn.viettuts.autowiring.bytype; public class Employee { private EmployeeAddress address; public EmployeeAddress getAddress() { return address; } public void setAddress(EmployeeAddress address) { this.address = address; } @Override public String toString() { return "Employee [address=" + address + "]"; } }
Tạo file cấu hình employee-bean.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"> <!-- byType example --> <bean id="employee" class="vn.viettuts.autowiring.bytype.Employee" autowire="byType"/> <bean id="employeeAddress" class="vn.viettuts.autowiring.bytype.EmployeeAddress" > <property name="street" value="333/33 Tran A"/> <property name="city" value="Ha Noi"/> </bean> </beans>
Trong file cấu hình trên rõ ràng là không thành phần nào tham chiếu đến bean "employeeAddress". Khi thiết lập autowire="byType" thì bean "employee" sẽ tự động liên kết với bean "employeeAddress" theo kiểu giá trị của bean (EmployeeAddress)
Run app
package vn.viettuts.autowiring; import org.springframework.context.support.AbstractApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import vn.viettuts.autowiring.byname.Application; import vn.viettuts.autowiring.bytype.Employee; import vn.viettuts.autowiring.no.Student; public class MainApp { public static void main(String[] args) { AbstractApplicationContext context; //autowire="byType" context = new ClassPathXmlApplicationContext("employee-bean.xml"); Employee employee = (Employee) context.getBean("employee"); System.out.println(employee); } }
Output:
Employee [address=EmployeeAddress [Street=333/33 Tran A, city=Ha Noi]]
4. autowire="constructor"
Tạo bean
package vn.viettuts.autowiring.constructor; public class EmployeeAddress1 { private String Street; private String city; public String getStreet() { return Street; } public void setStreet(String street) { Street = street; } public String getCity() { return city; } public void setCity(String city) { this.city = city; } @Override public String toString() { return "EmployeeAddress [Street=" + Street + ", city=" + city + "]"; } }
package vn.viettuts.autowiring.constructor; public class Employee1 { private EmployeeAddress1 address; public Employee1(EmployeeAddress1 address1) { System.out.println("running..."); this.address = address1; } public EmployeeAddress1 getAddress() { return address; } public void setAddress(EmployeeAddress1 address) { this.address = address; } @Override public String toString() { return "Employee [address=" + address + "]"; } }
Tạo file cấu hình employee-1-bean.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd"> <!-- byType example --> <bean id="employee" class="vn.viettuts.autowiring.constructor.Employee1" autowire="constructor"/> <bean id="address1" class="vn.viettuts.autowiring.constructor.EmployeeAddress1" > <property name="street" value="444/44 Tran B"/> <property name="city" value="Ha Noi"/> </bean> </beans>
Run app
import org.springframework.context.support.AbstractApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import vn.viettuts.autowiring.byname.Application; import vn.viettuts.autowiring.bytype.Employee; import vn.viettuts.autowiring.constructor.Employee1; import vn.viettuts.autowiring.no.Student; public class MainApp { public static void main(String[] args) { AbstractApplicationContext context; //autowire="constructor" context = new ClassPathXmlApplicationContext("employee-1-bean.xml"); Employee1 employee1 = (Employee1) context.getBean("employee"); System.out.println(employee1); } }
Output:
running... Employee [address=EmployeeAddress [Street=444/44 Tran B, city=Ha Noi]]
Download Source Code