用spring注解@Value绑定属性失败
环境:
- eclipse Version: Luna Release (4.4.0)
- spring 4.0
- Junit4
- 其他依赖包
描述:
JsrDAO类,在该类中使用了SpEL和spring注解
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
package com.laowang.annotationBase;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.ImportResource;
import org.springframework.stereotype.Repository;
(
"dao")
@ImportResource(
"classpath*:jdbc.properties")
public
class {
@Value(
"${url}")
private String url;
@Value(
"${name}")
private String name;
@Value(
"${password}")
private String password;
public void save(){
System.out.println(
"jsr saving...");
System.out.println(
"url: "+url);
System.out.println(
"name: "+name);
System.out.println(
"password: "+password);
}
public void init(){
System.out.println(
"init jsrDAO Bean ...");
}
public void destroy(){
System.out.println(
"destroy jsrDAO Bean ...");
}
}
|
资源文件内容
url=http://localhost:3306/database
name=root
password=root
JavaConfig类,Bean的装配工作
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
package com.laowang.annotationBase;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportResource;
import org.springframework.test.context.ContextConfiguration;
@Configuration
public
class JavaConfig {
@Bean(name=
"dao", initMethod=
"init", destroyMethod=
"destroy")
public JsrDAO getJseDAO(){
return
new JsrDAO();
}
}
|
测试类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
package com.laowang.annotationBase;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes=JavaConfig.class)
public
class TestA {
@Autowired
private JsrDAO jsDao;
@Test
public void testDAO(){
jsDao.save();
}
|
结果获得数据显示为
init jsrDAO Bean ...
jsr saving...
url: ${url}
name: ${name}
password: ${password}
destroy jsrDAO Bean ...
问题出现在用SpEL占位符绑定bean的三个属性没有成功,正确的结果应该是这样的
init jsrDAO Bean ...
jsr saving...
url: http://localhost:3306/database
name: root
password: root
destroy jsrDAO Bean ...
问题出现在哪里呢?按理说应该不会错的。于是百度、谷歌搜索,都没解决,最后去了spring官方文档看到正确使用方式
扫描二维码关注公众号,回复:
8190290 查看本文章
所以只需要修改JavaConfig文件就可以了,添加一行注解,变成如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
package com.laowang.annotationBase;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportResource;
@Configuration
@ImportResource(
"classpath*:spring-annotationBase.xml")
public
class JavaConfig {
@Bean(name=
"dao", initMethod=
"init", destroyMethod=
"destroy")
public JsrDAO getJseDAO(){
return
new JsrDAO();
}
@Bean
public JsrService getJsrService(){
JsrService service =
new JsrService();
service.setJsrDAO(getJseDAO());
return service;
}
}
|
同时再添加一个对应的xml配置文件,指定属性配置文件的位置,此时JsrDAo中属性文件位置的指定也可以不用了。
下面是对应的xml文件
1
2
3
4
5
6
7
8
9
10
11
12
|
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance"
xmlns:context=
"http://www.springframework.org/schema/context"
xsi:schemaLocation=
"http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<context:property-placeholder location="classpath:/properties/jdbc.properties"/>
</beans>
|
PS:下面补充一点知识
关于代理模式,如图
运行时注入
- 属性占位符(Property Placeholder)
- Spring 表达式语言SpEL
属性占位符(Property Placeholder)
加载资源配置文件后,通过环境对象(Environment)env获取配置文件内容,如
1
|
env.getProperty(
"jdbc.name");
|
具体使用要参考文档
解析属性占位符一般使用SpEL语言
SpEL语言特性如下:
- 使用bean的ID来引用bean
- 调用方法和访问对象的属性
- 对值进行算术、关系和逻辑运算
- 正则表达式匹配
- 集合操作
详
“#{…}”=======表达式
“${…}”=======占位符
字面常量
“#{1}”=======计算结果为1
引用bean、属性和方法
“#{bean}”=======引用bean
“#{bean.attr}”=======计算得到(引用)bean的属性
“#{systemProperties[‘jdbc.name’]}”=======通过systemProperties对象引用系统属性(个人理解为引用形同加载配置文件中的属性的值)
“#{bean.method()}”=======调用bean的方法
“#{bean.method()?.toUpperCase()}”=======方法返回不为空时继续调用toUpperCase(),否则不调用
在表达式中使用类型
“#{T(java.lang.Math).random}”=======只能调用类的静态方法和常量
SpEL 运算符
不说了
计算正则表达式:文本(matches)正则表达式
“#{admin.email matches ‘[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+.com’}”=======邮件验证
计算集合
“#{bean.list[2].attr}”=======获取bean中结合list第3个元素的attr属性
SpEL 其他运算符
- (.?[])对集合进行过滤。[]里面是表达式
“#{bean.list.?[attr eq ‘laowang’]}”
- .^[] 集合中查询第一个匹配项
- .$[] 集合中查询最后一个匹配项