07/09/2018, 16:08

Sử dụng anotation @Name và @Inject trong java.

Trước hết mình sẽ đi qua việc sử dụng bean trong Spring để các bạn dễ hình dung. Khi sử dụng Spring để tạo một bean bạn khai báo như sau. <bean id="textEditor" class="com.kipalog.TextEditor"/> Trong đó textEditor là tên thực thể của lớp TextEditor. Điểu này tương đương với việc: ...

Trước hết mình sẽ đi qua việc sử dụng bean trong Spring để các bạn dễ hình dung.

Khi sử dụng Spring để tạo một bean bạn khai báo như sau.

<bean id="textEditor" class="com.kipalog.TextEditor"/>

Trong đó textEditor là tên thực thể của lớp TextEditor. Điểu này tương đương với việc:

 TextEditor textEditor = new TextEditor();

Giả sử

Mã nguồn của lớp TextEditor.

package com.kipalog;

public class TextEditor {
   private SpellChecker spellChecker;

   // a setter method to inject the dependency.
   public void setSpellChecker(SpellChecker spellChecker) {
      System.out.println("Inside setSpellChecker." );
      this.spellChecker = spellChecker;
   }

   // a getter method to return spellChecker
   public SpellChecker getSpellChecker() {
      return spellChecker;
   }

   public void spellCheck() {
      spellChecker.checkSpelling();
   }
}

Mã nguồn của lớp SpellChecker:

package com.kipalog;

public class SpellChecker {
   public SpellChecker(){
      System.out.println("Inside SpellChecker constructor." );
   }

   public void checkSpelling(){
      System.out.println("Inside checkSpelling." );
   }

}

Để gán một bean vào trong một bean khác bạn sử dụng tag property, hay còn gọi là inject.

<bean id="textEditor" class="com.kipalog.TextEditor">
  <property name="spellChecker">
    <bean id="spellChecker" class="com.kipalog.SpellChecker"/>
  </property>
</bean>

Với khai báo này tương đương với việc bạn làm:

SpellChecker spellChecker = new SpellChecker();
TextEditor textEditor = new TextEditor();
textEditor.spellChecker = spellChecker;

Trong trường hợp bạn có nhiều bean, trong các bean có nhiều property thì việc khai báo như thế sẽ rất mất thời gian và đôi khi khiến bạn dễ nhầm lẫn. Từ Spring 3.0 trờ lên bạn có thể kết hợp với các annotation của Java để tối ưu việc khai báo các bean này.
Sau đây mình sẽ đưa ra một các tiếp cận 2 annotation @Named và @Inject cho thật dễ hiểu.

Sử dụng để khai báo tên thực thể của một bean chính là id của bean, được đặt ngay trên vị trí khai báo Class. Ví dụ

@Named
public class TextEditor {
}

@Named
public class SpellChecker {
}

Với kiểu sử dụng này mặc định lp TextEditor đã được ánh xạ vào bean thông qua id textEditor. Lớp SpellChecker ánh xạ thông qua id spellChecker .Có thể đổi tên thực thể tùy ý bằng cách.

@Named("tên thực thể")
public class TextEditor {
}

Bạn đã có một bean là textEditor và một bean spellChecker để inject spellChecker vào textEditor bạn chỉ cần khai báo theo một 3 cách sau:

Thông qua constructor.

public class TextEditor {
    private SpellChecker spellChecker;

    @Inject
    public TextEditor(spellChecker SpellChecker) {
        this.spellChecker = spellChecker;
    }
}

Việc sử dụng có nghĩa là spellChecker sẽ có giá trị ngay khi TextEditor được khởi tạo.

Thông qua fields.

public class TextEditor {
    @Inject
    private SpellChecker spellChecker;
}

Thông qua method

public class TextEditor {
    private SpellChecker spellChecker;

    @Inject
   public void setSpellChecker(SpellChecker spellChecker) {
      System.out.println("Inside setSpellChecker." );
      this.spellChecker = spellChecker;
   }
}

Với việc sử dụng @inject thông qua method và field thì spellChecker không thể sử dụng trong hàm contructor vì nó được inject sau khi hàm constructor đã chạy xong.
Mã nguồn https://github.com/canhlinh/SpringInjectExample

Ngoài việc sử dụng Inject với Spring, nhiều thư viện java khác cũng đã hỗ trợ các annotation trên như dagger https://github.com/google/dagger thường được sử dụng trong lập trình Android. Về ý nghĩa hành vi của các anotation trên tương tự.

0