• Spring @Condition注解实例讲解


    @Condition是Spring4新增的注解,作用是在满足条件时将bean注入到Spring容器,在Spring Boot中大量用到了@Condition注解,例如@ConditionOnBean等为Spring Boot自动化配置的核心。源码:

    @Target({ElementType.TYPE, ElementType.METHOD})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface Conditional {
    
        /**
         * All {@link Condition}s that must {@linkplain Condition#matches match}
         * in order for the component to be registered.
         */
        Class<? extends Condition>[] value();
    
    }

    注解的value是一个Condition接口的实现,Condition接口源码:

    public interface Condition {
    
        /**
         * Determine if the condition matches.
         * @param context the condition context
         * @param metadata metadata of the {@link org.springframework.core.type.AnnotationMetadata class}
         * or {@link org.springframework.core.type.MethodMetadata method} being checked.
         * @return {@code true} if the condition matches and the component can be registered
         * or {@code false} to veto registration.
         */
        boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata);
    
    }

    我们做一个简单的实例,根据设置的profile不同,在Spring容器中注册的bean也不同,首先定义一个Service接口:

    public interface ProfileService {
    
        void show();
    
    }

    再定义两个实现类:

    public class ProfileDevService implements ProfileService {
    
        @Override
        public void show() {
            System.out.println("this is dev");
        }
    
    }
    public class ProfilePrdService implements ProfileService {
    
        @Override
        public void show() {
            System.out.println("this is prd");
        }
    
    }

    这两个类只能在Spring窗口中注册一个,方法就是判断profile,两个判断类:

    public class OnDevProfile implements Condition {
    
        @Override
        public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
            return context.getEnvironment().getActiveProfiles()[0].equals("dev");
        }
    
    }
    public class OnPrdProfile implements Condition {
    
        @Override
        public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
            return context.getEnvironment().getActiveProfiles()[0].equals("prd");
        }
    
    }

    这两个类都实现了Condition接口,在注解@Condition需要用到这两个类:

    @Configuration
    public class ConditionConfiguration {
    
        @Bean
        @Conditional(OnDevProfile.class)
        public ProfileService devProfileService() {
            return new ProfileDevService();
        }
    
        @Bean
        @Conditional(OnPrdProfile.class)
        public ProfileService prdProfileService() {
            return new ProfilePrdService();
        }
    
    }

    在注入bean时加上了@Condition注解,所以能否注册成功,取决于@Condition注解的value类的matchs方法返回值。

    启动一个容器:

    public static void main(String[] args) {
    
            AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
            context.getEnvironment().setActiveProfiles("prd");
            context.register(ConditionConfiguration.class);
            context.refresh();
    
            ProfileService profileService = context.getBean(ProfileService.class);
            profileService.show();
    
            context.close();
        }

    这里设置active profiles为"prd",因此控制台打印的是this is prd,将active profiles改为"dev"打印的是this is dev

  • 相关阅读:
    maven项目报错:Class path contains multiple SLF4J bindings
    ubuntu18.04 点击启动器实现窗口最小化
    Eclipse lombok get set方法报错
    try-with-resources 让java资源关闭代码更简洁
    yang文件语法格式
    RabbitMQ 交换器、持久化
    RabbitMQ 简介
    systemctl命令配置系统服务
    Karaf基础知识
    Linux shell模拟多线程拷贝
  • 原文地址:https://www.cnblogs.com/c04s31602/p/11210892.html
Copyright © 2020-2023  润新知