目录
17、Spring SpEL
17.1、简介
Spring3中引入了Spring表达式语言—Spring SpEL,SpEL表达式是一种强大,简洁的装配Bean的方式,支持在xml和注解中使用,类似于JSP的EL,JSTL表达式语言。他可以通过运行期间执行的表达式将值装配到我们的属性或构造函数当中,,更可以调用JDK中提供的静态常量,获取外部Properties文件中的的配置。
其实无论是XML还是注解,在注入Bean或是属性时都是静态的注入,那么如果Bean A中的一个成员变量的值需要参考Bean B中的成员变量的值,那么这种静态的注入就有点力不从心了。所以Spring 提供了SpEL表示式来实现动态的注入。
Spring SpEL的格式为:#{ SpEL expression } 。
它支持如下表达式(关键字不区分大小写。):
- 基本表达式:字面量表达式、关系、逻辑与算术运算表达式、字符串连接及截取表达式、三目运算表达式、正则表达式、括号优先级表达式。
- 类相关表达式:类类型表达式、类实例化、instanceof 表达式、变量定义及引用、赋值表达式、自定义函数、对象属性存取及安全导航表达式、对象方法调用、Bean 引用;
- 集合相关表达式:内联 List、内联数组、集合、字典访问、列表、字典、数组修改、集合投影、集合选择;不支持多维内联数组初始化;不支持内联字典定义;
- 模板表达式。
17.2、配合@value使用
17.2.1、基本字面值
支持各种类型的字面值。字符串或字符类型的字面值需要使用引号包括,其他类型字面值直接写。
@Component
public class Student {
//注入int
@Value("#{1}")
private int id;
//注入String
@Value("#{'张三'}")
private String name;
//注入算数表达式
@Value("#{30-12}")
private int age;
//注入布尔值
@Value("#{true}")
private boolean deleted;
}
17.2.2、类相关表达式
除字面量外,还可以直接调用IOC容器中已经存在的Bean对象,且可以直接调用对象的属性。也可以直接对集合进行赋值
<bean id="dog" class="com.yu.springtest.entity.Dog">
<property name="name" value="大黄"/>
</bean>
<util:list id="list">
<value>java</value>
<value>python</value>
<value>c++</value>
</util:list>
//注入一个对象
@Value("#{dog}")
private Dog dog;
//可以调用对象
@Value("#{dog.name}")
private String dogName;
//注入集合
@Value("#{list}")
private List<String> strings;
@Value("#{{1,2,3,4}}")
List<Integer> list;
@Value("#{{'java','python'}")
List<String> strings;
@Value("#{{1,2,3,4}")
int[] ints;
@Value("#{{name:'张三',age:'13'}")
Map<String, String> map;
//从集合中获取数据
@Value("#{test.ints[0]}")
int id;
@Value("#{test.map['name']}")
private String name1;
17.2.3、properties
SpEl还能取出 properties文件中的数据,注入到bean变量
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/ssmtest?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
jdbc.username=root
jdbc.password=密码
-
util:properties加载的properties数据
<util:properties id="database" location="classpath:database.properties"/>
@Component public class Database { @Value("#{database['jdbc.driver']}") private String driver; @Value("#{database['jdbc.url']}") private String url; @Value("#{database['jdbc.username']}") private String name; @Value("#{database['jdbc.password']}") private String password; }
-
context:property-placeholder加载的properties数据
<context:property-placeholder location="classpath:database.properties"/>
@Component public class Database { @Value("${jdbc.driver}") private String driver; @Value("${jdbc.url}") private String url; @Value("${jdbc.username}") private String name; @Value("${jdbc.password}") private String password; }
17.2.4、T运算符
T操作符可以获取表达式对象的类型, 可以调用表达式对象的静态方法,如果是java.lang包下的类的对象,可以省略包名。
public class Test {
public static String getUserName(){
return "张三";
}
@Value("#{T(com.yu.springtest.spel.Test).getUserName()}")
private String name;
@Value("#{T(com.yu.springtest.spel.Test).userName}")
private String userName;
}
17.2.5、new
在 SpEl 中可以直接使用new 关键字来创建对象,如果new的是java.lang包下的类的对象,可以省略包名。
@Value("#{new com.yu.springtest.entity.Dog('大黄')}")
private Dog dog;
17.2.6、Elvis运算符
Spring EL表达式支持Elvis运算符,语法是变量?:默认值
意思是当某变量不为 null 的时候使用该变量,当该变量为 null 的时候使用指定的默认值。
//如果student.name不为空则使用student.name,否则使用张三
@Value("#{student.name?:'张三'}")
String username;
17.2.7、运算符
表达式中支持各种运算符,运算规则和Java规则类似。操作符:
- 关系操作符, 包括: eq(==), ne(!=), lt()<, le(<=), gt(>), ge(>=)
- 逻辑运算符, 包括: and(&&), or(||), not(!)
- 数学操作符, 包括: 加(+), 减(-), 乘(*), 除(/), 取模(%), 幂指数(^)
- 其他操作符, 如: 三元操作符(可用于赋默认值,), instanceof、 赋值(=), 正则匹配
17.2、配合XML使用
和在注解中使用类似、
<bean id="dog" class="com.yu.springtest.entity.Dog">
<property name="name" value="大黄"/>
</bean>
<util:list id="list">
<value>java</value>
<value>python</value>
<value>c++</value>
</util:list>
<bean id="student" class="com.yu.springtest.entity.Student">
<property name="dog" value="#{dog}"/>
<property name="dogName" value="#{dog.name}"/>
<property name="strings" value="#{list}"/>
<property name="name" value="#{list[0]}"/>
</bean>