SpringBoot SpringMvc 读取properties文件、yml配置文件(一次读取,永久使用)
情景展示
需求:封装一个Property工具类,读取properties文件取值,供其它Java类使用。
方式一:springmvc
import lombok.Getter; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.PropertySource; import org.springframework.stereotype.Component;
/** * properties文件工具类 * @description 在该类被加载的时候,它就会自动读取指定位置的配置文件内容并保存到静态属性中,高效且方便,一次加载,可多次使用 * @author: Marydon * @date: 2020年07月13日 0013 16:04 */ // 将该类标识为Bean,交由spring托管(使用注解@Value,该类必须是一个有Spring管理的bean对象或者带Controller注解的控制器) @Component //配置文件路径(路径引用需要加claspath:)(按住Ctrl键,鼠标悬浮上去可以打开该文件,据此可以校验路径是否正确) @PropertySource (value = "classpath:bill.properties" ,encoding = "UTF-8" ) // 对外提供取值方法 @Getter public class PropertyUtils { // 赋值 // 通过${属性名}取值并完成赋值操作 @Value ( "${bill.czSignAddress}" ) private String czSignAddress; @Value ( "${bill.czInterfaceAddress}" ) private String czInterfaceAddress; @Value ( "${bill.xcInterfaceAddress}" ) private String xcInterfaceAddress; }
@Setter和@Getter使用的是lombok插件的注解,被修饰的类,会自动生成私有属性的get()、set()方法
< dependency > < groupId >org.projectlombok < artifactId >lombok < version >1.18.12 < scope >provided
方式二:springboot
在上面导包的基础上多了2个
import lombok.Setter; import org.springframework.boot.context.properties.ConfigurationProperties;
/** * properties文件工具类 * @description 在该类被加载的时候,它就会自动读取指定位置的配置文件内容并保存到静态属性中,高效且方便,一次加载,可多次使用 * @author: Marydon * @date: 2020年07月13日 0013 16:04 */ // 将该类标识为Bean,交由spring托管(使用注解@Value,该类必须是一个有Spring管理的bean对象或者带Controller注解的控制器) @Component //所绑定的属性的前缀(不用加点.) // 使用这种方式,使得类的成员变量与properties文件的属性名称保持一致,我们可以省去赋值操作 @ConfigurationProperties (prefix = "bill" ) //配置文件路径(路径引用需要加claspath:)(按住Ctrl键,鼠标悬浮上去可以打开该文件,据此可以校验路径是否正确) @PropertySource (value = "classpath:bill.properties" ,encoding = "UTF-8" ) // 对外提供赋值方法(必须有成员变量的set方法,否则将无法完成赋值操作) @Setter // 对外提供取值方法 @Getter public class PropertyUtils { // 成员变量名称要与属性名称保持一致 private String czSignAddress; private String czInterfaceAddress; private String xcInterfaceAddress; }
添加了@ConfigurationProperties注解,这样就可以不用@Value注解进行赋值了,
取而代之的是:@Setter注解,同时,我们需要确保:成员变量名称要与属性名称保持一致。
说明:springboot也可以不使用@ConfigurationProperties注解,直接按照方式一springMVC进行配置是完全没有问题的。
关于对properties文件路径的引用还有另外一种方式:
如果不加classpath,也可以使用相对路径来实现,即/bill.properties,在idea中,按住Ctrl键,鼠标悬浮上去查看是否可以打开该文件,以此来判断路径是否正确。
@PropertySource("/bill.properties")
如何调用
要想获取到spring管理的bean对象,有4种方式
方式一:将引用的类也通过注解交由spring管理
// 要想获取spring管理的bean对象,则调用类必须是由spring管理的bean对象或者控制器,否则,即使有@Autowired注解也不生效 @Component public class XcUrlUtils { // 注入propertyUtils bean对象 @Autowired private PropertyUtils propertyUtils; // @Value引用properties文件中的属性使用"${}" // @Value引用Bean对象中的属性使用"#{}" // 赋值 @Value ( "#{propertyUtils.xcInterfaceAddress}" ) // 对外提供取值方法(如果不需要外部直接访问该变量,可以去掉该注解) @Getter private String xcOriginAddress; }
方式二:控制器
@RestController public class CzController { // 读取APPID和APPKEY @Autowired private PropertyUtils propertyUtils; // 电子票系统第三方单位服务注册APPID @Value ( "#{propertyUtils.czAppId}" ) private String APP_ID; // 电子票系统第三方单位服务注册APPKEY @Value ( "#{propertyUtils.czAppKey}" ) private String APP_KEY; }
注入后,通过@Value{"#{对象名.属性名}"}取值
方式三:调用时再取值
public class CzUrlUtils { @Autowired private PropertyUtils propertyUtils; // 接口请求地址 private String CZ_ORIGIN_ADDRESS; /* *类成员变量初始化 * @deccription: 解决propertyUtilsBean对象获取失败的问题 * @date: 2020年07月22日 0022 9:27 * @param: * @return: void */ private void initlization() { if (StringUtils.isEmpty(CZ_ORIGIN_ADDRESS)) { CZ_ORIGIN_ADDRESS = propertyUtils.getCzInterfaceAddress(); } } public String generateInterfaceUrl(String interfaceMethod) { // 接口地址初始化 initlization(); return CZ_ORIGIN_ADDRESS + "/" + interfaceMethod; } }
由于调用类不是spring管理的对象,所以要想获取spring管理的对象,只有在项目启动完毕之后,才能获取到;
如果我们按照前两种方式,直接通过@value进行赋值,启动时该类是获取不到propertyUtils对象的,会报空指针异常,为了解决这个问题,我们可以像懒加载那样,只有在需要用到CZ_ORIGIN_ADDRESS时,才对它进行赋值操作。
配好后,如果启动没有报错,基本上就没有问题了。
20201105
方式四:使用注解@PostConstruct
20201120
在spring框架中,对于能够配置到application.properties或者application.yml文件中的属性,还是配置到相应的配置文件,取值更为方便;
我们可以无数个子配置文件,想要使哪个配置文件生效,只需要在application.yml文件中指定即可。
这样一来,无论是配置在application.yml还是application-*.yml文件中属性,我们都可以通过注解@Value拿到
举个栗子:
如上图所示,我在application-dev.yml中配置了自定义属性,application.yml启用的是application-dev.yml,所以,我在java中就能直接获取到该配置文件的内容。
说明:
@Autowired, @Resource, @Value注解执行后,如果存在@PostConstrcut,会运行此注解。
注意事项
2023年5月24日14:57:04
第一,@Value注解,我们使用的是spring的注解,而不是lombok的@Value,别搞错了。
第二,当类的成员变量使用@Value注解后,不能被static修饰,不然的话,无法赋值。
这是错误的!!!
第三,在idea当中,如果我们通过@Value取值的属性具有唯一性(只在一个配置文件当中存在)的话,我们按住Ctrl键,鼠标悬浮上去,能够直接跳转到配置文件所配置的属性所在位置。
如果设置的属性在配置文件当中不存在,idea肯定找不到。
或者多个配置文件存在同一个属性(不同环境采用不同配置文件),idea将不知道该跳转到哪个配置文件当中。
2023年9月7日16:08:39
在java中,利用Properties.load()加载配置文件时,如果配置文件含有“\”,则会将反斜杠作为转义符处理,而不是作为正常字符。
所以,当我们需要在java类当中获取properties文件当中某属性值,且属性值含有反斜杠,想要其当成普通字符的话,需要再加一个反斜杠用于转义。
#2023年9月7日15:45:03
#增加wj_task_error.log路径前缀
#说明:反斜杠需要转义
wj.task.log.path.preffix=D:\\workspace-eclipse2021\\TWRS2
由上图可知,转义是由java语法造成的,与properties文件本身无关(从properties文件当中获取到的是两个反斜杠,java解析完成了一个反斜杠)。
本文来自博客园,作者:Marydon,转载请注明原文链接:https://www.cnblogs.com/Marydon20170307/p/13606372.html