Spring/Boot/Cloud系列知识(5)——Spring EL(1)

1、Spring EL 概述

Spring EL是Spring Expression Language的简称,中文称作Spring表达式语言。Spring EL并不单单指代某一种特定的表达式格式,而是对Spring中字符串表达式的一个概要性称呼。Spring EL基本功能由Spring核心包提供支持(spring-core组件和spring-context组件),并且不同的组件还对Spring EL的基本功能提供扩展。本文(及后续一文)主要对读者会在实际工作中使用到的Spring EL 进行讲述,并在最后结合一个使用Spring EL 完成自定义注解实例。

2、Spring EL 基本使用

Spring EL 的使用非常灵活,并且主要由“@Value”注解标记进行支撑。“@Value”注解可以在属性、方法上使用,通过这个注解可以基于IOC容器中的bean对象、对象属性、对象方法、操作符计算结果、正则表达式匹配结果、应用程序配置结果、操作系统环境变量配置结果等等,对目标属性、方法入参进行赋值。

2.1、Spring EL 引用固定值

......
@Component("BaseSpel")
public class BaseSpel {
  ......

  /**
   * 为这个存在于IOC容器中的对象的myValue1属性赋一个固定的字符串"string value"
   */
  @Value("string value")
  private String myValue1;
  /**
   * 为这个存在于IOC容器中的对象的myValue2属性赋一个固定的整型值"100"
   */
  @Value("100")
  private Integer myValue2;

  ......
}

使用“@Value”注解基于固定值对目标属性进行赋值的示例非常简单,虽然这样的赋值方式不经常在实际工程中使用(因为赋一个固定值基本没有意义),但通过这个简单示例读者可以热热身。

2.2、Spring EL引用对象、对象属性和对象方法

这种赋值方式在正式系统开发过程中使用频率一般,这里不用过多描述,直接上代码示例就行:

  • 这是一个存储在IOC容器中的普通Bean对象:
/**
 * 这是一个存储在IOC容器中的普通对象
 * @author yinwenjie
 */
@Component("myPojo")
public class MyPojo {
  ......
  @Value("a")
  private String a;

  @Value("b")
  private String b;

  // 这是一个没有任何入参的方法
  public String doHandle() {
    return "111111";
  }

  // 这是一个带有一个入参的方法
  public String doHandle(String param) {
    return new Date().toString() + param;
  }
  ......
}
  • 我们使用“@Value”注解进行赋值,在“BaseSpel”这个Bean初始化时,对其中的属性进行初始化。
@Component("BaseSpel")
public class BaseSpel {
  ......
  /**
   * 为BaseSpel类中的myPojo属性赋值
   */
  @Value("#{myPojo}")
  private MyPojo myPojo;

  /**
   * 这样可以将myPojo bean中的a属性进行赋值
   */
  @Value("#{myPojo.a}")
  private String myPojo_a;

  /**
   * 调用myPojo1 bean中的doHandle方法
   */
  @Value("#{myPojo.doHandle()}")
  private String myPojo_m;

  /**
   * 调用myPojo bean中的doHandle方法
   * 且将myPojo bean中的a属性的值,作为方法调用时的传入参数
   */
  @Value("#{myPojo.doHandle(myPojo.a)}")
  private String myPojo_n;
  ......
}

“@Value”注解中的“#{myPojo}”表示将IOC容器中名叫“myPojo”的bean对象进行赋值。这个名叫“myPojo”的信息必须存在。它或者是配置文件中的某个属性,或者是某个保留关键字(例如systemProperties),又或者是IOC容器中的一个bean对象等等,否则会报SpelEvaluationException性质的异常——“Property or field ‘XXXXXX’ cannot be found”。“#{myPojo.a}”表示名叫“myPojo”的bean对象中名叫“a”的属性。将后者的值赋予对象中的myPojo_a属性。

“#{myPojo.doHandle()}”表示使用名叫“myPojo”的bean对象中“doHandle()”方法的调用返回值作为“myPojo_m”属性的赋值结果。当然您还可以设置调用“doHandle()”方法时的参数传入,例如“#{myPojo.doHandle(myPojo.a)}”就是将“myPojo.a”属性的值作为调用方法时的参数进行传入。

请注意,由于Spring IOC容器中名叫“myPojo”的这个bean对象是以单例模式存在,所以无论有多少个Bean通过“@Value”注解获得“myPojo”这个bean中的值,其赋值结果都是一样的(当然调用方法进行赋值时方法中有不同处理的除外)。以下是debug时所显示的“BaseSpel”bean的属性值状态:

这里写图片描述

2.3、Spring EL中使用操作符

Spring EL支持数学操作符、逻辑操作符、关系操作符等基本的二元操作符和三元操作符。包括(但不限于):’==’、’!=’、“<=”、’>=’、’and’、’or’、’+’、’-‘、’*’、’/’、’%’、’^’等等。

请注意,由于本系列专题的示例都是基于Spring Boot这样免配置组件,所以以上列出的操作符都是在“@Value”这样的注解直接使用的。如果读者使用的是Spring XML这样的配置文件定义bean和依赖关系,那么Spring EL操作符就需要进行转义,例如’<’操作符转义为’&lt’、’>’操作符转义为’&gt’,等等。另外,类似“++”这样的一元操作符Spring EL表达式是不支持的

2.3.1、二元操作符

  • 以下是多个二元操作符的使用示例:
/**
 * 对操作符的支持
 */
@Component("opSpel")
public class OpSpel {
  ......
  // == 操作符,可以直接支持字符串的判断
  @Value("#{myPojo.a == 'a'}")
  private boolean eq;
  // != 操作符,也可以支持字符串的判断
  @Value("#{myPojo.a != 'yinwenjieb'}")
  private boolean noteq;
  // “与”操作符
  @Value("#{myPojo.a == 'a' and myPojo.a != 'b'}")
  private boolean and;
  // “或”操作符
  @Value("#{myPojo.a == 'a' or myPojo.a == 'b'}")
  private boolean or;
  // 加法操作
  @Value("#{BaseSpel.myValue2 + 1}")
  private int addop;
  // 减法操作
  @Value("#{BaseSpel.myValue2 - 1}")
  private int subop;
  // 除法操作
  @Value("#{BaseSpel.myValue2 / 20}")
  private float division;
  ......
}
  • 以下是debug操作时所显示的“opSpel”bean的属性值状态:

这里写图片描述

2.3.2、三元操作符

Spring EL除了支持基本的二元表达式(’==’、’!=’、“<=”、’>=’、’and’、’or’、’+’、’-‘、’*’、’/’、’%’、’^’等等),还支持三元表达式。以下是三元操作符的一个使用示例:

/**
 * 对操作符的支持
 */
@Component("opSpel")
public class OpSpel {
  ......
  /**
   * 三元操作符
   * randomNumber()方法将返回一个0.0到1.0的随机数。
   * 那么这个三元表达式有50%的几率返回'1';50%的几率返回'2'
   */
  @Value("#{BaseSpel.randomNumber() < 0.5 ? '1':'2'}")
  ......
}
  • 以上代码片段中调用的randomNumber()方法,在BaseSpel bean下的定义如下:
@Component("BaseSpel")
public class BaseSpel {
  ......
  public float randomNumber() {
    return new Random().nextFloat();
  }
  ......
}

2.4、Spring EL中使用正则表达式

Spring EL支持正则表达式,且这种方式在正式系统的开发中经常使用。本文不会讲解正则表达式本身的使用技巧,如果读者不清楚正则表达式的使用方式,请另外参考资料。

  • 以下是一个使用正则表达式的简单示例:

在一个名叫“BaseSpel”的Bean中定义了一个方法,这个方法中随机取出4个不同的用户名,如下所示:

@Component("BaseSpel")
public class BaseSpel {
  ......
  // 随机获取一个用户名
  public String randomUserName() {
    String userNames[] = new String[]{"yinwenjie2009","yin-wen-jie","yinwenjie-2009","Yinwenjie2009"};
    return userNames[new Random().nextInt(4)];
  }
  ......
}

然后接着在名叫“opSpel”的Bean中,通过“@Value”注解调用这个方法,如下所示:

@Component("opSpel")
public class OpSpel {
  ......
  @Value("#{BaseSpel.randomUserName() matches '^\\w+$'}")
  private boolean username;
  ......
}

以上代码中对“@Value”注解的使用大致的意思是,调用“opSpel”这个bean中的randomUserName()方法随机获得四个用户名”yinwenjie2009”、”yin-wen-jie”、”yinwenjie-2009”或者”Yinwenjie2009”,其中”yin-wen-jie”和”yinwenjie-2009”这两个用户名是不满足正则表达式的“^\w+$”规则的。于是username属性的值就会返回false(其它情况返回true)。

  • 再来一个三元表达式和和正则表达式混用的Spring EL示例,这里就只给代码,不再进行单独说明了:
@Component("opSpel")
public class OpSpel {
  ......
  @Value("#{BaseSpel.randomUserName() matches '^\\w+$'?'1':'2'}")
  private String userName;
  ......
}

======================================
(后文内容包括:Spring EL集合、Spring EL 和AOP切面配置)

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

说好不能打脸

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值