大数据平台技术笔记

扩展SpringCache注解

2022-06-14  本文已影响0人  OkGogogooo

1. 目标

实现4种自定注解:

  1. InstantCache,作用于方法,缓存方法的返回结果,1秒内有效。
  2. ShortCache,作用于方法,缓存方法的返回结果,方法超过10秒没有被调用,上次缓存的结果就失效。
  3. ModerateCache,作用于方法,缓存方法的返回结果,方法超过2分钟没有被调用,上次的结果就失效。
  4. LongCache,作用于方法,缓存方法的返回结果,10分钟内有效。

2. 实现

2.1 配置

        <dependency>
            <groupId>javax.cache</groupId>
            <artifactId>cache-api</artifactId>
            <version>1.1.1</version>
        </dependency>
        <dependency>
            <groupId>org.ehcache</groupId>
            <artifactId>ehcache</artifactId>
            <version>3.8.1</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-cache</artifactId>
            <version>2.4.4</version>
        </dependency>
#cache
spring.cache.type=jcache
spring.cache.jcache.provider=org.ehcache.jsr107.EhcacheCachingProvider
spring.cache.jcache.config=classpath:/ehcache.xml

2.2 注解定义

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Cacheable(cacheNames = "instantCache" , keyGenerator = "com.cimstech.ms.common.cache.MethodKeyGen")
public @interface InstantCache {
}
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Cacheable(cacheNames = "shortCache" , keyGenerator = "com.cimstech.ms.common.cache.MethodKeyGen")
public @interface ShortCache {
}
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Cacheable(cacheNames = "moderateCache" , keyGenerator = "com.cimstech.ms.common.cache.MethodKeyGen")
public @interface ModerateCache {
}
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Cacheable(cacheNames = "longCache" , keyGenerator = "com.cimstech.ms.common.cache.MethodKeyGen")
public @interface LongCache {
}
@Documented
@Retention(RUNTIME)
@Target({ TYPE })
@Import(MethodKeyGen.class)
@EnableCaching
public @interface EnableCache
{
}

2.3 MethodKeyGen实现

@Component
public class MethodKeyGen implements KeyGenerator
{
    
    public MethodKeyGen()
    {
    }

    @Override
    public Object generate(Object aTarget, Method aMethod, Object... aParams)
    {
        String objId = getClass().getName() + "@" + Integer.toHexString(System.identityHashCode(aTarget)) ;
                # XString.toString()用来拼接参数,每个参数转成String,用“()”包裹,然后用“,”连接
        return objId +"."+aMethod.getName()+XString.toString(",", "(", ")", aParams) ;
    }

}

2.4 ehcache.xml配置

<?xml version="1.0" encoding="UTF-8"?>
<config xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:jsr107='http://www.ehcache.org/v3/jsr107' xmlns='http://www.ehcache.org/v3'
    xsi:schemaLocation="http://www.ehcache.org/v3 http://www.ehcache.org/schema/ehcache-core-3.1.xsd
        http://www.ehcache.org/v3/jsr107 http://www.ehcache.org/schema/ehcache-107-ext-3.1.xsd">
    
    <!-- 距离加入缓存开始超过1秒,就从缓存中清楚 -->
    <cache alias="instantCache">
        <key-type>java.lang.String</key-type>
        <value-type>java.lang.Object</value-type>
        <expiry>
            <ttl unit="seconds">1</ttl>
        </expiry>
        <heap unit="entries">2000</heap>
    </cache>

    <!-- 距上次取用超过10秒,将从缓存中清除 -->
    <cache alias="shortCache">
        <key-type>java.lang.String</key-type>
        <value-type>java.lang.Object</value-type>
        <expiry>
            <tti unit="seconds">10</tti>
        </expiry>
        <heap unit="entries">1000</heap>
    </cache>
    
    <!-- 距上次取用超过2分钟,将从缓存中清除 -->
    <cache alias="moderateCache">
        <key-type>java.lang.String</key-type>
        <value-type>java.lang.Object</value-type>
        <expiry>
            <tti unit="minutes">2</tti>
        </expiry>
        <heap unit="entries">2000</heap>
    </cache>
    
    <!-- 距对象加入缓存开始超过10分钟,将从缓存中清除 -->
    <cache alias="longCache">
        <key-type>java.lang.String</key-type>
        <value-type>java.lang.Object</value-type>
        <expiry>
            <ttl unit="minutes">10</ttl>
        </expiry>
        <heap unit="entries">2000</heap>
    </cache>
</config>

3. 使用方法

@EnableCache
@SpringBootApplication
public class MainApplication
{
...省略更多
}
@Component
public class TaskServerSite
{
    @InstantCache
    public JSONArray getTasksOfType(String aName , TaskType aTaskType)
    {
        ...省略代码
    }
}

需要注意,SpringCache的内部实现是基于AOP的,这是一种代理技术,意味着同一个对象的方法间相互调用,缓存是不会起作用的。如果原先不是很理解AOP技术,可以这样类比理解,AOP代理相当于网关,不同对象间相互调用,相当于不同服务经过网关相互调用,网关就可以帮忙做缓存,而同一个对象的方法间相互调用,相当于服务自己调自己的接口,是不经过网关的,网关上的缓存就不会起作用。

上一篇下一篇

猜你喜欢

热点阅读