Skip to content

feiqing/cachex

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

CacheX 注解缓存框架

1.7.3-Hessian-SNAPSHOT

  • 目前已接入10+应用, 欢迎同学们使用并提出宝贵建议~~

I. 架构

架构模型


II. 简单使用

配置

  • pom
<dependency>
    <groupId>com.github.cachex</groupId>
    <artifactId>cachex</artifactId>
    <version>${cachex.version}</version>
</dependency>
  • XML注册
<!-- 启用自动代理: 如果已经开启则不必重复开启 -->
<aop:aspectj-autoproxy proxy-target-class="true"/>

<!-- 配置CacheX切面(CacheX代理需要手动生效) -->
<bean id="cachex" class="com.github.cachex.CacheXAspect">
    <constructor-arg name="caches">
        <map>
            <entry key="default" value-ref="guava"/>
            <entry key="tair" value-ref="tair"/>
            <entry key="redis" value-ref="redis"/>
        </map>
    </constructor-arg>
</bean>

<!-- com.github.cachex.ICache 接口实现 -->
<bean id="guava" class="com.github.cachex.support.cache.GuavaCache">
    <constructor-arg name="expire" value="600000"/>
    <constructor-arg name="size" value="100000"/>
</bean>

<bean id="tair" class="com.github.cachex.support.cache.TairCache">
    <constructor-arg name="tairManager" ref="tairManager"/>
    <constructor-arg name="namespace" value="${engine.tair.namespace}"/>
</bean>

<bean id="redis" class="com.github.cachex.support.cache.RedisPoolCache">
    <constructor-arg name="jedisPool" ref="jedisPool"/>
</bean>

使用

1. 添加缓存(@Cached & @CacheKey)

  • 在要添加缓存的方法上标@Cached
  • 在要组装为key的方法参数上标@CacheKey


2. 缓存失效(@Invalid & @CacheKey)


III. 注解详解

CacheX提供如下注解@Cached@Invalid@CacheKey. (ext: @CachedGet@CachedWrite)


@Cached

  • 在需要走缓存的方法前添加@Cached注解.
/**
 * @author jifang
 * @since 2016/11/2 下午2:22.
 */
@Documented
@Target(value = ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Cached {

    /**
     * @return Specifies the <b>Used cache implementation</b>,
     * default the first {@code caches} config in {@code CacheXAspect}
     */
    String value() default "";

    /**
     * @return Specifies the start prefix on every key,
     * if the {@code Method} have non {@code param},
     * {@code prefix} is the <b>constant key</b> used by this {@code Method}
     */
    String prefix() default "";

    /**
     * @return use <b>SpEL</b>,
     * when this spel is {@code true}, this {@code Method} will go through by cache
     */
    String condition() default "";

    /**
     * @return expire time, time unit: <b>seconds</b>
     */
    int expire() default Expire.FOREVER;
}
属性 描述 Ext
value 指定缓存实现: CacheXAspect/CacheXProxycaches参数的key 选填: 默认为注入caches的第一个实现(即caches的第一个Entry实例)
prefix 缓存key的统一前缀 选填: 默认为"", 若方法无参或没有@CacheKey注解, 则必须在此配置一个prefix, 令其成为缓存静态常量key
condition SpEL表达式 选填: 默认为""(true), 在CacheX执行前会先eval该表达式, 当表达式值为true才会执行缓存逻辑
expire 缓存过期时间(秒) 选填: 默认为Expire.FOREVER

@Invalid

  • 在需要失效缓存的方法前添加@Invalid注解.
@Documented
@Target(value = ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Invalid {

    /**
     * @return as {@code @Cached}
     * @since 0.3
     */
    String value() default "";

    /**
     * @return as {@code @Cached}
     * @since 0.3
     */
    String prefix() default "";

    /**
     * @return as {@code @Cached}
     * @since 0.3
     */
    String condition() default "";
}

注解内属性含义与@Cached相同.


@CacheKey

  • 在需要作为缓存key的方法参数前添加@CacheKey注解.
@Documented
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface CacheKey {

    /**
     * @return use a part of param as a cache key part
     */
    String value() default "";

    /**
     * @return used multi model(value has `#i` index) and method return {@code Collection},
     * the {@code field} indicate which of the {@code Collection}'s entity field related with this param
     */
    String field() default "";
}
属性 描述 Ext
value SpEL表达式: 缓存key的拼装逻辑 选填: 默认为""
field 批量模式(value参数包含#i索引)且方法返回值为Collection时生效: 指明该返回值的某个属性是与该参数是关联起来的 详见Ext.批量模式

Ext. @CachedGet

  • 在需要走缓存的方法前添加@CachedGet注解.

@Cached的不同在于@CachedGet只会从缓存内查询, 不会写入缓存(当缓存不存在时, 只是会取执行方法, 但不讲方法返回内容写入缓存).

@Documented
@Target(value = ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface CachedGet {

    /**
     * @return Specifies the <b>Used cache implementation</b>,
     * default the first {@code caches} config in {@code CacheXAspect}
     * @since 0.3
     */
    String value() default "";

    /**
     * @return Specifies the start keyExp on every key,
     * if the {@code Method} have non {@code param},
     * {@code keyExp} is the <b>constant key</b> used by this {@code Method}
     * @since 0.3
     */
    String prefix() default "";

    /**
     * @return use <b>SpEL</b>,
     * when this spel is {@code true}, this {@Code Method} will go through by cache
     * @since 0.3
     */
    String condition() default "";
}

注解内属性含义与@Cached相同.


Ext. @CachedWrite

  • 在需要写缓存的方法前添加@CachedGet注解.

@Cached的不同在于@CachedWrite只会将方法执行返回值写入缓存, 但不会从缓存中加载数据(todo: 待实现).


Ext. 批量模式

在该模式下: #i指定了ids作为批量参数: 假设ids={1,2,3}, CacheX会结合前面的prefix组装出 {[USER]:1[USER]:2[USER]:3} 这3个key去批量的查询缓存, 假设只有{1,2}能够命中, 则CacheX会只保留{3}去调用getUsers()方法, 将返回值写入缓存后, 将两部分内容进行merge返回.

  1. 注意1: 如果方法的返回值为Collection实例: 则@CacheKey必须指定field参数, 该参数会指定Collection元素(如User)内的某个属性(如id)与批量参数的元素(如ids内的元素项)是一一对应的, 这样CacheX就可以根据该属性提取出参数值, 拼装key然后写入缓存.
  2. 注意2. 如果方法的返回值为Map实例: 则field属性不填, 默认使用Map的Key作为field.
  3. 注意3. #i作为批量模式指示器, 批量模式需要使用#i来开启, #i指明某个参数作为批量参数, CacheX会不断的迭代该参数生成批量缓存key进行缓存的读写.

Ext. SpEL执行环境

对于@CacheKey内的value属性(SpEL), CacheX在将方法的参数组装为key时, 会将整个方法的参数导入到SpEL的执行环境内, 所以在任一参数的@CacheKeyvalue属性内都可以自由的引用这些变量, 如: 尽管在arg0我们可以引用整个方法的任意参数, 但为了可读性, 我们仍然建议对某个参数的引用放在该参数自己的@CacheKey

注意: 在Java8环境中, 如果编译时没有指定-parameters参数, 则参数名默认为arg0arg1、...、argN, 如果指定了该参数, 则在spel中使用实际的参数名即可, 如:#source.name(); 为了兼容这两种方式, CacheX提供了自己的命名方式args0args1、...、argsN, 使用户可以不用区分是否开启编译参数.

Ext. CacheX当前默认支持的缓存实现

Releases

No releases published

Packages

No packages published

Languages