Nói thêm về Constructor Injection trong Spring sử dụng tập tin XML

Trong bài viết trước, mình đã giới thiệu với các bạn cơ bản về Constructor Injection trong Spring sử dụng tập tin XML. Trong bài viết này, mình xin đề cập về nó một cách chi tiết hơn để các bạn có thể sử dụng nó một cách dễ dàng các bạn nhé!

Hãy xem xét ví dụ sau, mình có class Student:

và class Clazz:

Như các bạn thấy, class Clazz của mình đã định nghĩa một constructor với tham số là một đối tượng Student và một biến name kiểu String. Các tham số này là những đối tượng phụ thuộc, vậy làm thế nào để inject các đối tượng phụ thuộc này vào class Clazz sử dụng constructor này? Các bạn đọc tiếp nhé!

Trước tiên, để dễ hiểu, mình sẽ tạo mới một Maven project trước:

Mình sẽ sử dụng Java 17 cho ứng dụng ví dụ này:

Spring dependency như sau:

Class Application có nội dung như sau:

OK, bắt đầu nào các bạn.

Để inject đối tượng Student vào đối tượng Clazz, trước tiên chúng ta cần khởi tạo đối tượng Student trong Spring container trước! Ví dụ giờ mình 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:

Với cách khai báo này, Spring sẽ gọi đến constructor

để khởi tạo đối tượng Student.

Trong khai báo này, mình đã sử dụng thẻ <constructor-arg> với thuộc tính value để gán giá trị cho biến name. Thẻ <constructor-arg> này được sử dụng để định nghĩa các tham số của constructor cho các đối tượng trong khung chứa của Spring. Nó có nhiều thuộc tính nhưng có 2 thuộc tính mà chúng ta thường dùng với thẻ này là value và ref.

Thuộc tính value được sử dụng trong trường hợp giá trị inject là một giá trị text, số hoặc là boolean,… Còn thuộc tính ref thì được sử dụng để reference tới một bean khác đã được khởi tạo trong Spring container.

OK, vậy là chúng ta đã khai báo xong đối tượng Student, bây giờ đến đối tượng Clazz các bạn nhé!

Để khai báo đối tượng Clazz, chúng ta sẽ sử dụng thẻ <constructor-arg> cùng với cả 2 thuộc tính ref và value luôn theo thứ tự từng tham số, như sau:

Kết quả:

Nếu các bạn muốn khai báo các tham số theo những thứ tự khác nhau, chúng ta có thể khai báo như sau:

Giá trị của index bắt đầu từ 0 nhé các bạn.

Ngoài ra, thay vì sử dụng thẻ <constructor-arg>, Spring còn hỗ trợ cho chúng ta một cách khác đơn giản hơn để làm việc với Constructor Injection, đó chính là sử dụng namespace c, xmlns:c=”http://www.springframework.org/schema/c”.

Namespace này cho phép chúng ta có thể khai báo các tham số trong constructor của các đối tượng ngay trong thẻ <bean> dưới dạng là một thuộc tính. Nó không đi kèm một tập tin schema XSD, do đó để sử dụng namespace c, các bạn chỉ cần khai báo nó trong tập tin cấu hình XML của Spring như sau:

rồi sử dụng syntax sau để inject các đối tượng phụ thuộc.

Nếu các bạn sử dụng tên của các tham số trong constructor để inject các đối tượng phụ thuộc thì hãy khai báo một thuộc tính trong thẻ <bean> với name bắt đầu là “c:” tiếp theo là tên của tham số và kết thúc là “-ref” nếu đối tượng phụ thuộc là một bean khác trong khung chứa của Spring, sau đó gán cho nó một giá trị. Ví dụ mình có thể khai báo đối tượng Student như sau:

Còn nếu các bạn sử dụng index để khai báo các tham số thì thì hãy khai báo một thuộc tính trong thẻ <bean> với name bắt đầu là “c:_” tiếp theo là index và cuối cùng là “-ref” nếu đối tượng phụ thuộc là một bean khác trong khung chứa của Spring, sau đó gán giá trị cho nó. Ví dụ mình có thể khai báo đối tượng Clazz như sau:

Kết quả khi chạy lại ví dụ vẫn như trên:

4/5 - (3 bình chọn)

9 thoughts on “Nói thêm về Constructor Injection trong Spring sử dụng tập tin XML

  1. em muốn hỏi là nếu class có nhiều hơn 1 constructor vd :
    pubic class Student{
    private String name;
    private String className;
    public Student(String name){
    this.name = name;
    }
    public Student(String className){
    this.className = className;
    }

    }
    thì trong thẻ constructor-arg thuộc tính value sẽ set giá trị có name, hay className trước ạ ? E cảm ơn

  2. anh ơi cho em hỏi tại sao trong cái này cái này : System.out.println(clazz.toString()); nó lại gọi lại được hàm student.toString() luôn hả anh

    1. public String toString() {
      return “Clazz [name=” + name + “, student=” + student + “]”;
      }

      trong cái này student là đối tượng nên em không hiểu tại sao nó lại trả ra cái phương thức student.toString() luôn :/

Add Comment