Trong bài viết trước, mình đã giới thiệu với các bạn về Constructor Injection trong Spring. Nhưng bởi vì chúng ta có thể khai báo constructor cho một object theo nhiều cách khác nhau, nên trong bài viết này mình xin nói rõ thêm cho các bạn biết làm thế nào để khởi tạo đối tượng trong Spring container theo các cách khác nhau đó.
Hãy xem xét ví dụ sau nhé:
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.springoverloadedconstructorinjection; 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 + "]"; } } |
Như các bạn thấy, đối tượng Student của mình có ba constructor, hai trong số đó là overload. Bây giờ chúng ta hãy xem xét từng trường hợp cụ thể nhé!
Nhưng trước tiên, mình cần tạo Maven project trước:
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> |
Class Application có nội dung như sau:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
package com.huongdanjava.springoverloadedconstructorinjection; import org.springframework.beans.factory.BeanFactory; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Application { public static void main(String[] args) { BeanFactory context = new ClassPathXmlApplicationContext("spring.xml"); Student student = (Student) context.getBean("student"); System.out.println(student.toString()); } } |
OK, bắt đầu nào.
Đối với những overloaded constructor, chúng ta cần chỉ rõ loại dữ liệu của các tham số trong từng constructor các bạn ạ!
Ví dụ giờ mình cần khởi tạo đối tượng Student với tên là “Khanh”. Mình sẽ khai báo trong khung chứa của Spring như sau:
1 2 3 |
<bean id="student" class="com.huongdanjava.springoverloadedconstructorinjection.Student"> <constructor-arg type="java.lang.String" value="Khanh" /> </bean> |
Với cách khai báo này, Spring sẽ gọi đến constructor
1 2 3 |
public Student(String name) { this.name = name; } |
để khởi tạo đối tượng Student bởi vì biến name ở đây kiểu dữ liệu là String.
Kết quả:
Nếu bây giờ mình cần khởi tạo đối tượng Student với tuổi là 30, thì mình cần thay đổi kiểu dữ liệu, cụ thể như sau:
1 2 3 |
<bean id="student" class="com.huongdanjava.springoverloadedconstructorinjection.Student"> <constructor-arg type="int" value="30" /> </bean> |
Lúc này, Spring sẽ gọi đến constructor
1 2 3 |
public Student(int age) { this.age = age; } |
để khởi tạo đối tượng Student và kết quả sẽ như sau:
Đối với những constructor có nhiều tham số, chúng ta có thể khai báo chúng như bình thường:
1 2 3 4 |
<bean id="student" class="com.huongdanjava.springoverloadedconstructorinjection.Student"> <constructor-arg value="Khanh" /> <constructor-arg value="30" /> </bean> |
Thinh Au
Có vẻ đã đầy đủ, nhưng ngược lại còn một số trường hợp có thể gây lỗi nên tránh:
Nếu thêm 1 field như sau:
private String address;
public Student(String address, int age) {
this.address = address;
this.age = age;
}
Thế này thì 2 trường hợp cuối có thể gây lỗi vì ko tìm dc bean thích hợp 🙂
Thuan-Ngoc Le
@Thinh Au: Mình không nghĩ có khả năng tồn tại 2 overload có cùng type và order như vầy được:
public Constructor(String name, int age) { }
public Constructor(String address, int age) { }
Ngay tại compile time la` exception rồi, không cần đến runtime đâu anh Khanh nhĩ 🙂
Khanh Nguyễn
Đúng rồi đó em, không thể xảy ra!
Anonymous
Good job
AnBinh
Đối với những constructor có nhiều tham số trong vidu kế cuối, sao mình ko khai báo type để chỉ ra kiểu dữ liệu cho nó hả anh?
Khanh Nguyễn
Khai báo type chỉ trong trường hợp mình có nhiều constructor overload thôi em. Trong ví dụ của anh, không có overload nên anh chỉ cần khai báo như vậy là được.