/**
* aim to cache the data that‘s accessed frequently and costly.
* @param <K>
* @param <V>
*/
public interface Cache<K,V> {
V get(K k);
void put(K k, V v);
void clean();
int size();
}
/**
*this class is an implementor from Cache.and It cache data in thread local.
* @see Cache
* @see ThreadLocal
*/
public class ThreadLocalCache<K,V> implements Cache<K,V>{
private ThreadLocal<Map<K,V>> threadLocal = new ThreadLocal<>();
public ThreadLocal<Map<K, V>> getThreadLocal() {
return threadLocal;
}
public void setThreadLocal(ThreadLocal<Map<K, V>> threadLocal) {
this.threadLocal = threadLocal;
}
private Map<K, V> getThreadLocalMap(){
Map<K, V> map = getThreadLocal().get();
if (map == null){
map = new HashMap();
getThreadLocal().set(map);
}
return map;
}
protected void cleanThreadLocal(){
Map<K, V> map = getThreadLocal().get();
if (map != null)
map.clear();
getThreadLocal().remove();
}
private int sizeThreadLocal(){
Map<K, V> map = threadLocal.get();
return map == null ? 0 : map.size();
}
@Override
public V get(K k) {
return getThreadLocalMap().get(k);
}
@Override
public void put(K k, V v) {
getThreadLocalMap().put(k,v);
}
@Override
public void clean() {
cleanThreadLocal();
}
@Override
public int size() {
return sizeThreadLocal();
}
}
/**
* this class is to create a threadLocal through Factory.
* @see ThreadLocalFactory
* @see com.pretang.cloud.service.agent.AgentRpcService
*/
public class FactoryThreadLocalCache<K,V> extends ThreadLocalCache<K,V> {
public FactoryThreadLocalCache() {
super();
super.setThreadLocal(ThreadLocalFactory.getThreadLocal());
}
}
/**
* this class is a building ThreadLocal factory. And to manage the lifetime of the threadLocal.
* @see FactoryThreadLocalCache
*/
public abstract class ThreadLocalFactory {
// a sharing ThreadLocal in heap.
private static final ThreadLocal threadLocal = new ThreadLocal();
/**
* get a threadLocal instance.
* @return
*/
public static ThreadLocal getThreadLocal(){
return threadLocal;
}
/**
* clean the threadLocal
*/
public static void cleanThreadLocal(){
Object obj = threadLocal.get();
if (null != obj && obj instanceof Collection)
((Collection) obj).clear();
threadLocal.remove();
}
}
@Component
@WebFilter
public class CustomerFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
filterChain.doFilter(servletRequest,servletResponse);
// clean the variables in threads for a request
ThreadLocalFactory.cleanThreadLocal();
}
@Override
public void destroy() {
}
}
private static final Cache<Integer, AgentDto> agentDtoCache = new FactoryThreadLocalCache<>();
private static final Cache<Integer, AgentUser> agentUserCache = new FactoryThreadLocalCache<>();
using ThreadLocal to cache data in request scope
原文地址:http://blog.51cto.com/881206524/2104969