扒一下 EvictInterceptor.java 自己做一个啦。
自己做一个 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 MultiEvictCacheNameMap;
// KEY 存对于的 Method
// VALUE 是 对应注解上面的信息,下次取缓存,如命中则无需再次反射。
拦截器代码实现只是增强一下,支持自己的注解也支持 JFinal 的注解:
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 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;
}
}
又是 业务注解,又是 @Before ,写多了就累赘,全局 拦截器 自动按 Method 注解 查找 注册的 拦截器 调用处理,更完美。@JFinal
建议扩展一下 EvictIntercpetor 用于支持这种形式: @CacheName("order_cache","order_cache")这种写法报错
扩展起来很容易,基本就是添加一个 cacheName.splite(",") 就可以了