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

来源:互联网 发布:游族网络股票吧 编辑:程序博客网 时间:2024/04/29 07:30

@Inject

    @Inject支持构造函数、方法和字段注解,也可能使用于静态实例成员。可注解成员可以是任意修饰符(private,package-private,protected,public)。注入顺序:构造函数、字段,然后是方法。父类的字段和方法注入优先于子类的字段和方法,同一类中的字段和方法是没有顺序的。

    @Inject注解的构造函数可以是无参或多个参数的构造函数。@Inject每个类中最多注解一个构造函数。

    在字段注解:

  • 用@Inject注解
  • 字段不能是final的
  • 拥有一个合法的名称

    在方法上注解:

  • 用@Inject注解
  • 不能是抽象方法
  • 不能声明自身参数类型
  • 可以有返回结果
  • 拥有一个合法的名称
  • 可以有0个或多个参数

        @Inject MethodModirers ResultType Identifier(FormalParameterList ) Throws MethodBody

    [上述翻译:inject的doc文档,翻译不好敬请谅解]

    构造函数注解:

 

  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. }  

输出结果:

 

---这是房屋构造函数---
---这是人的构造函数---
张三

    上述例子在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. }  

用户接口:(对个数进行统计)

@Qualifier与@Resource区别:

  @Qualifier是spring的注解 而@Resource是javax的注解 功能虽然差不多 但是不是同一个框架 @Resource默认是根据名字注入 @Qualifier必须知道要注入的bean的id

 

  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

    使用该注解标记该类只创建一次,不能被继承。一般在类上用该注解。

原文:http://blog.csdn.net/binxigogo/article/details/7851924

0 0
原创粉丝点击