Spring Core – Phần 3: Spring Dependency Injection, DI trong Spring, so sánh CI – SI

Spring Core – Phần 3: Spring Dependency Injection, DI trong Spring, so sánh CI – SI

1. Dependency Injection là gì?

Dependency Inject là 1 kỹ thuật, 1 design pattern cho phép xóa bỏ sự phụ thuộc hard-code và làm cho ứng dụng của bạn dễ mở rộng và maintain hơn.

Về dependency Injection thì mình đã có 1 bài giới thiệu chi tiết tại: https://stackjava.com/design-pattern/dependency-injection-di-la-gi.html

Trong bài này mình sẽ chủ yếu hướng dẫn sử dụng Spring để thực hiện DI.

2. Denpendency Injection trong Spring

Bạn có thể dễ dàng thực hiện Dependency Injection bằng cách tự code, tự định nghĩa các điều kiện tạo thể hiện… Tuy nhiên trong thực tế người ta thường dùng các thư viện, framework để thực hiện Dependency Injection một cách thuật tiện, dễ hiểu hơn.

Ví dụ sử dụng thư viện CDI, các framework như Spring, JSF cũng đều hỗ trợ Denpendency Injection.

Trong Spring có 2 cách thực hiện Injection Dependency là: qua hàm khởi tạo và qua hàm setter (By Constructor / By Setter method)

Spring Core - Phần 3: Spring Dependency Injection, DI trong Spring, so sánh CI - SI

 

Code ví dụ:

<?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:p="http://www.springframework.org/schema/p"
  xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

  <bean id="helloWorld1" class="stackjava.com.springdi.demo.HelloWorld">
    <property name="message" value="inject by setter" />
  </bean>
  
  <bean id="helloWorld2" class="stackjava.com.springdi.demo.HelloWorld">
    <constructor-arg value="inject by constructor" type="String"></constructor-arg>
  </bean>

</beans>
public class HelloWorld {
  private String message;

  public HelloWorld() {
  }

  public HelloWorld(String message) {
    this.message = message;
  }

  public void setMessage(String message) {
    this.message = message;
  }

  public String getMessage() {
    return message;
  }

  public void print() {
    System.out.println("Print: " + this.message);
  }
}
public class MainApp {
  public static void main(String[] args) {
    ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
    HelloWorld helloWorld1 = (HelloWorld) context.getBean("helloWorld1");
    helloWorld1.print();
    HelloWorld helloWorld2 = (HelloWorld) context.getBean("helloWorld2");
    helloWorld2.print();

  }
}

Kết quả:

Print: inject by setter
Print: inject by constructor

3. Sự khác nhau giữa CI (Injection by Constructor) với SI (Injection by Setter)

  • Inject từng phần: bạn có thể inject từng thuộc tính bằng setter injection nhưng không thể làm với constructor.
  • Overriding: Setter injection ghi đè lại constructor injection, nếu ta dùng cả constructor và setter injection, IoC container sẽ sử dụng setter injection
  • Chuyển đổi: Ta có thể dễ dàng thay đổi giá trị bằng setter injection mà ko cần tạo một thể hiện mới của bean.

(Lưu ý: nếu sử dụng setter injection thì class của bạn phải có hàm khởi tạo mặc định không tham số, nếu dùng constructor injection thì phải có hàm khởi tạo với các tham số tương ứng với injection).

 

Download code ví dụ trên tại đây

Bài tiếp theo mình sẽ nói chi tiết hơn về những tình hướng Dependency Injection phức tạp hơn: https://stackjava.com/spring/spring-core-phan-4-spring-dependency-injection-voi-object-collections-map.html

Thanks các bạn đã theo dõi!

References: https://www.javatpoint.com/difference-between-constructor-and-setter-injection

stackjava.com