【Spring】3.5、运行时值注入

之前讨论的依赖注入,主要关注将一个bean引用注入到另一个bean的属性或构造器参数中。

依赖注入还有另外一方面:将值注入到bean的属性或构造器参数中。

当然可以使用之前说过的硬编码,但是我们这里希望这些值在运行时确定。

Spring提供2种运行时求值方式:属性占位符(Property placeholder)、Spring表达式语言(SpEL)

1、注入外部的值

1.1、用法

使用@PropertySource注解和Environment

@Configuration
@PropertySource("classpath:/com/soundsystem/app.properties")
public class EnvironmentConfig {

  @Autowired
  Environment env;
  
  @Bean
  public BlankDisc blankDisc() {
    return new BlankDisc(
        env.getProperty("disc.title"),
        env.getProperty("disc.artist"));
  }
  
}

通过@PropertySource注解引用一个名为app.properties的文件,文件内容如下

disc.title=Sgt. Peppers Lonely Hearts Club Band
disc.artist=The Beatles

然后通过Spring的Environment,使用getProperty()方法,进行检索属性。

1.2、深入Spring的Environment

getProperty()方法的重载

String getProperty(String key)
String getProperty(String key, String defaultValue)
T getProperty(String key, class<T> type)
T getProperty(String key, class<T> type,T defaultValue)

getProperty()方法如果没有找到对应的属性,会返回null值

getRequiredProperty()方法,如果没有找到属性,会抛出IllegalStateException异常

containsProperty()方法:检查某个属性是否存在

getPropertyAsClass()方法:将属性解析为类

检查profile的激活状态

String[] getActiveProfiles():返回激活profile名称的数组;

String[] getDefaultProfiles():返回默认profile名称的数组;

boolean acceptsProfiles(String... profiles):如果environment支持给定profile的话,返回true

1.3、解析属性占位符“${...}”以及注解@Value

使用Environment检索属性很方便,Spring同时也提供了占位符装配属性的方法

a、配置PropertyPlaceholderConfigurer bean或PropertySourcesPlaceholderConfigurer bean(Spring3.1开始推荐用这个) ,这个bean可以基于Spring Environment以及其属性源来解析占位符

Java配置

@Bean
public static PropertySourcesPlaceholderConfigurer placeholderConfigurer(){
    return new PropertySourcesPlaceholderConfigurer();
}

XML配置,引用Spring context命名空间中的<context:property-placeholder />即可自动生成PropertySourcesPlaceholderConfigurer bean

<?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-beans.xsd">

    <context:property-placeholder />

</beans>

b、注入

Java注入

public BlandKisc(
    @Value("${disc.title}") String title,
    @Value("${disc.artist}") String artist){
    this.title = title;
    this.artist = artist;
}

XML注入

<bean id="sgtPeppers"
      class="soundsystem.BlandDisc"
      c:_title="${disc.title}"
      c:_artist="${disc.artist}" />

 2、使用Spring表达式语言进行装配

Spring 3引入了Spring表达式语言(Spring Expression Language,SpEL),能够强大和简洁地把值装配到bean属性和构造器参数中。

SpEL的一些特性:

·使用bean的ID引用bean;

·调用方法和访问对象的属性;

·对值进行算术、关系和逻辑运算;

·正则表达式匹配;

·集合操作;

2.1、表示字面值

#{1}//整型
#{3.14159}//浮点数
#{9.87E4}//科学计数法
#{'Hello'}//String类型字面值
#{false}//Boolean类型

2.2、引用bean、属性和方法

#{sgtPeppers}//引用ID为sgtPeppers的bean
#{sgtPeppers.artist}//引用bean的属性
#{sgtPeppers.selectArtist()}//调用bean的方法
#{sgtPeppers.selectArtist().toUpperCase()}//调用bean的方法的值的方法,例如方法值是String类型,则可以调用String对象的toUpperCase方法
#{sgtPeppers.selectArtist()?.toUpperCase()}//类型安全的运算符“?.”,当值为null时返回null,否则猜执行toUpperCase方法

2.3、表达式中使用类型

主要作用是调用类的静态方法和变量。使用T()运算符,获得Class对象。

#{T(java.lang.Math)}//得到一个class对象
#{T(java.lang.Math).PI}//类的常量
#{T(java.lang.Math).random()}//类的静态方法

2.4、SpEL运算符

用于在SpEL表达式上做运算

#{2 * T(java.lang.Math).PI * circle.radius}//计算周长
#{T(java.lang.Math).PI * circle.radius ^ 2}//计算面积
#{disc.title + ' by ' + disc.artist}//拼接字符串
#{counter.total == 100}//比较运算符 结果为布尔值
#{counter.total eq 100}//比较运算符 结果为布尔值
#{scoreboard.score ? 1000 ? "Winner!" : "Loser"}//三元运算符
#{disc.title ?: 'Rattle and Hum'}//Elvis运算符(Elvis是猫王的名字,?:符号像猫王的头发),判断是否为null,是null则给默认值

2.5、计算正则表达式

使用matches运算符,返回Boolean类型值

#{admin.email matches '[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.com'}//验证有效邮件

 2.6、计算集合

#{jukebox.songs[4].title}//songs集合第5个元素的title属性
#{'this is a test'[3]}//String中的一个字符
#{jukebox.songs.?[artist eq 'Jay']}//使用查询运算符(.?[])过滤子集
#{jukebox.songs.^[artist eq 'Jay']}//使用第一个匹配符(.^[])找到第一个匹配的项
#{jukebox.songs.$[artist eq 'Jay']}//使用最后一个匹配符(.$[])找到最后一个匹配的项
#{jukebox.songs.![title]}//投影运算符(.![])选择属性投影到一个新的集合

2.7、这里介绍的SpEL只是冰山一角,有需要的去查阅相关资料

猜你喜欢

转载自www.cnblogs.com/LiveYourLife/p/9018150.html
今日推荐