package spel;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.expression.BeanFactoryResolver;
import org.springframework.core.io.Resource;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.ParserContext;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.stereotype.Component;
import java.io.InputStream;
import java.util.Map;
/**
* SpEL表达式测试
* @author Chenghe Xu
* @date 2022/8/17 18:51
*/
@Component
public class Expression {
@Value("正常注入属性用法")
private String normal;
@Value("#{ 10+20 }")
private Integer arithmetic;
@Value("#{ user }")
private User user1;
@Value("#{ user.age }")
private Integer age1;
@Value("#{ user.getAge() }")
private Integer age2;
@Value("#{ @user }")
private User user2;
@Value("#{ @user.age }")
private Integer age3;
@Value("#{ @user.getAge() }")
private Integer age4;
@Value("#{ systemEnvironment }")
private Map systemEnvironmentMap;
@Value("#{ systemProperties }")
private Map systemPropertiesMap;
@Value("classpath:custom/test.txt")
private Resource resourceFile;
@Value("www.baidu.com")
private Resource url1;
@Value("14.215.177.38")
private Resource url2;
/**
* 注意:properties属性注入不能有空格
*/
@Value("${spring.datasource.username}")
private String username;
@Value("${spring.datasource.password}")
private String password;
@Value("${server.port}")
private Integer port;
public void launch() throws Exception {
//1、解析执行四则运算逻辑表达式
System.out.println(spel("#{ 10+20 }"));
//2、通过反射获取对象方法一(java.lang是默认包名可以省略)
System.out.println(spel("#{ T(java.lang.Integer) }"));
System.out.println(spel("#{ T(Integer) }"));
System.out.println(spel("#{ T(spel.User) }"));
//2、通过反射获取对象方法二(Integer没有public的构造函数不能通过new访问构造函数)
System.out.println(spel("#{ new spel.User() }"));
System.out.println(spel("#{ new spel.User().getClass().getSimpleName() }"));
//3、解析调用静态方法、变量
System.out.println(spel("#{ T(java.lang.Integer).MAX_VALUE }"));
System.out.println(spel("#{ T(Integer).parseInt('919') }"));
System.out.println(spel("#{ T(spel.User).userName }"));
System.out.println(spel("#{ T(spel.User).getUserName() }"));
//3、解析调用非静态方法、变量
System.out.println(spel("#{ new spel.User().age }"));
System.out.println(spel("#{ new spel.User().getAge() }"));
//4、SpEL内置上下文对象访问
System.out.println(spel("#{ #var1 +'-'+ #var2 }"));
System.out.println(spel("#{ #var3 }"));
System.out.println(spel("#{ #var3.getClass().getSimpleName() }"));
System.out.println(spel("#{ #var3.age }"));
System.out.println(spel("#{ #var3.getAge() }"));
//5、@用法和&用法
//用于交给BeanFactory管理的Bean对象引用(涉及BeanResolver)
System.out.println(spelWithBean("#{ @user }"));
System.out.println(spelWithBean("#{ @user.age }"));
System.out.println(spelWithBean("#{ @user.getAge() }"));
//6、$用法
//$表示引入配置资源profiles文件的属性${ properties }
//7、自定义SpEL解析模板
System.out.println(mySpel("{ T(Integer).MIN_VALUE }"));
System.out.println("==========SpEL-@Value测试分割线==========");
//1、正常注入属性用法
System.out.println(normal);
//2、注入执行四则运算逻辑表达式
System.out.println(arithmetic);
//3、获取Spring容器中的Bean对象(要启动Spring容器测试)
//在@Value中直接通过Bean名称获取
System.out.println(user1);
System.out.println(age1);
System.out.println(age2);
//在@Value中通过@Bean名称获取
System.out.println(user2);
System.out.println(age3);
System.out.println(age4);
//4、注入操作系统属性
System.out.println(systemEnvironmentMap);
System.out.println(systemPropertiesMap);
//5、注入文件资源内容
InputStream inputStream = resourceFile.getInputStream();
// //注意:如果文件中有中文,就不用每字节读取转码否则会乱码
// int bt;
// while ((bt=inputStream.read())!=-1){
// System.out.print((char)bt);
// }
// System.out.println();
//有中文,可以使用1024整段字节的整数倍读取后进行转码
byte[] bts = new byte[1024*1];
int len;
while ((len=inputStream.read(bts))!=-1){
System.out.print(new String(bts,0,len));
}
System.out.println();
// //创建一个和文件大小一样的缓冲区
// byte[] buf=new byte[inputStream.available()];
// //有中文,可以使用整个文件读取到缓冲区后进行转码
// int len=inputStream.read(buf);
// System.out.println(new String(buf,0,len));
inputStream.close();
//6、注入URL资源内容
System.out.println(url1);
System.out.println(url2);
//7、使用$获取profiles配置文件properties属性
System.out.println(username);
System.out.println(password);
System.out.println(port);
}
/**
* 封装SpEL表达式解析执行的方法
*/
public static Object spel(String content){
//定义SpEL解析器
SpelExpressionParser spelExpressionParser = new SpelExpressionParser();
//表达式解析(和本类名重复,需通过包.类名指定)
org.springframework.expression.Expression expression = spelExpressionParser.parseExpression(content, ParserContext.TEMPLATE_EXPRESSION);
//表达式上下文配置
EvaluationContext evaluationContext=new StandardEvaluationContext();
evaluationContext.setVariable("var1", "ypy");
evaluationContext.setVariable("var2", 20);
evaluationContext.setVariable("var3", new User(30));
return expression.getValue(evaluationContext);
}
/**
* 自定义SpEL解析模板
*/
public static Object mySpel(String content){
//定义SpEL解析器
SpelExpressionParser spelExpressionParser = new SpelExpressionParser();
//自定义表达式解析模板(和本类名重复,需通过包.类名指定)
org.springframework.expression.Expression expression = spelExpressionParser.parseExpression(content
, new ParserContext() {
@Override
public boolean isTemplate() {
//启用模板
return true;
}
@Override
public String getExpressionPrefix() {
return "{";
}
@Override
public String getExpressionSuffix() {
return "}";
}
});
//表达式上下文配置
EvaluationContext evaluationContext=new StandardEvaluationContext();
return expression.getValue(evaluationContext);
}
/**
* 定义BeanResolver实现@引用Bean
*/
public static Object spelWithBean(String content){
//定义SpEL解析器
SpelExpressionParser spelExpressionParser = new SpelExpressionParser();
//表达式解析(和本类名重复,需通过包.类名指定)
org.springframework.expression.Expression expression = spelExpressionParser.parseExpression(content, ParserContext.TEMPLATE_EXPRESSION);
//表达式上下文配置
StandardEvaluationContext evaluationContext=new StandardEvaluationContext();
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
beanFactory.registerSingleton("user",new User(40));
evaluationContext.setBeanResolver(new BeanFactoryResolver(beanFactory));
return expression.getValue(evaluationContext);
}
}
/**
* Spring加载对象到容器的命名规则
* 第一个字母小写(如:User->user)
*/
@Component
class User{
/**
* 重写无参构造函数
* 因为,默认构造函数非public
* 由target->User.class可以看到编译文件
*/
public User() {}
public User(Integer age) {
this.age = age;
}
/**
* T(xxx.xxx).xxx只能访问public static的方法和变量
*/
public static String userName="xch";
/**
* @Value(xxx/@xxx.xxx)只能注入public的方法和变量
*/
public Integer age=21;
public static String getUserName(){
return userName;
}
public Integer getAge(){
return age;
}
/**
* 重写toString方法
* 用于内容输出代替地址输出
*/
@Override
public String toString() {
return "User{" +
"age=" + age +
'}';
}
}
SpEL表达式用法汇总
最新推荐文章于 2024-06-06 14:43:33 发布