javax.inject中@Inject、@Named、@Qualifier和@Provider用法

@Inject java

    @Inject支持構造函數、方法和字段註解,也可能使用於靜態實例成員。可註解成員能夠是任意修飾符(private,package-private,protected,public)。注入順序:構造函數、字段,而後是方法。父類的字段和方法注入優先於子類的字段和方法,同一類中的字段和方法是沒有順序的。 spring

    @Inject註解的構造函數能夠是無參或多個參數的構造函數。@Inject每一個類中最多註解一個構造函數。 ide

    在字段註解: 函數

  • 用@Inject註解
  • 字段不能是final的
  • 擁有一個合法的名稱

    在方法上註解: 測試

  • 用@Inject註解
  • 不能是抽象方法
  • 不能聲明自身參數類型
  • 能夠有返回結果
  • 擁有一個合法的名稱
  • 能夠有0個或多個參數

        @Inject MethodModirers ResultType Identifier(FormalParameterList ) Throws MethodBody this

    [上述翻譯:inject的doc文檔,翻譯很差敬請諒解]
spa

    構造函數註解: .net

  1. @Inject  
  2. public House(Person owner) {  
  3.     System.out.println("---這是房屋構造函數---");  
  4.     this.owner = owner;  
  5. }  
    字段註解:
  1. @Inject private Person owner;  
    方法註解:
  1. @Inject  
  2. public void setOwner(Person owner) {  
  3.     this.owner = owner;  
  4. }  
    @Inject註解和Spring的@Autoware註解都是根據類型對其進行自動裝配。

    SpringUtil類: 翻譯

  1. public class SpringUtil {  
  2.     private static ApplicationContext context = null;  
  3.     public static ApplicationContext getApplicationContext() {  
  4.         if (context == null) {  
  5.             context = new ClassPathXmlApplicationContext("spring.xml");  
  6.         }  
  7.         return context;  
  8.     }  
  9.   
  10.     public static ApplicationContext getApplicationContext(String path) {  
  11.         return new ClassPathXmlApplicationContext(path);  
  12.     }  
  13.   
  14.     public static ApplicationContext getAnnotationConfigApplicationContext(String basePackages) {  
  15.         return new AnnotationConfigApplicationContext(basePackages);  
  16.     }  
  17. }  
Person類:
  1. import javax.inject.Named;  
  2.   
  3. @Named  
  4. public class Person {  
  5.     private String name;  
  6.   
  7.     public Person() {  
  8.         System.out.println("---這是人的構造函數---");  
  9.     }  
  10.   
  11.     public String getName() {  
  12.         return name;  
  13.     }  
  14.   
  15.     public void setName(String name) {  
  16.         this.name = name;  
  17.     }  
  18. }  
House類:
  1. @Named  
  2. public class House {  
  3.     @Inject private Person owner;  
  4.     public House() {  
  5.         System.out.println("---這是房屋構造函數---");  
  6.     }  
  7.   
  8.     public Person getOwner() {  
  9.         return owner;  
  10.     }  
  11.   
  12.     public void setOwner(Person owner) {  
  13.         this.owner = owner;  
  14.     }  
  15. }  
測試類:
  1. public class Test {  
  2.     public static void main(String[] args) {  
  3.         ApplicationContext context = SpringUtil.getApplicationContext(  
  4.                 "test/spring/inject/bean-inject.xml");  
  5.         House house = (House)context.getBean("house");  
  6.         Person p = house.getOwner();  
  7.         p.setName("張三");  
  8.         System.out.println(house.getOwner().getName());  
  9.     }  
  10. }  
輸出結果:

---這是房屋構造函數---
---這是人的構造函數---
張三 orm

    上述例子在Spring3.1下測試成功,在Spring3.1下,每一個構造函數只初始化一次及默認的單例形式,我的感受若是脫離Spring環境應該每次用都會實例化新的對象,固然根據實現的jar包不一樣而不一樣,要不javax.inject下的@Singleton註解就沒有什麼用途了。

@Named

    @Named和Spring的@Component功能相同。@Named能夠有值,若是沒有值生成的Bean名稱默認和類名相同。

    例如:

  1. @Named public class Person  
    該bean的名稱就是person。
  1. @Named("p"public class Person  
    若是指定名稱,那麼就是指定的名稱嘍。

@Qualifier

    任何人均可以定義一個新的修飾語,一個qualifier註解應該知足以下條件:

  • 定義的註解類有@Qualifier,@Retention(RUNTIME)和@Documented。
  • 能夠有屬性
  • 能夠是公共API的一部分
  • 能夠用@Target註解限定使用範圍

    下面是Qualifier的例子:

Genre註解類:

  1. @Documented  
  2. @Retention(RetentionPolicy.RUNTIME)  
  3. @Qualifier  
  4. @Target (value = {ElementType.FIELD, ElementType.PARAMETER, ElementType.TYPE})  
  5. public @interface  Genre {  
  6.     User user() default User.STUDENT;  
  7.     public enum User {STUDENT, TEACHER}  
  8. }  
用戶接口:(對個數進行統計)
  1. public interface IUserDAO {  
  2.     int count();  
  3. }  
StudentDAO:
  1. @Named  
  2. @Genre(user = User.STUDENT)  
  3. public class StudentDAO implements IUserDAO{  
  4.     @Override  
  5.     public int count() {  
  6.         System.out.println("----StudentDAO----");  
  7.         return 0;  
  8.     }  
  9.   
  10. }  
TeacherDAO:
  1. @Named  
  2. @Genre(user = User.TEACHER)  
  3. public class TeacherDAO implements IUserDAO {  
  4.   
  5.     @Override  
  6.     public int count() {  
  7.         System.out.println("--TeacherDAO--");  
  8.         return 0;  
  9.     }  
  10. }  
UserDAOProcessor:
  1. @Named  
  2. public class UserDAOProcessor {  
  3.     /*對TeacherDAO類的注入,若是對StudentDAO類注入應該是:@Genre(user = User.STUDENT)或@Genre,由於@Genre默認的是STUDENT*/  
  4.     @Inject  
  5.     private @Genre(user = User.TEACHER) IUserDAO userDAO;   
  6.   
  7.     public int count() {  
  8.         return userDAO.count();  
  9.     }  
  10.   
  11.     public IUserDAO getUserDAO() {  
  12.         return userDAO;  
  13.     }  
  14.   
  15.     public void setUserDAO(IUserDAO userDAO) {  
  16.         this.userDAO = userDAO;  
  17.     }  
  18. }  


測試類:

  1. public class Test {  
  2.     public static void main(String[] args) {  
  3.         ApplicationContext context = SpringUtil.getApplicationContext(  
  4.                 "test/spring/inject/bean-inject.xml");  
  5.         UserDAOProcessor processor = (UserDAOProcessor)context.getBean("userDAOProcessor");  
  6.         System.out.println(processor.count());  
  7.     }  
  8. }  
輸出結果:

--TeacherDAO--
0

    我的對@Qualifier的理解:

  1. 和Spring的@Qualifier大體相同
  2. 單獨用@Inject沒法知足對接口的注入,沒法找到哪一個具體類,因此用@Qualifier來肯定注入的具體類
  3. 用到@Qualifier的註解中能夠有值、無值和用枚舉類型

@Singleton

    使用該註解標記該類只建立一次,不能被繼承。通常在類上用該註解。

相關文章
相關標籤/搜索