加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

依赖注入 javax.inject中@Inject、@Named、@Qualifier和@Provide

发布时间:2020-12-14 05:22:23 所属栏目:百科 来源:网络整理
导读:这个是?Java?EE?6?规范?JSR?330?--?Dependency?Injection?for?Java?中的东西,也就是?Java?EE?的依赖注入。 根据?API?document?上的说明,被?@Inject?标注的构造、成员字段和方法是可注入的。 其包可以在?jcp.org?上找到,并可以在这里下载: https://cds.su

这个是?Java?EE?6?规范?JSR?330?--?Dependency?Injection?for?Java?中的东西,也就是?Java?EE?的依赖注入。

根据?API?document?上的说明,被?@Inject?标注的构造、成员字段和方法是可注入的。
其包可以在?jcp.org?上找到,并可以在这里下载:
https://cds.sun.com/is-bin/INTERSHOP.enfinity/WFS/CDS-CDS_JCP-Site/en_US/-/USD/ViewProductDetail-Start?ProductRef=dependency_injection-1.0-final-oth-JSpec@CDS-CDS_JCP



  • Spring自带的@Autowired的缺省情况等价于JSR-330的@Inject注解;
  • Spring自带的@Qualifier的缺省的根据Bean名字注入情况等价于JSR-330的@Named注解;
  • Spring自带的@Qualifier的扩展@Qualifier限定描述符注解情况等价于JSR-330的@Qualifier注解。

    用过Spring框架的我们都知道,每当生成依赖注入的时候,我们都必须生成相应类的set方法,而且要在set方法上面写上@Autowired,才能实现依赖注入,如下:

    Java代码??

    收藏代码

    1. package?com.kaishengit.web;??
    2. ??
    3. import?com.kaishengit.service.ProjectService;??
    4. import?org.springframework.beans.factory.annotation.Autowired;??
    5. import?org.springframework.stereotype.Controller;??
    6. @Controller??
    7. public?class?FolderController?{??
    8. ????private?ProjectService?projectService;??
    9. ????//set??
    10. ????@Autowired??
    11. void?setProjectService(ProjectService?projectService)?{??
    12. ????????this.projectService?=?projectService;??
    13. ????}??
    14. }??

    ?每次都要生成相应的set方法感觉好麻烦,现在如果我们使用javax.inject.jar,只需要在相应类的属性上面加上@Inject,如下代码:

    import?javax.inject.Inject;??
  • @Inject??
  • ?javax.inject.jar下载地址:https://code.google.com/p/dependency-shot/downloads/detail?name=javax.inject.jar&can=2&q=


    @Inject

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

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

    ??? 在字段注解:

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

    ??? 在方法上注解:

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

    ??????? @Inject?MethodModirers ResultType Identifier(FormalParameterList ) Throws MethodBody

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

    ??? 构造函数注解:

    [java]? view plain copy
    1. @Inject??
    2. public?House(Person?owner)?{??
    3. ????System.out.println("---这是房屋构造函数---");??
    4. ????this.owner?=?owner;??
    5. }??
    ??? 字段注解:

    copy

    1. @Inject?private?Person?owner;??
    ??? 方法注解:

    copy

      public?void?setOwner(Person?owner)?{??
    1. ????this.owner?=?owner;??
    2. }??
    ??? @Inject注解和Spring的@Autoware注解都是根据类型对其进行自动装配。

    ??? SpringUtil类:

    copy

      class?SpringUtil?{??
    1. private?static?ApplicationContext?context?=?null;??
    2. static?ApplicationContext?getApplicationContext()?{??
    3. ????????if?(context?==?null)?{??
    4. ????????????context?=?new?ClassPathXmlApplicationContext("spring.xml");??
    5. ????????}??
    6. ????????return?context;??
    7. ????}??
    8. ??
    9. static?ApplicationContext?getApplicationContext(String?path)?{??
    10. return?new?ClassPathXmlApplicationContext(path);??
    11. static?ApplicationContext?getAnnotationConfigApplicationContext(String?basePackages)?{??
    12. new?AnnotationConfigApplicationContext(basePackages);??
    13. Person类:

      copy

        import?javax.inject.Named;??
      1. ??
      2. @Named??
      3. class?Person?{??
      4. private?String?name;??
      5. public?Person()?{??
      6. ????????System.out.println("---这是人的构造函数---");??
      7. ????}??
      8. public?String?getName()?{??
      9. return?name;??
      10. void?setName(String?name)?{??
      11. this.name?=?name;??
      12. House类:

        copy

          class?House?{??
        1. ????private?Person?owner;??
        2. public?House()?{??
        3. ????????System.out.println("---这是房屋构造函数---");??
        4. public?Person?getOwner()?{??
        5. return?owner;??
        6. 测试类:

          copy

            class?Test?{??
          1. static?void?main(String[]?args)?{??
          2. ????????ApplicationContext?context?=?SpringUtil.getApplicationContext(??
          3. ????????????????"test/spring/inject/bean-inject.xml");??
          4. ????????House?house?=?(House)context.getBean("house");??
          5. ????????Person?p?=?house.getOwner();??
          6. ????????p.setName("张三");??
          7. ????????System.out.println(house.getOwner().getName());??
          8. 输出结果:

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

            ??? 上述例子在Spring3.1下测试成功,在Spring3.1下,每个构造函数只初始化一次及默认的单例形式,个人感觉如果脱离Spring环境应该每次用都会实例化新的对象,当然根据实现的jar包不同而不同,要不javax.inject下的@Singleton注解就没有什么用途了。

            @Named

            ??? @Named和Spring的@Component功能相同。@Named可以有值,如果没有值生成的Bean名称默认和类名相同。

            ??? 例如:

            copy
              @Named?class?Person??
            ??? 该bean的名称就是person。

            copy

              @Named("p")???? 如果指定名称,那么就是指定的名称喽。

              @Qualifier

              ??? 任何人都可以定义一个新的修饰语,一个qualifier注解应该满足如下条件:

              • 定义的注解类有@Qualifier,@Retention(RUNTIME)和@Documented。
              • 可以有属性
              • 可以是公共API的一部分
              • 可以用@Target注解限定使用范围

              ??? 下面是Qualifier的例子:

              Genre注解类:

              copy

                @Documented??
              1. @Retention(RetentionPolicy.RUNTIME)??
              2. @Qualifier??
              3. @Target(value?=?{ElementType.FIELD,?ElementType.PARAMETER,?ElementType.TYPE})??
              4. @interface?Genre?{??
              5. ????User?user()?default?User.STUDENT;??
              6. enum?User?{STUDENT,?TEACHER}??
              7. 用户接口:(对个数进行统计)

                copy

                  interface?IUserDAO?{??
                1. int?count();??
                2. StudentDAO:

                  copy

                    @Genre(user?=?User.STUDENT)??
                  1. class?StudentDAO?implements?IUserDAO{??
                  2. ????@Override??
                  3. int?count()?{??
                  4. ????????System.out.println("----StudentDAO----");??
                  5. return?0;??
                  6. TeacherDAO:

                    copy

                      @Genre(user?=?User.TEACHER)??
                    1. class?TeacherDAO?implements?IUserDAO?{??
                    2. @Override??
                    3. int?count()?{??
                    4. ????????System.out.println("--TeacherDAO--");??
                    5. 0;??
                    6. UserDAOProcessor:

                      copy

                        class?UserDAOProcessor?{??
                      1. ????/*对TeacherDAO类的注入,如果对StudentDAO类注入应该是:@Genre(user?=?User.STUDENT)或@Genre,因为@Genre默认的是STUDENT*/??
                      2. @Inject??
                      3. private?@Genre(user?=?User.TEACHER)?IUserDAO?userDAO;???
                      4. return?userDAO.count();??
                      5. public?IUserDAO?getUserDAO()?{??
                      6. return?userDAO;??
                      7. void?setUserDAO(IUserDAO?userDAO)?{??
                      8. this.userDAO?=?userDAO;??
                      9. }??


                      测试类:

                      copy

                        ????????UserDAOProcessor?processor?=?(UserDAOProcessor)context.getBean("userDAOProcessor");??
                      1. ????????System.out.println(processor.count());??
                      2. --TeacherDAO--
                        0

                        ??? 个人对@Qualifier的理解:

                        1. 和Spring的@Qualifier大致相同
                        2. 单独用@Inject无法满足对接口的注入,无法找到哪个具体类,所以用@Qualifier来确定注入的具体类
                        3. 用到@Qualifier的注解中可以有值、无值和用枚举类型

                        @Singleton

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

                      3. Spring自带的@Qualifier的扩展@Qualifier限定描述符注解情况等价于JSR-330的@Qualifier注解。
                      4. (编辑:李大同)

                        【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

      推荐文章
        热点阅读