Spring笔记 - 资源Resource、表达式语言SpEL

1. 资源Resource

1.1 简介

通常指文本文件、二进制文件例如图片、属性文件properties、配置文件xml等,存放于classpath、文件系统、网络服务器等位置,通过file:、https:、ftp:等方式获取。是java.net.URL的增强与扩充。

1.2 Resource接口与内置实现

Resource接口在Spring广泛使用。其内置实现例如以下。顾名思义,从各自名称就可以大致猜测其用途。

  • UrlResource

  • ClassPathResource

  • FileSystemResource

  • ServletContextResource

  • InputStreamResource

  • ByteArrayResource

1.3 ResourceLoader接口

- 该接口声明了getResource方法,AppCtx实现了该接口。

Resource resource = ctx.getResource("x/y/config.txt");

- 资源字符串可以添加前缀如classpath:、file://、http://,如果不加,将视ctx的类型而定。例如ClassPathXMLAppCtx在classpath查找资源,FileSystemXmlAppCtx在文件系统查找资源。

- 如果是FileSystemXmlAppCtx,资源字符串不加file://前缀则为相对路径,加了则区分绝对路径和相对路径

FileSystemXmlApplicationContext ctx = ...;
//相对路径
ctx.getResource("path1/userList.txt");
//相对路径
ctx.getResource("/path1/userList.txt");
//绝对路径
ctx.getResource("file:///path1/userList.txt");

- 如果不使用ctx,可以在Bean中注入ResourceLoader

@Autowired
ResourceLoader resourceLoader;

1.4 直接注入Resource

往托管Bean直接注入Resource更加方便

<bean id="car" class="x.y.x.Car">
    <property name="manual" value="doc/manual.txt" />
</bean>


2. 表达式语言SpEL

2.1 简介

- Spring Expression Language简称SpEL,可以用来在运行时操作对象。同类语言或工具有OGNL、MVEL、JBoss EL等。SpEL在Spring Portfolio里面应用广泛。

- 其功能例如:字符表达式、布尔和关系操作符、正则表达式、类表达式、访问properties,arrays,lists,maps、方法调用、关系操作符、赋值、调用构造器、三元操作符、变量、用户自定义函数、集合投影、集合选择、模板表达式

2.2 使用方法

//创建parser进行识别
ExpressionParser parser = new SpelExpressionParser();
Expression exp = parser.parseExpression("'Hello World'.concat('!')");
String message1 = (String) exp.getValue(); //Hello World!
String message2 = (String) exp.getValue(String.class); //指定结果类型,性能更好

//使用EvaluationContext
car.setName("小汽车");
EvaluationContext context = new StandardEvaluationContext(car);
String name = (String) parser.parseExpression("name").getValue(context); //小汽车

//Parser设置
SpelParserConfiguration config = new SpelParserConfiguration(true,true); //arg1:被识别对象为null时自动创建实例,arg2:被识别对象是collection类型时超过collection上限则自动扩展
ExpressionParser parser = new SpelExpressionParser(config);
class Todo {
    public List<String> items;
}
parser.parseExpression("items[3]").getValue(new Todo()); //返回List<String>,包含4个空字符串

2.3 编译SpEL

- 对表达式进行编译可以提高性能,Spring reference提到一个例子编译前50000次迭代耗时75ms,编译后3ms

- 编译选项有:OFF(默认)、IMMEDIATE、MIXED

//arg2:在指定classLoader下面创建child classLoader,用来编译表达式;该classLoader需要能够识别表达式涉及的所有类型。允许null,线程上下文的classLoader将会被用到。
SpelParserConfiguration config = new SpelParserConfiguration(SpelCompilerMode.IMMEDIATE, this.getClass().getClassLoader()); 
SpelExpressionParser parser = new SpelExpressionParser(config);

2.4 在IoC容器中使用SpEL

<bean id="randomNumber" class="...">
    <property name="number" value="#{ T(java.lang.Math).random() }" />
</bean>

<bean id="guessNumber" class="...">
    <property name="correctNumber" value="#{ randomNumber.number }" />
</bean>
public class RandomNumber {
    @Value ("#{ T(java.lang.Math).random() }")
    int number;
    
    @Value("#{ systemProperties['user.region'] }")
    public void setDefaultLocale(String defaultLocale) {
        this.defaultLocale = defaultLocale;
    }
}

2.5 语言参考

SpEL有很多支持的表达式,可参考Spring Reference。






你可能感兴趣的:(Spring笔记 - 资源Resource、表达式语言SpEL)