扩展SpringCache注解

作者: OkGogogooo | 来源:发表于2022-06-14 17:57 被阅读0次

    1. 目标

    实现4种自定注解:

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

    2. 实现

    2.1 配置

    • pom.xml
            <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>
    
    • application.properties
    #cache
    spring.cache.type=jcache
    spring.cache.jcache.provider=org.ehcache.jsr107.EhcacheCachingProvider
    spring.cache.jcache.config=classpath:/ehcache.xml
    

    2.2 注解定义

    • InstantCache
    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)
    @Cacheable(cacheNames = "instantCache" , keyGenerator = "com.cimstech.ms.common.cache.MethodKeyGen")
    public @interface InstantCache {
    }
    
    • ShortCache
    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)
    @Cacheable(cacheNames = "shortCache" , keyGenerator = "com.cimstech.ms.common.cache.MethodKeyGen")
    public @interface ShortCache {
    }
    
    • ModerateCache
    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)
    @Cacheable(cacheNames = "moderateCache" , keyGenerator = "com.cimstech.ms.common.cache.MethodKeyGen")
    public @interface ModerateCache {
    }
    
    • LongCache
    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)
    @Cacheable(cacheNames = "longCache" , keyGenerator = "com.cimstech.ms.common.cache.MethodKeyGen")
    public @interface LongCache {
    }
    
    • EnableCache
    @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. 使用方法

    • MainApplication上加上@EnableCache
    @EnableCache
    @SpringBootApplication
    public class MainApplication
    {
    ...省略更多
    }
    
    • 在需要缓存的地方上加上期望的缓存注解
    @Component
    public class TaskServerSite
    {
        @InstantCache
        public JSONArray getTasksOfType(String aName , TaskType aTaskType)
        {
            ...省略代码
        }
    }
    

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

    相关文章

      网友评论

        本文标题:扩展SpringCache注解

        本文链接:https://www.haomeiwen.com/subject/hibzmrtx.html