使用@Value值注入及配置文件组件扫描
作者:还是转转 时间:2023-12-01 21:24:12
@Value值注入及配置文件组件扫描
spring配置文件对应的是父容器,springMVC配置文件产生的是子容器,前者一般配置数据源,事务,注解等,当然还可以进一步将一些配置细化到其他xml中;后者一般配置控制层相关的,如静态资源,视图解析器等。
系统启动的时候,先初始化父容器,然后初始化子容器。这里会涉及一个问题,如果配置组件扫描时都配置全组件扫描,就会导致service组件会被扫描两次,造成事务无法处理。
所以最好在springMVC配置文件中只做controller的扫描,在spring配置文件中扫描其他组件。
在spring的配置文件中配置:
<context:component-scan base-package="com"/>
在springMVC的配置文件中配置:
<context:component-scan base-package="com.**.controller"/>
这样就能各司其职了。
在使用中,这两个配置文件作用不同。如果要使用@Value注入一些系统配置文件中的变量时要注意:如果要在controller中使用注入的变量,需要在springMVC的配置文件中配置:
<context:property-placeholder location="classpath:{your variable file}.properties"/>
如果只在spring的配置文件中配置,那么在controller中是不会注入成功的。原因是:在项目启动时,先初始化父容器,再初始化子容器。如果两者在初始化时扫描了同样的组件,则子容器会覆盖父容器的相关的bean。子容器因为没有配置环境变量的文件bean,因此会用null覆盖掉原值(子容器能看到父容器的bean,反过来则不行)。
测试demo如下:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:applicationContext.xml",
"classpath:servlet-dispatcher.xml"})
public class InjecTest {
@Value("${ly.key}")
private String key;
@Test
public void test(){
System.out.println("注入的key为:"+key);
}
基于@Value进行注入时有两种方式,占位符和spel表达式
//占位符方式
@Value("${jdbc.url}")
private String url;
//SpEL表达方式,其中代表xml配置文件中的id值configProperties
@Value("#{configProperties['jdbc.username']}")
private String userName;
这两种方式需要在xml中配置时也是不一样的
<!--基于占位符方式 配置单个properties -->
<!--<context:property-placeholder location="conf/jdbc.properties"/>-->
<!--基于占位符方式 配置多个properties -->
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PreferencesPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:config/resource/dev/application.properties</value>
<value>classpath:config/resource/dev/lyframework.properties</value>
<value>classpath:config/resource/dev/common.properties</value>
</list>
</property>
</bean>
<!--基于SpEL表达式 配置多个properties id值为configProperties 提供java代码中使用 -->
<bean id="configProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="locations">
<list>
<value>classpath:/conf/jdbc.properties</value>
</list>
</property>
</bean>
<!--基于SpEL表达式 配置单个properties -->
<!--<util:properties id="configProperties" location="classpath:conf/jdbc.properties"/>-->
Spring @Value获取不到值
一、问题背景
这两天做东西的时候发现一个问题,在SpringMVC中使用@Value的时候,无法获取@Value对应的值。在网上查阅了各种资料之后,总结一下。
二、@Value注解的作用
为了减小耦合度,通常,将一些固定的常量放在配置文件***.properties中。
properties内容定义形式:名称=值
SAY_COUNT=10
TITLE_COUNT=10
MESSAGE_COUNT=10
BACK_COUNT=10
当需要这些常量的时候,通过加载properties文件,在需要的位置使用这些常量,当需要修改这些常量值的时候,只要在配置文件中修改就可以了。
在没有使用spring之前,想使用配置文件当中的数据必须得自己手工写代码加载配置文件。但是在使用spring的时候,这种操作可以通过在spring中添加一个配置来完成。
<context:property-placeholder location="classpath:resource/resource.properties"/>
在需要使用的地方,通过使用@Value注解,就可以自动完成注入。
@Value("${INDEX_TITLE}")
private Integer INDEX_TITLE;
三、获取不到值的情况
1)当SpringMVC与Spring整合使用的时候,在Controller中无法获取@Value对应的值。(刚开始我就是这种情况)
产生原因:只在applicationContext中添加了扫描,没有在SpringMVC对应的配置文件中扫描。
applicationContext加载的是父容器,,父容器在项目启动的时候就被加载了。SpringMVC对应的配置文件加载的是子容器,子容器可以访问父容器的对象,但是不能访问加载的配置文件。所以,如果想在SpringMVC中使用加载的配置文件,需要在SpringMVC对应的配置文件中添加相应的配置即可。
2)在service或者dao层无法获取@Value的数值。
可能情况:有多个applicationContext.xml文件,里面有多个context:property-placeholder,在web容器启动的时候同时加载了这些配置文件,这时候只会有一个配置文件中的context:property-placeholder会被加载,其他的不会被加载。
那么,当需要加载多个properties的时候,如何解决?可以用下面的方法
<context:property-placeholder location="classpath:resource/*.properties"/>
这样,将所有需要加载的properties放在一个目录之下,通过*.properties就可以加载所有的properties文件。
来源:https://blog.csdn.net/xiaoyi52/article/details/72632579
![](/images/zang.png)
![](/images/jiucuo.png)
猜你喜欢
Java设计模式之享元模式实例详解
详解三种C#实现数组反转方式
java如何使用自己的maven本地仓库详解
深入浅析Android消息机制
![](https://img.aspxhome.com/file/2023/9/85969_0s.png)
android图库播放幻灯片时按power键灭屏再亮屏显示keyguard
Java为什么占用四个字节你知道吗
![](https://img.aspxhome.com/file/2023/5/87215_0s.png)
java 如何计算同比增长工具类
C#实现上位机与欧姆龙PLC通讯(FINS)
Mybatis如何通过接口实现sql执行原理解析
![](https://img.aspxhome.com/file/2023/0/60480_0s.jpg)
Android中自定义控件的declare-styleable属性重用方案
java利用udp实现发送数据
![](https://img.aspxhome.com/file/2023/4/69734_0s.jpg)
Java新手环境搭建 Tomcat安装配置教程
![](https://img.aspxhome.com/file/2023/4/61294_0s.jpg)
一文详解Java中流程控制语句
仿orm自动生成分页SQL分享
数字金额大写转换器制作代码分享(人民币大写转换)
详解Spring Cloud Zuul中路由配置细节
![](https://img.aspxhome.com/file/2023/8/129208_0s.png)
C#编程获取客户端计算机硬件及系统信息功能示例
C#将布尔类型转换成字节数组的方法
java实现小球碰撞功能
![](https://img.aspxhome.com/file/2023/5/64105_0s.jpg)
C# 使用SharpZipLib生成压缩包的实例代码
![](https://img.aspxhome.com/file/2023/8/85738_0s.png)