@Value作用:获取配置文件的值。
注入值:在Spring容器初始化(所有的bean)之后,在当前的所在容器中获取值,然后注入。
@value是通过${}占位符去匹配加载到的配置文件中的键值对的键
通过以下配置来加载资源文件
<bean
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<!-- 允许JVM参数覆盖 -->
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
<!-- 忽略没有找到的资源文件 -->
<property name="ignoreResourceNotFound" value="true" />
<property name="order" value="1"></property>
<!-- 配置资源文件 -->
<property name="locations">
<list>
<value>classpath:env.properties</value>
</list>
</property>
</bean>
但是此配置是配置在springMVC中,springMVC在此项目中为子容器,而父容器中配置了数据库连接资源文件,各自用各自的配置,但是在控制层通过占位符${属性名}注入子容器属性时会抛出异常
Caused by: java.lang.IllegalArgumentException: Could not resolve placeholder 'REPOSITORY_PATH' in string value "${REPOSITORY_PATH}"
java.lang.IllegalArgumentException:字面意思是非法参数
但通常情况是找不到文件会抛出此异常
而这里
Could not resolve placeholder 'REPOSITORY_PATH' in string value "${REPOSITORY_PATH}"
意思是因为在控制层注入了${REPOSITORY_PATH},但是在父容器中无法解决这个REPOSITORY_PATH字符串,所以无法解析此占位符而抛出了异常
针对这个错误,并没有去剖析底层代码。而是进行了测试
[
假设两个资源文件
A.properties、B.properties
A.properties中有a = 1、b = 2、c = 3
B.properties中有c = 1、b = 3、e = 3
使用这两个资源文件在子父容器中进行测试
一、在子父容器中分别都注入A、B
运行不会抛出异常并且成功加载所有资源
二、在子父容器中各自注入其中一个
1调用子容器属性时会抛出异常
2调用父容器属性时正常
3在调用子容器中和父容器中共有的属性时不会跑出异常,但属性值会被子容器的值覆盖
综上所以得到结论
spring加载配置文件后会根据配置位置不同分别以将其内容以键值对的形式存在各自的容器中
父容器不能访问子容器的资源,子容器可以访问父容器的,但是@value又只能匹配本容器的资源,所以在子容器中匹配父容器中不存在的键会抛出上面的异常
${键} 的匹配方式,先去父容器存储键值对的地方去进行匹配,如果匹配不到则抛出异常
Caused by: java.lang.IllegalArgumentException: Could not resolve placeholder '键' in string value "${键}"
解决方案
1、在父容器配置中加入属性
<!-- 忽略无法解决的占位符 -->
<property name="ignoreUnresolvablePlaceholders" value="true" />
这个属性可以再即使父容器匹配不到的时候也不会抛出异常 继续去子容器中进行匹配
2、将子父容器中都加载资源文件,这样做比较浪费资源并且有废操作,比较业余、胜在方便
3、都在父容器中加载,在父容器的类中得到以后再注入到子容器中的类中,但这样会常见多余的对象
所以推荐使用第一种解决方案。。。
其他属性
<!-- <bean
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<!-- 允许JVM参数覆盖 -->
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
<property name="order" value="2"></property>
<!-- 忽略资源未找到
这个属性可以忽略不存在的资源文件
-->
<property name="ignoreResourceNotFound" value="true" />
<!-- 忽略无法解决的占位符 -->
<property name="ignoreUnresolvablePlaceholders" value="true" />
<!-- 配置资源文件 -->
<property name="locations">
<list>
<value>classpath:jdbc.properties</value>
</list>
</property>
</bean> -->