【Spring Cloud】Spring Cloud之自定义@SpringCloudProfile注解实现@Profile注解的功能
2024-08-30 14:32:31
一、为什么会想到定义@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() == '!') {
if (!isProfileActive(context,profile.substring())) {
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() == '!') {
throw new IllegalArgumentException("Invalid profile [" + profile + "]: must not begin with ! operator");
}
}
}
最新文章
- 一切Web的基础----HTTP
- 【翻译二十一】java-并发之分拆和合并
- LinkedList源码分析
- 常用的 SQL 函数
- [转]WEB开发者必备的7个JavaScript函数
- Hibernate--Enum类型的set集合映射到数据库(xml配置文件实现方式)
- 关于PYTHON_EGG_CACHE无权限的问题
- Python基础:1.数据类型(列表)
- 判断IMEI或MEID是否合法
- pytest自动化7:assert断言
- 【Java入门提高篇】Day30 Java容器类详解(十二)TreeMap详解
- C# 列出进程
- Https 忽略证书\使用自定义证书的java代码实现
- tmux 快捷操作
- C#系列之{流和序列化}
- WPF加载HTML、WPF与JavaScript交互
- The import XXX cannot be resolved
- JAVA 之 多态 抽象 接口
- docker中使用nginx容器代理其他容器
- ssvm和console 模板机 连接不上管理节点
热门文章
- LeetCode 100. Same Tree相同的树 (C++)
- 使用jQuery的replaceWith()方法要注意的地方
- 洛谷 P1919 A*B Problem升级版
- 总线宽度VS总线带宽
- [LeetCode] 119. Pascal&#39;s Triangle II 杨辉三角之二
- java byte[]和base64互相转换
- vue.js三种安装方式
- python运维开发常用模块(三)DNS处理模块dnspython
- ThinkPHP连接Oracle数据库的详细教程
- Navicat Premium 12 安装与激活