Spring аннотация @Qualifier подробный анализ

Spring Boot Java

1 Обзор

Узнай сегодняSpringв рамке@QualifierАннотация, какие проблемы он решает и как его использовать. Мы также узнаем о его@PrimaryРазница в аннотации. Для более подробного технического анализа, пожалуйста, посетитеfelord.cn

2. Болевые точки

использовать@AutowiredАннотацияSpringОтличный способ сделать внедрение зависимостей. Но в некоторых сценариях одной этой аннотации недостаточно, чтобы Spring знал, какой из них следует внедрить.bean. по умолчанию,@AutowiredСборка по типуSpring Bean. Если есть несколько контейнеров одного типаbean, фреймворк выкинетNoUniqueBeanDefinitionException, чтобы указать, что существует несколькоbeanЗаймитесь автоматической сборкой. Программа не может правильно решить какой из них использовать.Вот живой пример:

    @Component("fooFormatter")
    public class FooFormatter implements Formatter {
        public String format() {
            return "foo";
        }
    }

    @Component("barFormatter")
    public class BarFormatter implements Formatter {
        public String format() {
            return "bar";
        }
    }

    @Component
    public class FooService {
        @Autowired
        private Formatter formatter;
        
        //todo 
    }

Если мы попытаемсяFooServiceзагружается в наш контекст,Springкадр будет бросатьNoUniqueBeanDefinitionException. Это потому чтоSpringне знаю что вводитьbean. Чтобы избежать этой проблемы, есть несколько решений. Итак, что мы собираемся объяснить@QualifierАннотация — одна из них. Следуйте за ритмом маленького толстого брата и спускайтесь вниз.

3. @Qualifier

используя@Qualifierаннотацию, мы можем устранить необходимость вводить какиеbeanПроблема. Давайте вернемся к предыдущему примеру и посмотрим, как мы можем это сделать, включив@Qualifierкомментарий, чтобы указать, что мы хотим использоватьbeanрешить проблему:

    @Component
    public class FooService {
        @Autowired
        @Qualifier("fooFormatter")
        private Formatter formatter;
        
        //todo 
    }

поставив@QualifierАннотация со специфическими данными, которые мы хотим использоватьSpring beanсобраны вместе с именамиSpringКаркас может быть изготовлен из нескольких однотипных и соответствовать требованиям сборкиbeanНайдите то, что мы хотим, и избегайте разделенного мозга Spring. Все, что нам нужно сделать, это атрибут значения, объявленный в аннотации @Component или @Bean, чтобы определить имя. На самом деле мы также можемFormatterиспользовать в классе реализации@Qualifierаннотация вместо@Componentили@BeanТого же эффекта можно добиться, указав имя в:

     @Component
     @Qualifier("fooFormatter")
     public class FooFormatter implements Formatter {
         public String format() {
             return "foo";
         }
     }
 
     @Component
     @Qualifier("barFormatter")
     public class BarFormatter implements Formatter {
         public String format() {
             return "bar";
         }
     }

4. @Qualifier VS @Primary

Есть еще одно имя@PrimaryАннотация, которую мы также можем использовать, чтобы решить, что вводить, когда есть двусмысленность во внедрении зависимостей.bean. Когда есть несколько одинаковыхbean, эта аннотация определяет предпочтение. Если не указано иное, тот же@PrimaryСвязанная аннотацияbean. Давайте посмотрим на пример:

    @Bean
    public Employee tomEmployee() {
        return new Employee("Tom");
    }

    @Bean
    @Primary
    public Employee johnEmployee() {
        return new Employee("john");
    }

В этом примере оба метода возвращают одно и то жеEmployeeтип.Springбудет введеноbeanэто методjohnEmployeeвозвращениеbean. Это потому, что он содержит@Primaryаннотация. Когда мы хотим указать, что определенный тип должен вводиться по умолчаниюbean, эта аннотация полезна. Если нам нужен еще один в определенной точке впрыскаbean, мы должны указать это специально. мы можем пройти@QualifierАннотация для этого. Например, мы можем использовать@Qualifierаннотация, чтобы указать, что мы хотим использоватьtomEmployeeметод возвращенbean. Стоит отметить, что если@Qualifierи@Primaryаннотации существуют, то@QualifierКомментарии будут иметь приоритет. в основном,@Primaryопределено значение по умолчанию, и@Qualifierочень специфичен. Конечно@Componentтакже можно использовать@PrimaryОбратите внимание, на этот раз используется пример из 3 выше:

     @Component
     @Primary
     public class FooFormatter implements Formatter {
         public String format() {
             return "foo";
         }
     }
 
     @Component
     public class BarFormatter implements Formatter {
         public String format() {
             return "bar";
         }
     }

при этих обстоятельствах,@PrimaryВ аннотации указано, что инъекция по умолчаниюFooFormatter, что устраняет неоднозначность инъекции в сцене.

5. Автоматическая закачка по имени

в настоящее время использует@AutowiredПри автопроводке, еслиSpringНикаких других подсказок, будет искать подходящее имя переменной в соответствии с именем переменной, которую необходимо ввести.bean. Это также может решить проблему неоднозначности внедрения зависимостей. Давайте посмотрим на некоторый код, основанный на нашем исходном примере:

    @Component
    public class FooService {
        @Autowired
        private Formatter fooFormatter;
        
        //todo 
    }

при этих обстоятельствах,SpringопределитbeanдаFooFormatter, потому что имя поля такое же, как у нас вbeanиз@Componentили@BeanЗначение, используемое в аннотации (по умолчанию@Beanиспользуйте имя метода) для соответствия.

6. Резюме

через пару@QualifierМы знаем, что эта аннотация используется для устранения конфликтов внедрения зависимостей. Это в ежедневной разработке, напримерRabbtimqчасто встречается в объявлениях очередей. Брат Сяопан также показал некоторые общеупотребительные употребления, комбинируя и сравнивая эту аннотацию с другими вышеупомянутыми аннотациями. Это поможет вамSpringПонимание механизма внедрения зависимостей.

关注公众号:Felordcn获取更多资讯

Личный блог: https://felord.cn