`
jinnianshilongnian
  • 浏览: 21437348 次
  • 性别: Icon_minigender_1
博客专栏
5c8dac6a-21dc-3466-8abb-057664ab39c7
跟我学spring3
浏览量:2405616
D659df3e-4ad7-3b12-8b9a-1e94abd75ac3
Spring杂谈
浏览量:2998170
43989fe4-8b6b-3109-aaec-379d27dd4090
跟开涛学SpringMVC...
浏览量:5631827
1df97887-a9e1-3328-b6da-091f51f886a1
Servlet3.1规范翻...
浏览量:257673
4f347843-a078-36c1-977f-797c7fc123fc
springmvc杂谈
浏览量:1593347
22722232-95c1-34f2-b8e1-d059493d3d98
hibernate杂谈
浏览量:249028
45b32b6f-7468-3077-be40-00a5853c9a48
跟我学Shiro
浏览量:5847978
Group-logo
跟我学Nginx+Lua开...
浏览量:698271
5041f67a-12b2-30ba-814d-b55f466529d5
亿级流量网站架构核心技术
浏览量:780633
社区版块
存档分类
最新评论

@Value注入Properties 使用错误的案例

 
阅读更多

最近有朋友问@Value注入Properties数据注入不进去,接下来我就分析一下为什么。

 

场景:

需要注入Properties的value数据到Bean或方法参数。

 

准备数据:

    <bean id="props" class="java.util.Properties">
        <constructor-arg index="0">
           <props>
              <prop key="a">123</prop>
           </props>
        </constructor-arg>
    </bean>
    
    <bean id="map" class="java.util.HashMap">
        <constructor-arg index="0">
           <map>
              <entry key="a" value="234"/>
           </map>
        </constructor-arg>
    </bean>

 

失败的做法:

@Value("#{props['a']}")
    private String propsA;

此时无法获取props的a这个键对应的值。

 

正确的做法:

    @Value("#{props.getProperty('a')}")
    private String propsA;
    
    @Value("#{map['a']}")
    private String mapA;
    
    @RequestMapping(value="/value2")
    public String test2(@Value("#{props.getProperty('a')}") String propsA, @Value("#{map['a']}") String mapA) {

 

为什么?最后探讨。

 

最好的正确做法:

    <util:properties id="props2">
       <prop key="a">123</prop>
    </util:properties>

 //该标签内部使用org.springframework.beans.factory.config.PropertiesFactoryBean FactoryBean实现;

 

@Value("#{props2['a']}") String props2A,

 注入数据直接使用props[key]即可。

 

why?

为什么如下方式不行:

    <bean id="props" class="java.util.Properties">
        <constructor-arg index="0">
           <props>
              <prop key="a">123</prop>
           </props>
        </constructor-arg>
    </bean>

 

而如下这种方式行呢?

    <util:properties id="props2">
       <prop key="a">123</prop>
    </util:properties>

 

原因很简单:API不熟造成的:

1、首先我们来看下Properties构造器定义:

javadoc 写道
public Properties(Properties defaults)创建一个带有指定默认值的空属性列表。 

参数:
defaults - 默认值。

 

    1)、构造器第一个参数是默认值;

    2)、当我们使用getProperty(key) 时,首先查自己的prop,如果有直接返回,否则查defaults中的key。

javadoc 写道
public String getProperty(String key)
用指定的键在此属性列表中搜索属性。如果在此属性列表中未找到该键,则接着递归检查默认属性列表及其默认值。如果未找到属性,则此方法返回 null。
3)、原因到此很明显了,此时我们使用#{props.getProperty('a')} 其实是查的defaults
4)、Properties本身继承了Hashtable,其实是一种错误的用法,造成了我们现在的我们现在的问题,get(key)只查自己,而getProperty会先查自己 再查defaults。

 

2、而使用<util:properties id="props2"> 本身是一个FactoryBean,帮我们创建没有我们真实需要的properties。有兴趣可以看下源代码。

 

 

总结:

1、API不熟造成了错误理解(以为类似于如集合框架是做拷贝);

2、Properties继承Hashtable本身就是一种错误的继承,形成两套不同的API。

12
1
分享到:
评论
4 楼 sunshine_bean 2014-12-18  
每次看你的blog都有收获,谢谢
3 楼 melody_nancy 2012-11-19  
good,thx
2 楼 jinnianshilongnian 2012-10-24  
thc1987 写道
挺好的,知其然,知其所以然.

1 楼 thc1987 2012-10-24  
挺好的,知其然,知其所以然.

相关推荐

Global site tag (gtag.js) - Google Analytics