zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    转载:Tomcat发布项目时,浏览器地址栏图标的问题
    获取刚插入的主键
    便利map的四种方法
    Caused by: java.lang.NoClassDefFoundError: org/apache/commons/lang/exception/NestableRuntimeException
    js限制输入框只能输入整数、小数
    js如何判断小数
    错误: java.lang.ClassNotFoundException: org.apache.commons.lang3.StringUtils
    Tomcat内存溢出的三种情况及解决办法分析
    JAVA正则表达式语法大全
    HTTP Status 404(The requested resource is not available)异常解决
  • 原文地址:https://www.cnblogs.com/c04s31602/p/11210892.html
Copyright © 2011-2022 走看看