zoukankan      html  css  js  c++  java
  • spring基于@Value绑定属Bean性失

    用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官方文档看到正确使用方式

    所以只需要修改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")//这个必须要引入,否者得到配置文件中的值是有问题的,有了这个可以不用在JsrDAO中重配置了,多了也无妨
    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:下面补充一点知识

    关于代理模式,如图

    运行时注入

    1. 属性占位符(Property Placeholder)
    2. 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’]}”
    • .^[] 集合中查询第一个匹配项
    • .$[] 集合中查询最后一个匹配项
  • 相关阅读:
    spring(1)
    mybatis(7)自定义结果集(一对多/多对一)
    延迟加载
    《构建之法》阅读笔记03
    http socket
    转换
    .net后台通过xmlhttp 和远程服务通讯
    XMLHttpRequest介绍
    js 贪吃蛇
    触发器
  • 原文地址:https://www.cnblogs.com/lijianming180/p/12041106.html
Copyright © 2011-2022 走看看