【问题标题】:Spring @Autowired and @Qualifier [closed]Spring @Autowired 和 @Qualifier [关闭]
【发布时间】:2017-04-11 08:43:23
【问题描述】:

是否使用 @Autowired 自动检测到?
使用@Qualifier时,是否是通过名称进行依赖注入?
我们如何使用这些注解进行 setter 和构造函数注入?

【问题讨论】:

    标签: java spring


    【解决方案1】:

    您可以将@Qualifier@Autowired 一起使用。事实上,如果发现不明确的 bean 类型,spring 会要求你明确选择 bean,在这种情况下你应该提供限定符

    例如在以下情况下,必须提供限定符

    @Component
    @Qualifier("staff") 
    public Staff implements Person {}
    
    @Component
    @Qualifier("employee") 
    public Manager implements Person {}
    
    
    @Component
    public Payroll {
    
        private Person person;
    
        @Autowired
        public Payroll(@Qualifier("employee") Person person){
              this.person = person;
        }
    
    }
    

    编辑:

    在 Lombok 1.18.4 中,当你有 @Qualifier 时,终于可以避免构造函数注入的样板,所以现在可以执行以下操作:

    @Component
    @Qualifier("staff") 
    public Staff implements Person {}
    
    @Component
    @Qualifier("employee") 
    public Manager implements Person {}
    
    
    @Component
    @RequiredArgsConstructor
    public Payroll {
       @Qualifier("employee") private final Person person;
    }
    

    如果您使用新的 lombok.config 规则 copyableAnnotations(通过将以下内容放在项目根目录的 lombok.config 中):

    # Copy the Qualifier annotation from the instance variables to the constructor
    # see https://github.com/rzwitserloot/lombok/issues/745
    lombok.copyableAnnotations += org.springframework.beans.factory.annotation.Qualifier
    

    这是最近在最新的 lombok 1.18.4 中引入的。

    注意

    如果您使用字段或 setter 注入,则必须将 @Autowired 和 @Qualifier 放在字段或 setter 函数的顶部,如下所示(其中任何一个都可以工作

    public Payroll {
       @Autowired @Qualifier("employee") private final Person person;
    }
    

    public Payroll {
       private final Person person;
       @Autowired
       @Qualifier("employee")
       public void setPerson(Person person) {
         this.person = person;
       } 
    }
    

    如果你使用构造函数注入,那么注释应该放在构造函数上,否则代码将无法工作。像下面这样使用它 -

    public Payroll {
    
        private Person person;
    
        @Autowired
        public Payroll(@Qualifier("employee") Person person){
              this.person = person;
        }
    
    }
    

    【讨论】:

      【解决方案2】:

      @Qualifier 注解用于解决自动装配冲突,当有多个相同类型的 bean 时。

      @Qualifier 注解可以用在任何用@Component 注解的类或用@Bean 注解的方法上。此注解也可以应用于构造函数参数或方法参数。

      例如:-

      public interface Vehicle {
           public void start();
           public void stop();
      }
      

      有两个bean,Car和Bike实现Vehicle接口

      @Component(value="car")
      public class Car implements Vehicle {
      
           @Override
           public void start() {
                 System.out.println("Car started");
           }
      
           @Override
           public void stop() {
                 System.out.println("Car stopped");
           }
       }
      
      @Component(value="bike")
      public class Bike implements Vehicle {
      
           @Override
           public void start() {
                System.out.println("Bike started");
           }
      
           @Override
           public void stop() {
                System.out.println("Bike stopped");
           }
      }
      

      使用 @Autowired@Qualifier 注释在 VehicleService 中注入 Bike bean。如果你没有使用@Qualifier,它会抛出NoUniqueBeanDefinitionException

      @Component
      public class VehicleService {
      
          @Autowired
          @Qualifier("bike")
          private Vehicle vehicle;
      
          public void service() {
               vehicle.start();
               vehicle.stop();
          }
      }
      

      参考:-@Qualifier annotation example

      【讨论】:

      • 解释清楚...
      【解决方案3】:

      @Autowired 按类型自动连接(或搜索)
      @Qualifier 按名称自动连接(或搜索)
      @Qualifier 的其他替代选项是 @Primary

      @Component
      @Qualifier("beanname")
      public class A{}
      
      public class B{
      
      //Constructor
      @Autowired  
      public B(@Qualifier("beanname")A a){...} //  you need to add @autowire also 
      
      //property
      @Autowired
      @Qualifier("beanname")
      private A a;
      
      }
      

      //If you don't want to add the two annotations, we can use @Resource
      public class B{
      
      //property
      @Resource(name="beanname")
      private A a;
      
      //Importing properties is very similar
      @Value("${property.name}")  //@Value know how to interpret ${}
      private String name;
      }
      

      更多关于@value

      【讨论】:

        猜你喜欢
        • 2011-12-12
        • 2020-09-01
        • 2016-12-05
        • 1970-01-01
        • 2019-11-15
        • 2019-06-08
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多