使用@Value值注入及配置文件组件扫描


Posted in Java/Android onJuly 09, 2021

@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文件。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Java/Android 相关文章推荐
Spring Bean的实例化之属性注入源码剖析过程
Jun 13 Java/Android
Feign调用传输文件异常的解决
Jun 24 Java/Android
Java集成swagger文档组件
Jun 28 Java/Android
分析并发编程之LongAdder原理
Jun 29 Java/Android
总结Java对象被序列化的两种方法
Jun 30 Java/Android
Java 语言中Object 类和System 类详解
Jul 07 Java/Android
logback 实现给变量指定默认值
Aug 30 Java/Android
java中用float时,数字后面加f,这样是为什么你知道吗
Sep 04 Java/Android
SpringBoot中获取profile的方法详解
Apr 08 Java/Android
Java由浅入深通关抽象类与接口(上篇)
Apr 26 Java/Android
openGauss数据库JDBC环境连接配置的详细过程(Eclipse)
Jun 01 Java/Android
java实现web实时消息推送的七种方案
Jul 23 Java/Android
详细了解MVC+proxy
Jul 09 #Java/Android
Spring实现内置监听器
Jul 09 #Java/Android
新手初学Java网络编程
Jul 07 #Java/Android
Java 语言中Object 类和System 类详解
Jul 07 #Java/Android
新手初学Java List 接口
Jul 07 #Java/Android
Spring Boot 整合 Apache Dubbo的示例代码
Jul 04 #Java/Android
Java实现聊天机器人完善版
You might like
德生PL990,目前市面上唯一一款便携式插卡蓝牙全波段高性能收音机
2021/03/02 无线电
PHP使用者状态管理功能的应用
2006/10/09 PHP
Mysql和网页显示乱码解决方法集锦
2008/03/27 PHP
PHP之COOKIE支持详解
2010/09/20 PHP
php的curl封装类用法实例
2014/11/07 PHP
复选框全选与全不选操作实现思路
2013/08/18 Javascript
js实现点击向下展开的下拉菜单效果代码
2015/09/01 Javascript
Bootstrap分页插件之Bootstrap Paginator实例详解
2016/10/15 Javascript
vuejs如何配置less
2017/04/25 Javascript
JS实现点击链接切换显示隐藏内容的方法
2017/10/19 Javascript
Angular动画实现的2种方式以及添加购物车动画实例代码
2018/08/09 Javascript
ECharts地图绘制和钻取简易接口详解
2019/07/12 Javascript
Vue实现渲染数据后控制滚动条位置(推荐)
2019/12/09 Javascript
JS通用方法触发点击事件代码实例
2020/02/17 Javascript
vue.js 输入框输入值自动过滤特殊字符替换中问标点操作
2020/08/31 Javascript
js对象属性名驼峰式转下划线的实例代码
2020/09/17 Javascript
[01:14]DOTA2 7.22版本新增神杖效果展示(智力英雄篇)
2019/05/29 DOTA
python编写的最短路径算法
2015/03/25 Python
仅用50行代码实现一个Python编写的计算器的教程
2015/04/17 Python
python利用matplotlib库绘制饼图的方法示例
2016/12/18 Python
Python计算斗牛游戏概率算法实例分析
2017/09/26 Python
Python中的Django基本命令实例详解
2018/07/15 Python
Python绘制堆叠柱状图的实例
2019/07/09 Python
使用python爬取抖音视频列表信息
2019/07/15 Python
python 已知一个字符,在一个list中找出近似值或相似值实现模糊匹配
2020/02/29 Python
jupyter notebook 的工作空间设置操作
2020/04/20 Python
js实现移动端H5页面手指滑动刻度尺功能
2017/11/16 HTML / CSS
HTML5+CSS3应用详解
2014/02/24 HTML / CSS
Dr. Martens马汀博士澳大利亚官网:马丁靴鼻祖
2019/07/02 全球购物
建筑工程专业学生的自我评价
2013/12/25 职场文书
会计与审计专业自荐信范文
2014/03/15 职场文书
实验室的标语
2014/06/20 职场文书
工作经历证明范本
2015/06/15 职场文书
门卫管理制度范本
2015/08/05 职场文书
redis三种高可用方式部署的实现
2021/05/11 Redis
Win11跳过联网界面创建本地管理账户的3种方法
2022/04/20 数码科技