Inject đối tượng này vào đối tượng khác trong Spring thực sự rất phổ biến khi các bạn làm việc với các dự án có sử dụng Spring framework. Trong bài viết trước mình đã đề cập đến thuộc tính ref của Spring để đưa đối tượng Shape vào đối tượng Drawing, trong bài viết này mình sẽ nói thêm một số cách khai báo khác để inject đối tượng này vào đối tượng khác trong Spring sử dụng tập tin XML, các bạn nhé!
Đầu tiên, mình sẽ tạo mới một Maven project để làm ví dụ:
Mình sẽ sử dụng Java 17 cho ứng dụng ví dụ này:
1 2 3 4 |
<properties> <maven.compiler.source>17</maven.compiler.source> <maven.compiler.target>17</maven.compiler.target> </properties> |
Spring dependency như sau:
1 2 3 4 5 |
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>6.0.2</version> </dependency> |
OK, bây giờ giả sử mình có một lớp học, lớp học này sẽ bao gồm một hoặc nhiều sinh viên, cụ thể như sau:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
package com.huongdanjava.springexample; public class Student { private String name; private int age; public Student(String name) { this.name = name; } public Student(int age) { this.age = age; } public Student(String name, int age) { this.name = name; this.age = age; } @Override public String toString() { return "Student [name=" + name + ", age=" + age + "]"; } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
package com.huongdanjava.springexample; import java.util.List; public class Clazz { private Student student; private List<Student> students; public Clazz(Student student) { this.student = student; } public Clazz(List<Student> students) { this.students = students; } public Student getStudent() { return student; } public List<Student> getStudents() { return students; } } |
Giờ chúng ta sẽ xem xét trường hợp đầu tiên nhé các bạn. Mình sẽ tạo một lớp học chỉ có một sinh viên duy nhất bằng cách đưa đối tượng sinh viên A vào trong đối tượng Clazz. Thông thường, chúng ta sẽ khởi tạo như sau:
1 2 3 4 5 6 7 |
<bean id="studenta" class="com.huongdanjava.springexample.Student"> <constructor-arg value="A" /> </bean> <bean id="clazz" class="com.huongdanjava.springexample.Clazz"> <constructor-arg type="com.huongdanjava.springexample.Student" ref="studenta" /> </bean> |
Nếu đối tượng sinh viên A của chúng ta có khai báo một tên gọi, chúng ta cũng có thể sử dụng nó với thuộc tính ref của Spring.
1 2 3 4 5 6 7 |
<bean id="clazz" class="com.huongdanjava.springexample.Clazz"> <constructor-arg type="com.huongdanjava.springexample.Student" ref="student1" /> </bean> <bean id="studenta" class="com.huongdanjava.springexample.Student" name="student1"> <constructor-arg value="A" /> </bean> |
Ngoài ra, chúng ta còn 1 cách khác nữa để khai báo:
1 2 3 4 5 6 7 |
<bean id="clazz" class="com.huongdanjava.springexample.Clazz"> <constructor-arg type="com.huongdanjava.springexample.Student"> <bean id="studenta" class="com.huongdanjava.springexample.Student"> <constructor-arg value="A" /> </bean> </constructor-arg> </bean> |
Đối tượng sinh viên A được tạo ra như thế này được gọi là Inner Bean, id của bean trong trường hợp này không quan trọng, Spring không quan tâm đến nó nhé các bạn.
Các bạn chỉ nên áp dụng trong trường hợp đặc biệt nào đó, ngoài ra theo mình nghĩ thì không nên dùng. Spring nó hỗ trợ nên mình chỉ muốn nói ra cho các bạn biết.
Code để kiểm tra:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
package com.huongdanjava.springexample; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Application { public static void main(String[] args) { // Call Spring container ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml"); // Request to get Clazz object Clazz clazz = (Clazz) context.getBean("clazz"); // Do anything System.out.println(clazz.getStudent().toString()); } } |
Kết quả:
OK, giờ mình sẽ nói đến trường hợp thứ hai. Chúng ta sẽ tạo một lớp học với một danh sách các sinh viên. Mình sẽ tạo ba sinh viên A, B, C và đưa chúng vào đối tượng Clazz. Cụ thể như sau:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
<bean id="clazz" class="com.huongdanjava.springexample.Clazz"> <constructor-arg type="java.util.List"> <list> <ref bean="studenta"/> <ref bean="studentb"/> <ref bean="studentc"/> </list> </constructor-arg> </bean> <bean id="studenta" class="com.huongdanjava.springexample.Student"> <constructor-arg value="A" /> </bean> <bean id="studentb" class="com.huongdanjava.springexample.Student"> <constructor-arg value="B" /> </bean> <bean id="studentc" class="com.huongdanjava.springexample.Student"> <constructor-arg value="C" /> </bean> |
Code để kiểm tra:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
package com.huongdanjava.springexample; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Application { public static void main(String[] args) { // Call Spring container ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml"); // Request to get Clazz object Clazz clazz = (Clazz) context.getBean("clazz"); // Do anything System.out.println(clazz.getStudents().size()); } } |
Kết quả:
Trường
Ở cách thứ 3 dùng idref không biết chỗ này có sai sót gì không nhỉ. Code bean chỗ này mình để là :
Nhưng lại chạy ra kết quả là:
Student [name=studenta, age=0]
Khanh Nguyen
Không thấy code của bạn nhỉ?
Minh
Hình như sinh viên chưa có hàm tạo không đối, nên khi khao báo 1 đối tượng clazza trong spring.xml nó báo lỗi phải không a
Cương
E có chút chưa hiểu ở class Student có 2 thuộc tính String name và int age, khi khởi tạo bean trong file XML a sử dụng thẻ thì sẽ set đc giá trị cho name là “a” vậy còn giá trị age thì mình set như thế nào và thẻ chỉ set giá trị đầu tiên thôi ạ? nếu có 2 giá trị đều thuộc kiểu string thì sẽ như thế nào ? Mong a giải đáp giúp e :))
Khanh Nguyen
Xem thêm bài viết này https://huongdanjava.com/vi/noi-them-ve-constructor-injection-trong-spring-su-dung-tap-tin-xml.html, em nhé!
Cương
e cảm ơn
Huy Tuấn
Series tuyệt vời!
Cám ơn chủ blog đã có những bài viết tuyệt vời! Minh đã kiếm tài liệu về Spring mấy ngày nay chỉ có mỗi nội dung ở đây vừa dễ đọc vừa đầy đủ rõ ràng.
Khanh Nguyen
Thanks bạn
gian nui
very good, this is a document useful
Quân
Vậy nếu có n sinh viên thì làm sao ạ. Bài viết rất hay và bổ ích .Thanks
Khanh Nguyễn
Nếu có n sinh viên thì mình cũng tạo n bean, mỗi bean chứa thông tin sinh viên khác nhau. Sau đó mình thêm vào giống như trường hợp thứ hai đó Quân.
Quân
cảm ơn anh. mà tạo ra n bean có nghĩa thông tin mỗi sinh viên mình phải nhập vô hả, hay là sao c
Quân
có cách nào để đưa 1 danh sách sinh viên có sẵn vào bean k ạ, chứ nếu sinh viên quá nhiều mà ta nhập vào thì hơi lâu đấy a.
Khanh Nguyễn
Nếu mà sinh viên quá nhiều, thì mình cần 1 cách khác để giải quyết, ví dụ mình sẽ dùng file properties để lưu danh sách sinh viên, sau đó sẽ viết lại code để có thể tạo bean từ danh sách sinh viên đó. Hoặc mình cũng có thể dùng database để lưu danh sách sinh viên cũng được. Cái này tùy theo nhu cầu của em thôi.
Quân
dạ , em cảm ơn ạ