最新要闻
- 【环球速看料】上下五千年 熊猫第一次有了站姐
- 环球滚动:菜鸟首个航空货运中心落户深圳:包裹效率提升30%
- 昆自股份拟通过拍卖方式购买14套房产作为公司经营活动场所 评估价值为3516.56万
- 引入人工智能!米哈游刘伟:《崩坏:星穹铁道》将在NPC加入AI
- 终结者来临?让开发者都畏惧的AI真的对人类有威胁吗
- 【独家焦点】重回1元/包:中石化出品原生竹浆90抽*3层抽纸大促
- 观天下!11.98万起 广汽埃安爆款2023上新:48小时订单破万
- 我国民营火箭公司天兵科技将研发空天飞机:载100人全球任意地点往返
- 天天快报!上古卷轴五强制随从代码_上古卷轴5强制随从代码
- 天天消息!夜宿海底捞引争议!究竟谁在留宿?多数都为旅游的年轻人
- 当前资讯!00后男生坚持做副业月入万元:父母能力有限 只能靠自己
- 即时焦点:等等党赢了!全球车企正迈向产量过剩:价格战或卷土重来
- 15999元 微星泰坦GP68HX游戏本预售:16寸2.5K屏+RTX 4080
- 焦点消息!2023 LPL季后赛爆冷:BLG 3比0横扫WBG 提前进入四强
- 天天消息!韩国音乐下载网站(求专门下载韩国歌曲的网站··)
- 最新快讯!网信办:移动物联网连接数首次超移动电话用户数 已县县通5G
手机
iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?
警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案
- iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?
- 警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案
- 男子被关545天申国赔:获赔18万多 驳回精神抚慰金
- 3天内26名本土感染者,辽宁确诊人数已超安徽
- 广西柳州一男子因纠纷杀害三人后自首
- 洱海坠机4名机组人员被批准为烈士 数千干部群众悼念
家电
世界新消息丨Autoconfiguration详解——自动注入配置参数
- Autoconfiguration详解——自动注入配置参数
- 一、 理解自动装配bean
- 1. 常用注解
- 2. 定位自动装配的候选类
- 3. 条件注解
- 3.1 有关类的判断
- 3.2 有关bean的判断
- 3.3 配置条件
- 3.4 源文件条件
- 3.5 web 应用条件
- 3.6 Spel表单式条件
- 二、自动注入配置基础
- 三、注释切面 @Metrics
- 1. 注解@Metrics
- 2. 切面MetricsAspect
- 3. 自动注入AutoConfiguration
- 4. 配置文件MetricsProperties
- 5. 其它配置
- 四、自定义spring的profile限定注解
- 1. 注解@RunOnProfiles
- 2. 切面RunOnProfilesAspect
- 3. 自动注入AutoConfiguration
- 4. 其它配置
- 参考
- 一、 理解自动装配bean
Autoconfiguration详解——自动注入配置参数
一、 理解自动装配bean
1. 常用注解
@AutoConfiguration
(每个配置类都要加上)Class>[] after() default {};
Class>[] before() default {};
- 以上两个配置可以控制加载顺序;
- 不需要再增加
@Configuration
注解;
@AutoConfigureBefore
and@AutoConfigureAfter
@Configuration
@Conditional
(后面会详细讲到)@ConditianalOnClass
@ConditionalOnMissingClass
@ConditionalOnWebApplication
:只在web应用中加载;
@EnableConfigurationProperties
:配置文件参数内容,参照类RedisProperties
;@ConfigurationProperties(prefix = "spring.redis")
,该注解展示了配置文件前缀;
@DependsOn
:列举一些前置的注入bean,以备用,用在类上需要有@Component
自动扫描的时候才能生效;- 实际上控制了bean加载的顺序,优先加载指定的bean,然后加载当前bean;
- 销毁的时候,注解的bean优先与于依赖的bean销毁;
2. 定位自动装配的候选类
springboot
框架会自动扫描 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
进行引入,所以需要自动注入的Configuration
文件都写在这个文件中。每个class
一行。
这里本质上是一个自动版的@Import。
示例:
(资料图片仅供参考)
# commentsorg.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfigurationorg.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfigurationorg.springframework.boot.autoconfigure.web.servlet.HttpEncodingAutoConfiguration
如果需要引入特定的
Component
,使用@Import注解。
3. 条件注解
在所有自动装配类出现的地方,我们都因该时加上@Conditional
注解,允许使用的开发人员覆盖自动装配的bean,当然他们也可以选择什么也不做,使用默认的配置。
Spring Boot 提供了一些条件注解,可以注解在@Configuration
类或者@Bean
方法上。
3.1 有关类的判断
对于@Configuration
类来说,@ConditionalOnClass
和@ConditionalOnMissingClass
代表了在指定类存在或者不存在的时候进行加载。因为实际上注解的元数据使用ASM技术进行解析,所以可以使用value
参数来指定特定的类的class对象(可以是多个),或者使用name
参数来指定特定的类名(可以是多个),两种方式所指向的类即使不存在也不影响正常执行。
当@Bean
方法返回值是条件注解的的目标之时,可能会因为JVM加载顺序的问题导致加载失败,上文提到的两个注解可以用在@Bean
方法上。
3.2 有关bean的判断
@ConditionalOnBean
和@ConditionalOnMissingBean
,代表在指定bean存在或者不存在时加载。value
参数可以指定bean的class(多个),name
可以指定bean的名称(多个)。search
参数允许你限制ApplicationContext
即应用上下文的搜索范围,可选当前上下文,继承上层,或者是全部(默认)。
在@Bean
方法上使用时,默认参数为当前方法返回类型。
在使用@Bean注解时,建议使用具体类型而不是父类型进行指代。
3.3 配置条件
@ConditionalOnProperty
,指定配置项文件(例如dev,pro),prefix
属性规定了配置前缀,name
属性指定了应该被检查的参数。默认,所有存在且不等于false
的参数都会被匹配到,你也可以使用havingValue
和matchIfMissing
属性闯将更多的校验。
例子:@ConditionalOnProperty(name = "spring.redis.client-type", havingValue = "lettuce", matchIfMissing = true)
;
属性名 | 类型 | 解析 |
---|---|---|
name | String[] name() default {}; | 配置项全称,如果有prefix,可以省略prefix中的前缀部分 |
prefix | String prefix() default ""; | 统一的配置项前缀 |
havingValue | String havingValue() default ""; | 配置项需要匹配的内容,如果没有指定,那么配置的值等于false 时结果为false,否则结果都为true |
matchIfMissing | boolean matchIfMissing() default false; | 配置项不存在时的配置,默认为false |
3.4 源文件条件
@ConditionalOnResource
,指定源文件存在时引入。
例如:@ConditionalOnResource(resources = {"classpath:test.log"})
;
3.5 web 应用条件
@ConditionalOnWebApplication
和 @ConditionalOnNotWebApplication
,web应用或者不是web应用时启用,以下部分只要满足一个条件即为web 应用。
servlet-based
web 应用特点:
- 使用 Spring
WebApplicationContext
; - 定义了一个
session
作用域的bean; - 有一个
WebApplicationContext
;
reactive
web 应用特点:
使用了
ReactiveWebApplicationContext
;有一个
ConfigurableReactiveWebEnvironment
;
ConditionalOnWarDeployment
,仅限于使用war进行部署的场景,在嵌入式tomcat的场景里不会启用;
3.6 Spel表单式条件
ConditionalOnWarDeployment
,使用Spel表达式返回结果进行判断。
注意:在表达式中引用一个bean会导致这个bean非常早的被加载,此时还没有进行预加载(例如配置项的绑定),可能会导致不完成的加载。
二、自动注入配置基础
@EnableConfigurationProperties(CommonRedisProperties.class)
注解configuration
类;@ConfigurationProperties(prefix = "myserver")
注解配置文件类,prefix标明配置文件的前缀;public RedisTemplate
,加到需要使用的参数中即可;getRedisTemplate(CommonRedisProperties properties, RedisConnectionFactory redisConnectionFactory) META-INF
目录下添加additional-spring-configuration-metadata.json
文件,格式如下
{ "groups": [ { "name": "server", "type": "com.huawei.workbenchcommon.redis.CommonRedisProperties", "sourceType": "com.huawei.workbenchcommon.redis.CommonRedisProperties" } ], "properties": [ { "name": "myserver.database", "type": "java.lang.String", "sourceType": "org.springframework.boot.autoconfigure.web.ServerProperties" } ]}
三、注释切面 @Metrics
1. 注解@Metrics
@Retention(RetentionPolicy.RUNTIME)@Target({ElementType.METHOD, ElementType.TYPE})public @interface Metrics { /** * 在方法成功执行后打点,记录方法的执行时间发送到指标系统,默认开启 */ boolean recordSuccessMetrics() default true; /** * 在方法成功失败后打点,记录方法的执行时间发送到指标系统,默认开启 */ boolean recordFailMetrics() default true; /** * 通过日志记录请求参数,默认开启 */ boolean logParameters() default true; /** * 通过日志记录方法返回值,默认开启 */ boolean logReturn() default true; /** * 出现异常后通过日志记录异常信息,默认开启 */ boolean logException() default true; /** * 出现异常后忽略异常返回默认值,默认关闭 */ boolean ignoreException() default false;
2. 切面MetricsAspect
@Aspect@Slf4j@Order(Ordered.HIGHEST_PRECEDENCE)public class MetricsAspect { /** * 让Spring帮我们注入ObjectMapper,以方便通过JSON序列化来记录方法入参和出参 */ @Resource private ObjectMapper objectMapper; /** * 实现一个返回Java基本类型默认值的工具。其实,你也可以逐一写很多if-else判断类型,然后手动设置其默认值。 * 这里为了减少代码量用了一个小技巧,即通过初始化一个具有1个元素的数组,然后通过获取这个数组的值来获取基本类型默认值 */ private static final Map, Object> DEFAULT_VALUES = Stream .of(boolean.class, byte.class, char.class, double.class, float.class, int.class, long.class, short.class) .collect(toMap(clazz -> clazz, clazz -> Array.get(Array.newInstance(clazz, 1), 0))); public static T getDefaultValue(Class clazz) { //noinspection unchecked return (T) DEFAULT_VALUES.get(clazz); } /** * 标记了Metrics注解的方法进行匹配 */ @Pointcut("@annotation(com.common.config.metrics.annotation.Metrics)") public void withMetricsAnnotationMethod() { } /** * within指示器实现了匹配那些类型上标记了@RestController注解的方法 * 注意这里使用了@,标识了对注解标注的目标进行切入 */ @Pointcut("within(@org.springframework.web.bind.annotation.RestController *)") public void controllerBean() { } @Pointcut("@within(com.common.config.metrics.annotation.Metrics)") public void withMetricsAnnotationClass() { } @Around("controllerBean() || withMetricsAnnotationMethod() || withMetricsAnnotationClass()") public Object metrics(ProceedingJoinPoint pjp) throws Throwable { // 通过连接点获取方法签名和方法上Metrics注解,并根据方法签名生成日志中要输出的方法定义描述 MethodSignature signature = (MethodSignature) pjp.getSignature(); Metrics metrics = signature.getMethod().getAnnotation(Metrics.class); String name = String.format("【%s】【%s】", signature.getDeclaringType().toString(), signature.toLongString()); if (metrics == null) { @Metrics final class InnerClass { } metrics = InnerClass.class.getAnnotation(Metrics.class); } // 尝试从请求上下文获得请求URL RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes(); if (requestAttributes != null) { HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest(); name += String.format("【%s】", request.getRequestURL().toString()); } // 入参的日志输出 if (metrics.logParameters()) { log.info(String.format("【入参日志】调用 %s 的参数是:【%s】", name, objectMapper.writeValueAsString(pjp.getArgs()))); } // 连接点方法的执行,以及成功失败的打点,出现异常的时候记录日志 Object returnValue; Instant start = Instant.now(); try { returnValue = pjp.proceed(); if (metrics.recordSuccessMetrics()) { // 在生产级代码中,应考虑使用类似Micrometer的指标框架,把打点信息记录到时间序列数据库中,实现通过图表来查看方法的调用次数和执行时间, log.info(String.format("【成功打点】调用 %s 成功,耗时:%d ms", name, Duration.between(start, Instant.now()).toMillis())); } } catch (Exception ex) { if (metrics.recordFailMetrics()) { log.info(String.format("【失败打点】调用 %s 失败,耗时:%d ms", name, Duration.between(start, Instant.now()).toMillis())); } if (metrics.logException()) { log.error(String.format("【异常日志】调用 %s 出现异常!", name), ex); } if (metrics.ignoreException()) { returnValue = getDefaultValue(signature.getReturnType()); } else { throw ex; } } // 返回值输出 if (metrics.logReturn()) { log.info(String.format("【出参日志】调用 %s 的返回是:【%s】", name, returnValue)); } return returnValue; }
3. 自动注入AutoConfiguration
@AutoConfiguration@Slf4j@EnableConfigurationProperties(MetricsProperties.class)@ConditionalOnProperty(prefix = "common.metrics", name = {"keep-alive"}, havingValue = "true", matchIfMissing = true)public class AspectAutoConfiguration { public AspectAutoConfiguration() { log.info("AspectAutoConfiguration initialize."); } @Bean public MetricsAspect metricsAspect() { return new MetricsAspect(); }}
4. 配置文件MetricsProperties
@ConfigurationProperties(prefix = "common.metrics")public class MetricsProperties { public Boolean getKeepAlive() { return keepAlive; } public void setKeepAlive(Boolean keepAlive) { this.keepAlive = keepAlive; } private Boolean keepAlive = true;}
5. 其它配置
配置自动注入
配置resource.META-INF.spring.org.springframework.boot.autoconfigure.AutoConfiguration.imports文件,增加AspectAutoConfiguration
类路径。
配置文件提示
{ "groups": [], "properties": [ { "name": "common.metrics.keepAlive", "type": "java.lang.Boolean", "sourceType": "com.common.config.metrics.properties.MetricsProperties" } ]}
四、自定义spring的profile限定注解
1. 注解@RunOnProfiles
@Target({ElementType.METHOD,ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)@Documented@Indexedpublic @interface RunOnProfiles { /** * Profile name array,eg,dev,pro. */ String[] value() default {}; /** * Skip the code of the method of the class or method itself. */ boolean skip() default true;}
2. 切面RunOnProfilesAspect
@Aspect@Slf4j@Order(Ordered.HIGHEST_PRECEDENCE)@Componentpublic class RunOnProfilesAspect { @Autowired private ApplicationContext applicationContext; @Pointcut("@annotation(com.common.config.profiles.annotation.RunOnProfiles)") public void withAnnotationMethod() { } @Pointcut("@within(com.common.config.profiles.annotation.RunOnProfiles)") public void withAnnotationClass() { } @Around("withAnnotationMethod() || withAnnotationClass()") public Object runsOnAspect(ProceedingJoinPoint pjp) throws Throwable { var activeArray = applicationContext.getEnvironment().getActiveProfiles(); MethodSignature signature = (MethodSignature) pjp.getSignature(); RunOnProfiles runOnProfiles = signature.getMethod().getAnnotation(RunOnProfiles.class); if (runOnProfiles == null) { return null; } var profilesArray = runOnProfiles.value(); if (profilesArray == null || profilesArray.length == 0) { return pjp.proceed(); } for (var profile : profilesArray) { for (var p : activeArray) { if (p.equals(profile)) { return pjp.proceed(); } } } return null; }}
3. 自动注入AutoConfiguration
@AutoConfiguration@Slf4jpublic class RunsOnProfilesAutoConfiguration { public RunsOnProfilesAutoConfiguration() { log.info("RunsOnProfilesAutoConfiguration initialize."); } @Bean public RunOnProfilesAspect runsOnProfilesAspect() { return new RunOnProfilesAspect(); }}
4. 其它配置
配置自动注入
配置resource.META-INF.spring.org.springframework.boot.autoconfigure.AutoConfiguration.imports文件,增加RunsOnProfilesAutoConfiguration
类路径。
参考
[1] springboot doc configuration metadata
关键词:
-
世界新消息丨Autoconfiguration详解——自动注入配置参数
Autoconfiguration详解——自动注入配置参数一、理解自动装配bean1 常用注解@AutoConfiguration(每个...
来源: 天天最资讯丨Flask
世界新消息丨Autoconfiguration详解——自动注入配置参数
当前速看:1080. 根到叶路径上的不足节点
【环球速看料】上下五千年 熊猫第一次有了站姐
环球滚动:菜鸟首个航空货运中心落户深圳:包裹效率提升30%
世界焦点!计算机系统的组成(1硬件系统篇)
昆自股份拟通过拍卖方式购买14套房产作为公司经营活动场所 评估价值为3516.56万
引入人工智能!米哈游刘伟:《崩坏:星穹铁道》将在NPC加入AI
终结者来临?让开发者都畏惧的AI真的对人类有威胁吗
【独家焦点】重回1元/包:中石化出品原生竹浆90抽*3层抽纸大促
观天下!11.98万起 广汽埃安爆款2023上新:48小时订单破万
我国民营火箭公司天兵科技将研发空天飞机:载100人全球任意地点往返
债市日报:4月3日
天天快报!上古卷轴五强制随从代码_上古卷轴5强制随从代码
天天消息!夜宿海底捞引争议!究竟谁在留宿?多数都为旅游的年轻人
当前资讯!00后男生坚持做副业月入万元:父母能力有限 只能靠自己
即时焦点:等等党赢了!全球车企正迈向产量过剩:价格战或卷土重来
15999元 微星泰坦GP68HX游戏本预售:16寸2.5K屏+RTX 4080
焦点消息!2023 LPL季后赛爆冷:BLG 3比0横扫WBG 提前进入四强
dmesg 时间误差现象
天天消息!韩国音乐下载网站(求专门下载韩国歌曲的网站··)
最新快讯!网信办:移动物联网连接数首次超移动电话用户数 已县县通5G
炫富风波后中金人均降薪20万 平均收入降至约78万元
3月朋友圈疯传的十大谣言:闰月上坟祸事临门、反复烧开水致癌都是假的
首次融入生成式AI!百度地图V18版发布:数字人小姐姐“坐”你副驾
环球快看:超威超能石墨烯电池旧车挑战赛:平均续航103.6km仍余电
环球快看点丨记录--Canvas实现打飞字游戏
微信小程序订阅消息开发指南(java)
环球动态:Midjourney? 文心一格? 一张思维导图带你了解图片生成AI
张同乐-从零开始,打造高效可靠的Locust性能测试
星城控股20亿元私募债券获上交所受理
张颂文败给了新海诚?同上映11天:两部新片口碑相仿 票房差距5亿
世界速递!成都一公寓按排量收停车费每月最低1200元 官方回应:可自行定价
北野武悼念坂本龙一:朋友们都不在了 只剩下我一个人
环球新动态:无任何定语!真我GT Neo5 SE预售销量破纪录:1999元真香
世界微头条丨《小美人鱼》新镜头截图:爱丽儿抚摸王子脸 王子尬笑
极氪001车主吐槽:语音助手突然出现故障,无法语音识别指令
Flask框架cbv的写法、请求与响应、请求扩展、session源码分析、闪现
HEU KMS Activator 30.2.0全能系统数字许可激活工具 (全新激活版)
DecisionTreeClassifier&DecisionTreeClassRegression
GPT-4 还没玩透,GPT-5已遭众人围剿
Python常见面试题015.请实现一个如下功能的函数
焦点快报!任天堂或将进军手游!宣布与DeNA合作创立新公司
世界通讯!终于不用忍受熊孩子了!复兴号智能动车上线“静音车厢”
世界微资讯!真不是电影特效!武汉大暴雨白天秒变黑夜:雷电大风齐上阵
当前动态:3月新势力销量排名:理想断崖领先 第二名只卖一款车
身残技坚 国外一《守望先锋2》眼睛残疾玩家达到大师段位
【焦点热闻】《秋叶原物语2导演剪辑版》Switch中文版开启预购 4月20日发售
全球即时:统一观测丨使用 Prometheus 监控 Nginx Ingress 网关最佳实践
世界观热点:第06章 索引的数据结构
阿里云EMAS移动测试最佳实践|马来西亚第一大电子钱包通过EMAS测试提效6倍
提供一个SpringCloud Gateway获取body参数的方法
每日机构分析:4月3日
当前热门:7个摄像头走天下!大疆千元级智驾方案炸场:马斯克看了都得服
【环球热闻】2022胡润品牌榜发布:贵州茅台第一 阿里巴巴赢麻了
1999元潮玩电竞旗舰!真我GT Neo5 SE图赏
vivo X Flip真机亮相:超大外屏、紫色菱格纹吸睛
环球消息!日本8336米深海发现怪鱼:上岸就融化成“果冻状”
天天要闻:张艺兴受邀参加2023「钟表与奇迹」日内瓦高级钟表展
介绍一下requestAnimationFrame和requestIdleCallback
以 100GB SSB 性能测试为例,通过 ByteHouse 云数仓开启你的数据分析之路
验证码案例|深圳人才网信息安全
智能云呼叫中心系统的功能
云南怒江:“四聚焦”推动招商引资工作再上新台阶
天天快资讯:很良心?RTX 4070非公版亮相零售商店 这价格买不买
【全球新视野】A股公司已有51位“90后”董事长 网友:这就叫年少有为?
全球热讯:特斯拉地库“起飞” 破墙连撞6车
锐龙 9 7945HX加持!华硕ROG魔霸7 Plus超能版图赏
当前快讯:形似小鹏P7 网传小米汽车曝光?实为大运旗下、曾“溜”出展台
今日快讯:Neovim,要尝一口不?
每日关注!利用高德地图 API 显示地图信息
呼和浩特:春雨贵如油!气象部门开展人工增雨作业 助力蓄水增墒
世界看点:一个时代结束!小灵通退出日本市场 中国运营商早已抛弃
世界新消息丨ChatGPT大封号、亚洲成重灾区!网友自救喊话:不要登录、不要登录
【报资讯】业主投诉邻居每天5点剁馅:万没想到结果是只啄木鸟
北京银行短贷宝多久时间到账?北京银行短贷宝怎么申请?
朱拉隆功大学相当于国内什么大学?朱拉隆功大学留学条件
泰版流星花园花泽类的扮演者是谁?泰版流星花园演员表
郑秀妍和郑秀晶的关系是什么?郑秀妍个人简介资料
多宁生物拟香港IPO上市,招股书显示2022年净利降86%
杨迪达人秀是哪一届?杨迪在达人秀里表演的是什么节目?
环球最新:从C#中的数组中删除指定元素的几种方法,超简单
【天天新要闻】经验不足口气不小!韩国企业自研首枚商用火箭:要追上SpaceX
今日快看!摩托车、电动自行车头盔新国标正式发布:三大特点
环球热讯:每天扫码60亿次!条形码迎来50岁生日:首用于口香糖
今日热门!服务业开始了?麦当劳暂时关闭美国办公室:将通知裁员事宜
国乒官宣世乒赛参赛名单!林高远压线入围男单,林诗栋蒯曼打混双
广汉鲜花礼品
当前短讯!使用篇丨链路追踪(Tracing)其实很简单:请求轨迹回溯与多维链路筛选
天天快看:mysql/mariadb配置详解
世界报道:“5步”做好研发效能度量,打造DevOps研发管理闭环
2022年全国因公牺牲民警308名 辅警179名
世界观热点:小牛自游家汽车真要“黄了”?官方APP已停止服务
独家!RTX 4070国行价格确定:比预期贵那么一点点
每日看点!《铃芽之旅》连续10天票房日冠:观影人次第一
世界微速讯:亏电油耗5.55升 新款魏牌摩卡DHT-PHEV官图曝光:改头又换面
速递!热气球空中起火:画面骇人!致墨西哥两游客身亡
【时快讯】南阳市西峡县:寻访老君印迹 畅游紫荆花海
当前速读:大众将停产燃油版高尔夫车型,但将保留该名称用于未来的电动车型
天天观天下!云原生(一):云原生是什么