[Исходный код фрейма] Основная аннотация исходного кода Spring @Conditional принцип и применение

вставьте сюда описание изображения

1. Что такое аннотация @Conditional

  • @ConditionalЭто следует из spring-contextкомментария под пакетом.
  • Настройте некоторые условные суждения через @Conditional.Когда все условия будут выполнены, цель, отмеченная аннотацией @Conditional, будет обработана Spring.
  • Например, в соответствии с текущей средой, системными свойствами, файлами конфигурации и другими условиями, чтобы решить, регистрировать ли Bean-компонент или выполнять определенный компонент.

  • Сценарий приложения

    • В определенной среде необходимо зарегистрировать определенный компонент, который обычно используется для регистрации, когда компонент не существует.
    • В соответствии со свойством в файле конфигурации решить, следует ли регистрировать bean-компонент.
    • Выберите класс конфигурации в соответствии со средой, такой как тип операционной системы и версия текущей системы, чтобы определить, следует ли его выполнять.

2. Анализ исходного кода аннотации @Conditional

  • По его аннотациям можно узнать, что он чисто функциональная аннотация, он не зависит от других аннотаций, а на класс всего три метааннотации .
@Target({
    
    ElementType.TYPE, ElementType.METHOD})  //注解作用范围在接口、类、枚举、注解、方法
@Retention(RetentionPolicy.RUNTIME) //保留到运行期,jvm加载class文件之后,仍然存在
@Documented  //生成javadoc文档
public @interface Conditional {
    
    

  /**
   * All {@link Condition} classes that must {@linkplain Condition#matches match}
   * in order for the component to be registered.
   */
  Class<? extends Condition>[] value();
}
  • значение: массив типа Condition, Condition — это интерфейс, представляющий условное суждение, и внутри есть метод для возврата true или false
  • Когда все условия условия истинны, результат @Conditional истинен

Вопрос: Так что же это за состояние?

  • Условие само по себе является интерфейсом.Метод match в исходном коде оценивает, соответствует ли условие.В методе есть два параметра:

    • context context, получить информацию о компоненте в контейнере

    • метаданные: получить всю аннотационную информацию об объекте, отмеченном @Conditional

    public interface Condition {
          
          
      //判断条件是否匹配
      boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata);
    }
    
  • Давайте посмотрим на исходный код ConditionContext.

public interface ConditionContext {
    
    

  //返回bean定义注册器,用于获取Bean定义的注册表,可以用来注册和获取bean定义的各种配置信息
  BeanDefinitionRegistry getRegistry();

  //用于获取Bean工厂,可以用来获取或操作Bean实例,相当于一个ioc容器对象
  ConfigurableListableBeanFactory getBeanFactory();

  //用于获取环境变量和属性值等配置信息
  Environment getEnvironment();

  //用于获取资源文件,比如XML文件、图片、文本等
  ResourceLoader getResourceLoader();

 //用于获取类加载器,可以用来加载类或资源文件
  ClassLoader getClassLoader();

}
  • Главное здесь — BeanDefinitionRegistry, который возвращает регистр определения бина, который используется для получения реестра определения бина, которым мы воспользуемся позже.

  • Исходный код BeanDefinitionRegistry

public interface BeanDefinitionRegistry extends AliasRegistry {
    
    

	//用于向Bean定义注册表中注册一个Bean定义,参数beanName表示Bean的名称,beanDefinition表示Bean的定义信息
  void registerBeanDefinition(String beanName, BeanDefinition beanDefinition);

	//从Bean定义注册表中移除指定名称的Bean定义,参数beanName表示要移除的Bean名称
  void removeBeanDefinition(String beanName) ;

	//获取指定名称的Bean定义,参数beanName表示要获取的Bean名称
  BeanDefinition getBeanDefinition(String beanName) ;

	//判断指定名称的Bean定义是否存在于注册表中,参数beanName表示要判断的Bean名称 
  boolean containsBeanDefinition(String beanName);

	//获取所有Bean定义的名称,返回一个String数组
  String[] getBeanDefinitionNames();

	//获取Bean定义的数量。
  int getBeanDefinitionCount();

	//判断指定名称的Bean是否已经被使用,参数beanName表示要判断的Bean名称。如果该名称已经被使用,则返回true,否则返回false
  boolean isBeanNameInUse(String beanName);

}
  • Введение в BeanDefinitions
    • BeanDefinition — одна из наиболее важных концепций в контейнере Spring, которая является основой контейнера для создания и управления экземплярами Bean, абстрагирования и инкапсуляции информации об определениях Bean.
    • Описать информацию об определении компонента, включая имя компонента, тип, область действия, атрибуты и другую информацию.
    • Создание и управление бинами можно настроить и контролировать в деталях, например, указать область действия бина, указать, загружается ли он отложенно, внедряется ли он автоматически, и другие атрибуты.
  • Назначение BeanDefinition
    • Определите основную информацию о Bean-компоненте, включая имя, тип и область действия Bean-компонента.
    • Определить информацию об атрибутах Bean, включая имя, тип, значение атрибута Bean и т. д.
    • Определите информацию о жизненном цикле Bean-компонента, включая метод инициализации и метод уничтожения Bean-компонента.
    • Определите зависимости, такие как bean-компоненты, включая зависимости между bean-компонентами, методы внедрения и т. д.
    • Определить Bean и другую информацию AOP, включая аспекты, уведомления, pointcut и т. д.

3. @Conditional аннотация в случае реального боя

  • Предыстория требования: теперь в системе есть два набора источников данных, имитирующих баскетбольную мобилизацию, один официальный, а другой запасной.Только когда официальный не может играть, запасной будет играть.

  • Кодирование в действии

    Создайте объектный компонент баскетболиста

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public class BasketballPlayers {
          
          
    
        /**
         * 姓名
         */
        private String name;
    
        /**
         * 年龄
         */
        private int age;
    
        /**
         * 性别
         */
        private String sex;
    
    }
    

    Создайте класс конфигурации компонента

    public class BasketballPlayersConfig {
          
          
    
        @Bean("lixiang")
        public BasketballPlayers BasketballPlayers1(){
          
          
            return new BasketballPlayers("李祥",18,"男");
        }
        @Bean("zhangsan")
        public BasketballPlayers BasketballPlayers2(){
          
          
            return new BasketballPlayers("张三",18,"男");
        }
    
    }
    

    Пользовательский класс условий

    public class MyCondition implements Condition {
          
          
        @Override
        public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
          
          
            BeanDefinitionRegistry registry = conditionContext.getRegistry();
            //不存在,才返回true
            boolean flag = !registry.containsBeanDefinition("lixiang");
            return flag;
        }
    }
    

    вставьте сюда описание изображения

    тестовый код

    public static void main(String[] args) {
          
          
            AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
            //扫描指定的包,包括子包
            context.scan("com.lixiang");
            //里面完成初始化操作,核心方法
            context.refresh();
            Map<String, BasketballPlayers> beansOfType = context.getBeansOfType(BasketballPlayers.class);
            System.out.println(beansOfType);
        }
    

вставьте сюда описание изображения
вставьте сюда описание изображения
вставьте сюда описание изображения

Acho que você gosta

Origin blog.csdn.net/weixin_47533244/article/details/130657165
Recomendado
Clasificación