SpringBoot系列之@PropertySource和@Value注解(⼆)
前⾔
本⽂我们来看看在Spring中如何使⽤@PropertySource和@Value注解从属性⽂件读取值,同时呢我们也将讨论有关Spring Environment接⼝的信息以及相应的XML配置。@PropertySource注解主要使⽤Spring的Environment接⼝从属性⽂件中读取,事实上,此注解位于@Configuration类上,⽽ Spring @Value注解可⽤于在字段或⽅法上指定表达式,常见的例⼦是从.properties⽂件中指定属性以及默认值,接下来我们⼀起来看看。
@PropertySource和@Value注解
⾸先我们在resources⽂件夹下创建⼀个名为config.properties的⽂件,内容如下:
接下来我们在上⼀节所创建的SpringConfig配置⽂件中添加⼀个name字段,如下:
package com.demo.springboot;
import org.springframework.beans.factory.annotation.Value;
import t.annotation.Bean;
import t.annotation.Configuration;
import t.annotation.PropertySource;
@Configuration
@PropertySource(value = "classpath:config.properties")
public class SpringConfig {
@Value("${name}")
public String name;
@Bean
public UserDAL getUserDAL() {
System.out.println(name);
return new UserDAL();
}
}
我们通过@PropertySource注解声明配置⽂件存放的地⽅,⼀般来讲如果是内部配置⽂件约定是放在spring默认为我们创建的resources⽂件夹下,当然我们也可以在此⽂件夹下创建⽬录,同时更改注解存放的地址即可。如果要读取的值存放到内部不同⽂件夹或者内部和外部,此时我们需要使⽤
@PropertySources,要是读取的多个配置⽂件中对应的键⼀样,此时会以最后读取的配置⽂件中的值进⾏覆盖,⽐如如下b配置⽂件中也存在name,那么配置⽂件中的值将覆盖a配置⽂件中的值。
@PropertySources({@PropertySource("classpath:a.properties"),@PropertySource("classpath:b.properties")})
我们通过注解@Value来读取到的配置⽂件中的值,其中$符号相信我们都不陌⽣,起到占位符的作⽤。此时我们不禁想,要是指定配置⽂件不存在或者到的配置⽂件中的值和声明注解的占位符不匹配会怎样呢?下⾯我们将我们创建的配置⽂件中的name修改为如下名称,此时将抛出如下异常:
name11=Jeffcky
同理对于配置⽂件中未查到,那更加值也将不存在也会抛出如上异常,由于映射值是交给spring内置在处理,我们可能完全捕捉不到这种异常,所以为了解决映射出现异常情况,我们需要给个默认值,对name字段进⾏如下修改:
@Value("${name:}")
public String name;
在占位符中通过冒号指定若映射值不存则使⽤上述默认空字符串,很完美的解决了这个问题,此时我们打印出如下空字符串
在开头我们讲解到注解@PropertySource是添加到了Spring Environment接⼝中,所以我们可以从Spring IOC容器中获取该接⼝,同样也可以获取上述name 值,如下:
package com.demo.springboot;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import t.annotation.Bean;
import t.annotation.Configuration;
import t.annotation.PropertySource;
import nv.Environment;
@Configuration
@PropertySource(value = "classpath:config.properties")
public class SpringConfig {
@Autowired
private Environment environment;
@Bean
public UserDAL getUserDAL() {
System.out.Property("name"));
return new UserDAL();
}
}
上述我们讲解了映射的占位符不匹配的问题,要是映射的占位符到了,但是值的类型不匹配该咋办呢?⽐如如下,将抛出异常:
org.springframework.beans.factory.UnsatisfiedDependencyException:  Cannot convert value of type 'java.lang.String' to required type 'apache.xpath.internal.operations.String'.....
当然上述情况是及其不可能发⽣的,我是⼿贱搞了快捷⽅式看都没看,发现也是字符串怎么会抛出如上异常,搞了⼀会才发现导⼊的包搞错了。要是我们将配置⽂件中name修改为1.0,同时我们将字段name类型修改为int,此时会怎样呢?
Failed to convert value of type 'java.lang.String' to required type 'int'; nested exception is java.lang.NumberFormatException: For input string: "1.0"
此时将出现映射类型不匹配的情况,⾸先确认到底是映射类型是否为int,若是将配置⽂件中类型修改1,或者进⾏如下修改:
@Value("#{new Double('${name}')}")
public int name;
或者
@Value("#{T(Double).parseDouble('${name}')}")
public int name;
否则将字段类型修改为double(当然包装类型也可)。如下:
resource和autowired注解的区别
@Value("${name}")
public double name;
如上我们⼀直讨论的是将配置⽂件放在spring resources⽬录下,要是我们现在将上述配置⽂件放在其他⽬录(外部⽬录)呢,⽐如如下:
org.springframework.beans.factory.BeanDefinitionStoreException:...... class path resource [config.properties] cannot be opened because it does not exist
对于内部⽬录即放在resources⽬录下,声明注解@PropertySource时参数使⽤classpath,⽽对于外部⽬录声明注解@PropertySource时参数使⽤file。如下:
@PropertySource(value = "file:../../config.properties")
此时我们发现同样会抛出异常,只不过内容不⼀样⽽已。这是因为⽆论是将⽂件放在内外部,路径必须绝对路径⽽⾮相对路径,只不过将⽂件放在内部默认⽬录是resources⽽已。
org.springframework.beans.factory.BeanDefinitionStoreException: ....... nested exception is java.io.FileNotFoundException: ..\..\config.properties (系统不到指定的⽂件。)
针对Windows系统⽽⾔,我们可使⽤定义环境变量来解决,这⾥需要注意,定义完环境变量后,此时需要重启idea才能重新加载系统定义的环境变量,否则不⽣效,如下:
@PropertySource(value = "file:${Test}/config.properties")
总结
本⽂我们详细讲解了@PropertySource和@Value注解,针对读取外部配置⽂件其实还有⼀些细节需要深⼊,这⾥并未过多深讨,等待哪天再次有了更多积累会进⼀步分析,好了,感谢阅读本⽂的您,我们下节见。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。