【Spring Cloud】Spring Cloud之自定義@SpringCloudProfile注解實現@Profile注解的功能


一、為什么會想到定義@SpringCloudProfile這樣的注解

首頁提一下@Profile注解:它主要用與Spring Boot多環境配置中,指定某個類只在指定環境中生效,比如swagger的配置只允許開發和測試環境開發,線上需要禁止使用。

使用@Profile進行如下配置:

@Configuration
@EnableSwagger2
@Profile({"dev", "test"})
public class Swagger2Config { @Bean public Docket docket() { return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo()).select() //當前包路徑 .apis(RequestHandlerSelectors.basePackage("com.zbq.springbootbase.controller")) .paths(PathSelectors.any()).build(); } //構建api文檔的詳細信息函數 private ApiInfo apiInfo() { return new ApiInfoBuilder() //頁面標題 .title("springboot-base-frame,使用Swagger2構建RESTful API") //創建人 .contact(new Contact("張波清", "756623607@qq.com", "")) //版本號 .version("1.0") //描述 .description("API 描述") .build(); } }

但是在Spring Cloud中由於使用了配置中心,導致啟動項目時沒有指定spring.profiles.active屬性導致@Profile注解失效,原因就是@Profile通過獲取環境變量中spring.profiles.active屬性值,與注解中設置的值進行比較,包含就生效。

所有在Spring Cloud中需要換一個環境變量來實現,正好有spring.cloud.config.profile這個變量,該變量用於指定讀取配置中心那個環境配置的,一般有這些值,dev、test、prod

二、自定義@SpringCloudProfile注解的實現

1)定義@SpringCloudProfile注解

/**
 * @author zhangboqing
 * @date 2019/11/12
 */
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional(SpringCloudProfileCondition.class)
public @interface SpringCloudProfile {

    /**
     * The set of profiles for which the annotated component should be registered.
     */
    String[] value();

}

2)實現SpringCloudProfileCondition類,用於條件匹配

/**
 * @author zhangboqing
 * @date 2019/11/12
 */
public class SpringCloudProfileCondition implements Condition {

    public static final String ACTIVE_PROFILES_PROPERTY_NAME = "spring.cloud.config.profile";

    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        MultiValueMap<String, Object> attrs = metadata.getAllAnnotationAttributes(SpringCloudProfile.class.getName());
        if (attrs != null) {
            for (Object value : attrs.get("value")) {
                if (acceptsProfiles(context,(String[]) value)) {
                    return true;
                }
            }
            return false;
        }
        return true;
    }

    public boolean acceptsProfiles(ConditionContext context,String... profiles) {
        Assert.notEmpty(profiles, "Must specify at least one profile");
        for (String profile : profiles) {
            if (StringUtils.hasLength(profile) && profile.charAt(0) == '!') {
                if (!isProfileActive(context,profile.substring(1))) {
                    return true;
                }
            }
            else if (isProfileActive(context,profile)) {
                return true;
            }
        }
        return false;
    }

    protected boolean isProfileActive(ConditionContext context,String profile) {
        validateProfile(profile);
        String property = context.getEnvironment().getProperty(ACTIVE_PROFILES_PROPERTY_NAME);
        return property.equals(profile);
    }

    protected void validateProfile(String profile) {
        if (!StringUtils.hasText(profile)) {
            throw new IllegalArgumentException("Invalid profile [" + profile + "]: must contain text");
        }
        if (profile.charAt(0) == '!') {
            throw new IllegalArgumentException("Invalid profile [" + profile + "]: must not begin with ! operator");
        }
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM