青岛做网站的好公司,张掖交通建设投资有限责任公司网站,哈尔滨专业网站建设哪个好,调用wordpress数据库id#x1f4e2; 大家好#xff0c;我是 【战神刘玉栋】#xff0c;有10多年的研发经验#xff0c;致力于前后端技术栈的知识沉淀和传播。 #x1f497; #x1f33b; CSDN入驻不久#xff0c;希望大家多多支持#xff0c;后续会继续提升文章质量#xff0c;绝不滥竽充数… 大家好我是 【战神刘玉栋】有10多年的研发经验致力于前后端技术栈的知识沉淀和传播。 CSDN入驻不久希望大家多多支持后续会继续提升文章质量绝不滥竽充数欢迎多多交流。 文章目录 写在前面的话SB 读取配置的方式Value 知识扩展三种方式用法集合与Map注入配合 PropertySource使用的注意事项源码简单分析 总结陈词 写在前面的话
Java 程序猿在面向 SpringBoot 开发的时候读取配置文件信息是一个日常需求Value 应该屡见不鲜了这边对知识做一个汇总方便查阅。 Tips近期在更新程序猿入职必会系列还在进行中先更换一个知识点调剂一下每天都有新东西。 系列文章 《程序猿入职必会1 · 搭建拥有数据交互的 SpringBoot 》 《程序猿入职必会2 · 搭建具备前端展示效果的 Vue》 SB 读取配置的方式
先看一下基础知识SpringBoot 开发中需要读取application.yml或Nacos上的配置信息可以使用下面两种方式。
方式一使用Value读取 配置属性使用Value(“${my.name}”)方式注入成员变量Value是实现把配置文件的单个属性的提取。 属性若不存在启动时候就会报错如下所示 为防止这种情况可以指定默认值例如
Value(${system.defaultReply:不能识别的信息})
private String defaultReply;Value(${sql.maxRow:1000})
private String maxRow;//#{SPEL} Spring表达式
Value(#{11*2}) // 字面量
Value(true) Tips添加上冒号代表后面是默认值冒号后面是空的代表空字符串推荐都加上否则生产环境差异会导致异常。。 方式二使用 ConfigurationProperties 绑定实体 Value 仅适合单个属性的情况如果属性很多建议用绑定实体的方式。 ConfigurationProperties可以实现把配置文件的某前缀开始的key自动映射为实体的初值。 1、添加相应的配置文件信息
ali:oss:accessKeyId: LTAI4FhYdxC7YY8RR6shfXjkaccessKeySecret: LmVvWUJCQzdQpJyX621Xnf43GasQDObucketName: cjwmy1013endPoint: oss-cn-beijing.aliyuncs.comfileHost: https://cjwmy1013.oss-cn-beijing.aliyuncs.com/2、新建一个实体和配置文件对应如下
Component
ConfigurationProperties(prefix ali.oss)
Data
public class AliOSSProperties {private String accessKeyId;private String accessKeySecret;private String endPoint;private String bucketName;private String fileHost;
}
3、注入实体使用。
Autowired
private AliOSSProperties aliOss;4、引入 configuration-processor 依赖这样绑定后可以有提示也可以跳转如下
!-- 配置文件对应 --
dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-configuration-processor/artifactIdoptionaltrue/optional
/dependency补充配置文件和属性不匹配也不会报错需要校验可以添加Validated和NotNull注解如下
ConfigurationProperties(prefix author)
Validated
Component
public class AuthorBean {NotNullprivate String name;
}Value 知识扩展
Value属于 Spring 的注解在spring-beans包下可以在字段、方法参数、构造函数参数等上面使用通常用于属性注入支持 SpEL 表达式来注入值同时也支持属性占位符注入值。
三种方式用法
1、配置文件读取值 这个也是最常见的从配置文件读取值即application.yml 或 application.properties。 和前面介绍的一样建议添加上一个默认值否则配置不存在会报错。
Value(${spring.application.name:})
private String name;2、直接赋值 直接注入字符串有点类似于直接给属性赋值一样感觉多此一举实际开发当中这种应用场景非常少。
Value(战神)
private String name;3、SpEl 表达式赋值 #{} 方式表示 SpEl 表达式通常用来注入Bean对象。 还有很多强大的用法可以自行掌握。
Component
public class MyService {Value(#{myBean})private MyBean myBean;
}Component
public class MyBean {// ...
}集合与Map注入
test:array: aaa,bbb,cccmap: {name: zhangsan, sex: male} // 数组
Value(${test.array:})
private String[] array1;// 集合
Value(${test.array:})
private ListString list1;// Map
Value(#{${test.map}})
private MapString,String map1;配合 PropertySource
Springboot 默认读取的都是 application.yml 或 application.properties但是有时候我们想把一些配置给独立起来这时候可以采用PropertySource。
Component
PropertySource(value demo.properties)
public class ReadByProperty {Value(${demo.name})private String name;
} 使用的注意事项
使用Value前提 1、不能直接作用于静态变量static 2、不能直接作用于常量final; 3、不能在非注册的类中使用类需要被注册在spring上下文中如用Service,RestController,Component等 4、使用这个类时只能通过依赖注入的方式用new的方式是不会自动注入这些配置的。
静态变量注入 使用 Value 注解是不允许在 static 变量注入的包括 get 方法也是直接会获取 null 值。 原因很简单Value 围绕的是注入到spring容器当中的这个单例对象而 static 是类变量所以肯定不可以的。可以理解为 类变量初始化优先于 Spring 对象注入所以他无法注入进去。 解决方案可以通过方法注入或者通过PostConstruct等初始化逻辑注入总之就是简洁注入。
Configuration
public class MyConfig {public static String name;Value(${spring.application.name})public void initName(String param) {name param;}
}Configuration
public class MyConfig {public static String name;Value(${spring.application.name})private String param;PostConstructpublic void init(){name param;}
}源码简单分析
以下面代码为例值是怎么设置进去的呢
Value(${spring.application.name:})
private String authorName;Value 实际上是通过 org.springframework.beans.factory.config.BeanPostProcessor 来执行的实际负责做事的是其实现类 AutowiredAnnotationBeanPostProcessor它负责检查是否有这个注解的存在。 看一下源码追踪入口是 AutowiredAnnotationBeanPostProcessor#AutowiredFieldElement#inject 这里九曲十八弯过程省略DefaultListableBeanFactory 当中的 doResolveDependency 方法通过表达式得到真正的值不同方式的获取逻辑略有差异。 最后将得到的值通过反射Field的set赋值。 Tips由于本篇文章不是专门的源码分析篇简单介绍一下定位方式源码还是要自己动手看来得真切。 总结陈词
此篇文章介绍了Value在项目中得常见用法仅供学习参考。 后续会逐步分享企业实际开发中的实战经验有需要交流的可以联系博主。