记一次Spring 配置类bean的自动装载与cong上下文获取的不同
关于Spring中Bean的自动装载和从上下文获取,我一直以为这两者获取到的对象是一样的,应该都是从容器中取出的。但是,实际工作中遇到了一个情况,让我发现这个其实还是有点区别的,花了不少时间才解决。故在此简单记录一下该问题:
问题背景:SSM框架(Spring+SpringMVC+Mybatis)
本文提及的配置类(示例):
@Component
public class MyConfig {
@Value("${api.url}")
private String apiUrl;
public String getApiUrl() {
return apiUrl;
}
public void SetApiUrl(String apiUrl) {
this.apiUrl = apiUrl;
}
}
在其他Spring组件中调用时通过@Autowired自动装配时,获取到的对象中,@Value设置的占位符可以被自动解析,而在自定义的Util类中,通过Spring上下文获取到的bean对象,@Value设置的占位符不会被自动解析,即apiUrl的值仍是${apiUrl}。
经过对比,发现了问题出在Spring的配置中。在spring-mvc.xml中有如下配置:
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="localOverride" value="true" />
<property name="locations">
<list>
<value>classpath:config.properties</value>
</list>
</property>
<property name="order" value="1" />
<property name="ignoreUnresolvablePlaceholders" value="true" />
</bean>
而spring-mybatis.xml中没有加载该配置文件,出于会不会是因为Spring上下文获取bean需要在Spring-mybatis.xml中注册的考虑,尝试性的在Spring-mybatis.xml中增加一行代码,加载该配置文件。
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:jdbc.properties</value>
<value>classpath:config.properties</value>
</list>
</property>
<property name="order" value="1" />
<property name="ignoreUnresolvablePlaceholders" value="true" />
</bean>
<value>classpath:config.properties</value>
</list>
</property>
<property name="order" value="1" />
<property name="ignoreUnresolvablePlaceholders" value="true" />
</bean>
重启了一下应用,发现这时通过上下文获取到的MyConfig对象中,${apiUrl}可以被正常解析成config.propertis对应的内容了!
思考:spring-mvc.xml及spring-mybatis.xml中的配置,在Spring容器初始化的时候不都会去加载么,那么能不能将spring-mvc.xml中的加载配置的bean删掉的?于是我又尝试了一遍,发现删掉之后,轮到通过@Autowired自动装配的对象中${apiUrl}占位符无法被解析了。。。
结论:注解自动装配读取的是spring-mvc.xml中的配置,而通过上下文获取的,则是读取spring-mybatis.xml中的配置。
关于导致这种现象的原理,本人还在学习研究,欢迎各抒己见,在评论区留言交流!
https://www.cnblogs.com/hujunzheng/p/5673377.html ---深入分析Spring 与 Spring MVC容器