欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-03-28 22:06:24
@value值注入及配置文件组件扫描spring配置文件对应的是父容器,springmvc配置文件产生的是子容器,前者一般配置数据源,事务,注解等,当然还可以进一步将一些配置细化到其他xml中;后者一...

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

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