首先,如下代码是在一位大神代码的基础上进行了稍加修改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 会从新刷新缓存测试