月度归档: 2023年5月

JexlEngine表达式引擎的简单使用

JEXL 是一个表达式语言引擎,可以在应用程序或框架中实现动态和脚本功能。先写一个简单的例子,最直观的感受下。

依赖

首先我们是引入依赖包,添加pom文件中的dependency

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-jexl3</artifactId>
    <version>3.1</version>
</dependency>

基础用法

再新建一个测试用的对象类

public class TestJexlObj {
    private int numA;
    private int numB;

    //get.set方法省略
}

之后我们来写一份测试逻辑用的代码

@Test
public void test() {
    TestJexlObj testObj = new TestJexlObj();
    testObj.setNumA(12);
    testObj.setNumB(9);
    JexlEngine jexl = new Engine();
    JexlExpression expression = jexl.createExpression("'numA is '+testObj.getNumA()+' numB is '+testObj.getNumB()");
    JexlContext jc = new MapContext();
    jc.set("testObj", testObj);
    String str = String.valueOf(expression.evaluate(jc));
    System.out.println(str);
    JexlExpression expression2 = jexl.createExpression("'numA + numB = '+(testObj.getNumA()+testObj.getNumB())");
    String str2 = String.valueOf(expression2.evaluate(jc));
    System.out.println(str2);
}

执行后我们可以看到如下结果

以及一份多行构建java对象的表达式作为Script执行的示例代码

Continue reading

基于AOP的Redis缓存注解功能开发设计

在完成的前面的《Redis结合AOP实现限流注解的开发》之后,文中提到了一个配置管理或者字典管理的功能模块,作为一个对外提供快速查询获取配置信息的功能模块,其数据信息本身可以保存的Mysql数据库中。但如果每次查询都要从Mysql中获取数据则又非常影响接口效率和速度,故需要将对应信息在Redis中做一份缓存,帮助快速查询获取。

基础前置

需要的基础前置知识包括《Redis结合AOP实现限流注解的开发》AOP相关,《Java对象序列化常用操作-Protostuff》Java对象的序列化和反序列化,可以前往对应文章查看。

基础思路是这样的

首先我们需要定一个作用于方法上的注解比如@RedisCache(题外话,Spring自身也也有个类似功能的注解@Cacheable,回头可以再开一篇写下相关的使用方法,本文着重是自己开发一套这样的功能)。之后通过一个RedisCacheAspect类,使用@Around注解实现对添加了@RedisCache注解的方法的代理,并将方法的入参,执行结果序列化之后保存到Redis的一个Hash表中去。当下次请求过来的时候,先根据请求参数去Redis的Hash表中查询一下,如果存在,则将查到的信息反序列化为所要查询的对象直接返回给方法调用者。

代码实现

首先是注解类,我们需要新建一个这样的RedisCache注解类

/**
 * @author CheungQ
 */
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface RedisCache {
    String value();

    String key() default "";
}

之后,我们在自行实现一个切面类,用来定义切面,并实现切面上的功能。使用@Around注解,并在@RedisCache注解作用的方法前查询Redis中是否有缓存,如果有,则返回结果,如果没有则执行@RedisCache作用的方法,得到方法执行结果,并将结果缓存到Redis,待下次请求的时候查询获取。基本逻辑就是这样,具体的可以看下代码中的实现,这里用到了上面提到的前几篇文章中的相关技术细节。代码如下

Continue reading