(原创)Spring 依赖注入 - 运行时进行值注入的两种方法

目录

一、背景

二、用法介绍

1.属性占位符

2.Spring表达式语言(SpEL)


一、背景

通常我们讨论依赖注入时,指的都是将一个 bean 引用注入到另一个 bean 的属性或构造器中,它通常是指对象与对象之间的关联。除此之外,bean 的装配还可以将一个值注入到 bean 的属性或构造器中。但是值注入经常会造成硬编码,如下代码所示:

@Bean
public People getPeople() {
    return new Boy("oysq", "boy");
}

与此类似,XML 风格的注入也存在此类硬编码的问题,如:

<bean id="people"
    class="aa.bb.People"
    c:_name="oysq"
    c:_sex="boy" />

所以,我们希望这些值能在运行时再确定,而不是直接编写到代码中。具体有两种方法:

  • 属性占位符,用法:${ ... } 
  • Spring表达式语言(SpEL),用法:#{ ... } 

二、用法介绍

1.属性占位符

属性占位符的使用是将值放于配置文件中,并通过声明属性源的方式,使得 Spring 的 Environment 能检索到这些属性,最后通过代码的方式或属性占位符进行注入。

例如,现在我们创建一个配置文件 boy.properties ,内容如下:

boy.name=oysq
boy.age=26
boy.phone=123456789

通过 @PropertySource 注解声明属性源,将其加载到 Spring 的 Environment 中,再通过 Environment 取出注入。

@Configuration
@PropertyEource("classpath:/com/sys/boy.properties")
public class MyConfig {

    @Autowired
    Environment env;

    @Bean
    public People getPeople() {
        return new Boy(
            env.getProperty("boy.name"),
            env.getProperty("boy.age")
        );
    }

}

其中,Environment 除了能获取属性值外,还有很多用法,比如获取 profile 来判断激活状态等等。

如果是自动扫描的的方式,我们在组件处通过 @Value 注解来注入,并需要配置一个 PropertyPlaceholderConfigurer 的 bean 或 PropertySourcesPlaceholderConfigurer 的 bean,从 spring 3.1 开始,推荐使用 PropertySourcesPlaceholderConfigurer,因为它能够基于 Spring Environment 及其属性源来解析占位符。代码如下:

@Component
public class Boy {

    private String name;
    private String age;

    public Boy(
        @Value("${boy.name}") String name,
        @Value("${boy.age}") String age) {
        this.name = name;
        this.age = age;
    }
}
@Bean
public PropertySourcesPlaceholderConfigurer getPlaceholderConfigurer() {
    return new PropertySourcesPlaceholderConfigurer();
}

而在 xml 中我们使用属性占位符,并通过 <context:property-placeholder /> 来生成 PropertySourcesPlaceholderConfigurer 的 bean,如下:

<bean id="people"
    class="aa.bb.People"
    c:_name="${boy.name}"
    c:_sex="${boy.age}" />

<context:property-placeholder />

2.Spring表达式语言(SpEL)

SpEL 表达式有很多的特性,除了依赖注入,还能用在很多其它的地方。于属性占位符最直接的区别就是它 放在 #{ ... } 之中。

它的特性包括:

  • 使用 bean 的 ID 来引用 bean
  • 调用方法和访问对象的属性
  • 对值进行算数、关系和逻辑运算
  • 正则表达式匹配
  • 集合操作

这边只简单举例用法:

@Component
public class Boy {

    private String name;
    private String age;

    public Boy(
        @Value("#{systemProperty['boy.name']}") String name,
        @Value("#{systemProperty['boy.age']}") String age) {
        this.name = name;
        this.age = age;
    }
}

写在最后:虽然 SpEL 表达式很智能,但是建议不要写太复杂,因为毕竟是一个字符串,不好做测试。

 

(原创不易,转载请注明出处!!)

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值