首先,如下代碼是在一位大神代碼的基礎上進行了稍加修改java
1、自定義緩存框架
所用到的技術:cglib動態代理(MethodInterceptor),自定義註解,BeanPostProcessor接口的使用,
實現org.springframework.cglib.proxy.MethodInterceptor接口,能夠作到環繞加強
實現org.springframework.beans.factory.config.BeanPostProcessor接口,能夠在Spring上下文初始化Bean先後,增長本身的業務邏輯spring
2、使用的類以下
CacheProxy.java => 定義哪裏類的方法進行緩存(類級別註解)緩存
package com.wilbur.cache; @Target(ElementType.TYPE) @Retention(Retention.RUNTIME) public @interface CacheProxy{ }
Cache.java => 定義哪些方法進行緩存(方法級別註解) package com.wilbur.cache;app
@Target(ElementType.METHOD) @Retention(Retention.RUNTIME) public @interface Cache{ //時間刻度,天、時、分... int timeScale(); //時間間隔 int timeInterval(); }
CacheWrapper.java => 緩存包裝類,定義過時刷新,及緩存值框架
package com.wilbur.cache; public class CacheWrapper<T>{ //緩存對象 T cacheValue; //定時器 Calendar timer; //定時器域(時分秒..) int field; //定時器間隔 int amount; public CacheWrapper(Cache cache){ this(cache.timeScale(),cache.timeInterval()); } public CacheWrappe(int field,int amount){ this.field = field; this.amount = amount; resetTimer(); } public void resetTimer(){ timer = Calendar.getInstance(); timer.add(field,amount); } public boolean isTimeOut(){ return Calendar.getInstance().after(timer); } public T getCacheValue(){ return cacheValue; } public void setCacheValue(){ this.cacheValue = cacheValue; } }
CacheMethodInterceptor.java => 代理類,主要的業務邏輯dom
package com.wilbur.cache; public class CacheMethodInterceptor implements MethodInterceptor{ //代理對象 private Object target; //緩存 private Map<String,CacheWrapper<Object>> cacheWrapper = new HashMap<String,CacheWrapper<Object>>(); public CacheMethodInterceptor (){ } public CacheMethodInterceptor (Object target){ this.target = target; } @override public Object intercept(Object arg0,Method method,Object[] args,MethodProxy proxy) thows Throwable{ Object result = null; CacheWrapper wrapper = null; Cache cache = method.getAnnotation(Cache.class); if(!(cache == null && cache.timeInterval() <= 0)){ if(cacheWrapper.containsKey(method.toString())){ wrapper = cacheWrapper.getKey(method.toString()); }else{ wrapper = new CacheWrapper(cache); result = method.invoke(target,args); wrapper.setCacheValue(result ); cacheWrapper.put(method.toString(),wrapper); } if(wrapper.isTimeOut()){ //緩存過時 synchronized(wrapper){ if(wrapper.isTimeOut()){ wrapper.resetTimer(); result = method.invoke(target,args); wrapper.setCacheValue(result); }else{ result = wrapper.getCacheValue(); } } }else{ result = wrapper.getCacheValue(); } }else{ //若是不需求緩存,即沒有Cache註解 result = method.invoke(target,args); } return result; } }
CachePostBeanProcessor.java => Spring容器初始化時,爲緩存的類進行代理類ide
package com.wilbur.cache; public class CachePostBeanProcessor implements BeanPostProcessor{ @override public Object postProcessAfterInitialization(Object bean,String beanName) throws BeansException{ if(bean.getClass().isAnnotationPresent(CacheProxy.class)){ //若是是代理的類 Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(bean.getClass()); enhancer.setCallback(new CachceMethodInterceptor(bean)); return enhancer.create(); }else{ return bean; } } public Object postProcessBeforeInitialization(Object bean,String beanNames) throws BeansException{ return bean; } }
3、測試 package com.wilbur.domain;post
public User{ private String name; private int age; public User(){ } public User(String name,int age){ this.name = name; this.age = age; } public String toString(){ return "User: name = " + name + " age = " + age; } } package com.wilbur.repository; public class UserRepository{ public UserRepository(){ } public User getUser(){ return new User("wilbur",10); } } package com.wilbur.service; public interface IUserService{ public User getUser(); } package com.wilbur.service.impl; @CacheProxy public class UserServiceImpl implements IUserService{ //10秒刷新一次 @Cache(timeScale = Calendar.SENCOD,timeInterval = 10) public User getUser(){ System.out.println("Time Out"); return new UserRepository().getUser(); } } package test; public class Test{ public static void main(String[] args){ ApplicationContext context = ClassPathXmlApplicationContext("beans.xml"); IUserService serivce = (IUserService)context.getBean("IUserService"); while(true){ System.out.println(serivce.getUser()); try{ Thread.sleep(1000); }catch(EXception e){ } } } } beans.xml <bean class="com.wilbur.cache.CachePostBeanProcessor"/> <bean id="IUserService" class="com.wilbur.service.impl.UserServiceImpl"/>
4、結果
咱們能夠看到Time Out 10s出現一次,說明10s 會從新刷新緩存測試