开发者社区> 问答> 正文

JFINAL注解如何清除多个缓存?报错

jfinal注解清除缓存,如何清除多个,@CacheName("order_cache","order_cache")这种写法报错,

也无法多个@CacheName

展开
收起
爱吃鱼的程序员 2020-06-06 10:49:40 487 0
1 条回答
写回答
取消 提交回答
  • https://developer.aliyun.com/profile/5yerqm5bn5yqg?spm=a2c6h.12873639.0.0.6eae304abcjaIB
                        <p>扒一下 <strong>EvictInterceptor.java</strong> 自己做一个啦。</p> 
    

    自己做一个 EvictInterceptor 的子类 MultiEvictInterceptor ,主要功能是 增强 原先父类的业务,支持自己定义的注解,并且也支持 原先 JFinal 的 CacheName 注解。

    自己写一个注解 MultiCacheName :

    package com.rocbin.demo;
    
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.METHOD)
    public @interface MultiCacheName {
        String[] value();
    }
    

    拦截器和注解结合的桥梁就是通过 Java 反射,通过反射来获取 被调用的 Method(方法)的注解,然后进一步取得注解配置的信息,最后做一些基于配置的反应操作。

    想要搞懂那就去看 EvictInterceptor.java ,估计里面都涉及到上面的知识点。

    最后,建议一点点,反射 Method 最好能加一个 Cache:

    ConcurrentHashMap<Method, String[]> MultiEvictCacheNameMap;
    // KEY 存对于的 Method
    // VALUE 是 对应注解上面的信息,下次取缓存,如命中则无需再次反射。

     

                        <p>拦截器代码实现只是增强一下,支持自己的注解也支持 JFinal 的注解: </p> 
    
    package com.rocbin.demo;
    
    public class MultiEvictInterceptor extends com.jfinal.plugin.ehcache.EvictInterceptor implements Interceptor {
    	
    	final public void intercept(Invocation inv) {
    		inv.invoke();
    		String name = buildCacheName(inv);
            String[] multiName = buildMultiCacheName(inv);
            Set<String> nameSet = new HashSet();
            if(name!=null)
               nameSet.add(name);
            nameSet.addAll(Arrays.asList(multiName));
    
    		if (nameSet.isEmpty())
    			throw new RuntimeException("MultiEvictInterceptor need CacheName or MultiCacheName annotation in controller.");
            for(String name: nameSet)
    		   CacheKit.removeAll(name);
    	}
    	
    	private String[] buildMultiCacheName(Invocation inv) {
    		MultiCacheName cacheName = inv.getMethod().getAnnotation(MultiCacheName.class);
    		if (cacheName != null)
    			return cacheName.value();
    		cacheName = inv.getController().getClass().getAnnotation(MultiCacheName.class);
    		return cacheName != null ? cacheName.value() : new String[]{};
    	}
    	
    	private String buildCacheName(Invocation inv) {
    		CacheName cacheName = inv.getMethod().getAnnotation(CacheName.class);
    		if (cacheName != null)
    			return cacheName.value();
    		
    		cacheName = inv.getController().getClass().getAnnotation(CacheName.class);
    		return cacheName != null ? cacheName.value() : null;
    	}
    }

     

                            又是 业务注解,又是 <a class="referer" target="_blank">@Before</a> ,写多了就累赘,全局 拦截器 自动按 Method 注解 查找 注册的 拦截器 调用处理,更完美。<a class="referer" target="_blank">@JFinal</a> 
                        
    
                        <p>建议扩展一下 EvictIntercpetor 用于支持这种形式: @CacheName("order_cache","order_cache")这种写法报错</p> 
    

     

    扩展起来很容易,基本就是添加一个 cacheName.splite(",") 就可以了

    2020-06-06 10:49:57
    赞同 展开评论 打赏
问答排行榜
最热
最新

相关电子书

更多
基于英特尔 SSD 的虚拟机缓存解决SSD 立即下载
用户态高速块缓存方案 立即下载
高性能Web架构之缓存体系 立即下载