微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

依赖注入 javax.inject中@Inject、@Named、@Qualifier和@Provider用法

这个是JavaEE6规范JSR330--DependencyInjectionforJava中的东西,也就是JavaEE的依赖注入。

根据APIdocument上的说明,被@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. packagecom.kaishengit.web;
    2. importcom.kaishengit.service.ProjectService;
    3. importorg.springframework.beans.factory.annotation.Autowired;
    4. importorg.springframework.stereotype.Controller;
    5. @Controller
    6. publicclassFolderController{
    7. privateProjectServiceprojectService;
    8. //set
    9. @Autowired
    10. voidsetProjectService(ProjectServiceprojectService){
    11. this.projectService=projectService;
    12. }
    13. }

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

    importjavax.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个或多个参数

    @InjectMethodModirers ResultType Identifier(FormalParameterList ) Throws MethodBody

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

    构造函数注解:

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

    copy

    1. @InjectprivatePersoNowner;
    方法注解:

    copy

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

    SpringUtil类:

    copy

      classSpringUtil{
    1. privatestaticApplicationContextcontext=null;
    2. staticApplicationContextgetApplicationContext(){
    3. if(context==null){
    4. context=newClasspathXmlApplicationContext("spring.xml");
    5. }
    6. returncontext;
    7. staticApplicationContextgetApplicationContext(Stringpath){
    8. returnnewClasspathXmlApplicationContext(path);
    9. staticApplicationContextgetAnnotationConfigApplicationContext(StringbasePackages){
    10. newAnnotationConfigApplicationContext(basePackages);
    11. Person类:

      copy

        importjavax.inject.Named;
      1. @Named
      2. classPerson{
      3. privateStringname;
      4. publicPerson(){
      5. System.out.println("---这是人的构造函数---");
      6. }
      7. publicStringgetName(){
      8. returnname;
      9. voidsetName(Stringname){
      10. this.name=name;
      11. House类:

        copy

          classHouse{
        1. privatePersoNowner;
        2. publicHouse(){
        3. publicPersongetowner(){
        4. returnowner;
        5. 测试类:

          copy

            classTest{
          1. staticvoidmain(String[]args){
          2. ApplicationContextcontext=SpringUtil.getApplicationContext(
          3. "test/spring/inject/bean-inject.xml");
          4. Househouse=(House)context.getBean("house");
          5. Personp=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
              @NamedclassPerson
            该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. @interfaceGenre{
              5. Useruser()defaultUser.STUDENT;
              6. enumUser{STUDENT,TEACHER}
              7. 用户接口:(对个数进行统计

                copy

                  interfaceIUserDAO{
                1. intcount();
                2. StudentDAO:

                  copy

                    @Genre(user=User.STUDENT)
                  1. classStudentDAOimplementsIUserDAO{
                  2. @Override
                  3. intcount(){
                  4. System.out.println("----StudentDAO----");
                  5. return0;
                  6. TeacherDAO:

                    copy

                      @Genre(user=User.TEACHER)
                    1. classTeacherDAO@Override
                    2. intcount(){
                    3. System.out.println("--TeacherDAO--");
                    4. 0;
                    5. UserDAOProcessor:

                      copy

                        classUserDAOProcessor{
                      1. /*对TeacherDAO类的注入,如果对StudentDAO类注入应该是:@Genre(user=User.STUDENT)或@Genre,因为@Genre认的是STUDENT*/
                      2. @Inject
                      3. private@Genre(user=User.TEACHER)IUserDAOuserDAO;
                      4. returnuserDAO.count();
                      5. publicIUserDAOgetUserDAO(){
                      6. returnuserDAO;
                      7. voidsetUserDAO(IUserDAOuserDAO){
                      8. this.userDAO=userDAO;
                      9. }


                      测试类:

                      copy

                        UserDAOProcessorprocessor=(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. 原文地址:https://www.jb51.cc/javaschema/283289.html

                        版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

                        相关推荐