基于cglib动态代理的缓存框架
2013-10-11 16:27
267 查看
首先,以下代码是在一位大神代码的基础上进行了稍加修改
一、自定义缓存框架
所用到的技术:cglib动态代理(MethodInterceptor),自定义注解,BeanPostProcessor接口的使用,
实现org.springframework.cglib.proxy.MethodInterceptor接口,可以做到环绕增强
实现org.springframework.beans.factory.config.BeanPostProcessor接口,可以在Spring上下文初始化Bean前后,增加自己的业务逻辑
二、使用的类如下
CacheProxy.java => 定义哪里类的方法进行缓存(类级别注解)
Cache.java => 定义哪些方法进行缓存(方法级别注解)
package com.wilbur.cache;
CacheWrapper.java => 缓存包装类,定义过期刷新,及缓存值
CacheMethodInterceptor.java => 代理类,主要的业务逻辑
CachePostBeanProcessor.java => Spring容器初始化时,为缓存的类进行代理类
三、测试
package com.wilbur.domain;
四、结果
我们可以看到Time Out 10s出现一次,说明10s 会重新刷新缓存
一、自定义缓存框架
所用到的技术:cglib动态代理(MethodInterceptor),自定义注解,BeanPostProcessor接口的使用,
实现org.springframework.cglib.proxy.MethodInterceptor接口,可以做到环绕增强
实现org.springframework.beans.factory.config.BeanPostProcessor接口,可以在Spring上下文初始化Bean前后,增加自己的业务逻辑
二、使用的类如下
CacheProxy.java => 定义哪里类的方法进行缓存(类级别注解)
package com.wilbur.cache; @Target(ElementType.TYPE) @Retention(Retention.RUNTIME) public @interface CacheProxy{ }
Cache.java => 定义哪些方法进行缓存(方法级别注解)
package com.wilbur.cache;
@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 => 代理类,主要的业务逻辑
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容器初始化时,为缓存的类进行代理类
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; } }
三、测试
package com.wilbur.domain;
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"/>
四、结果
我们可以看到Time Out 10s出现一次,说明10s 会重新刷新缓存
相关文章推荐
- 【框架】[Spring] 基于Spring框架的Web应用演示(附带cglib工具进行动态代理)
- [置顶] Java的静态代理、动态代理,CGLib的动态代理,使用动态代理基于AOP的AspectJ框架—深入探究
- 框架 day37 Spring3,AOP,代理模式(动态/CGLIB/工厂bean),传统AOP,AspectJ框架(基于xml/注解),切入点表达式,jdbcTemplate
- Java的静态代理、动态代理,CGLib的动态代理,使用动态代理基于AOP的AspectJ框架—深入探究
- Java的静态代理、动态代理,CGLib的动态代理,使用动态代理基于AOP的AspectJ框架—深入探究
- 无代理不框架,浅析JDK和Cglib动态代理
- 框架 day54 BOS项目练习(权限/角色/用户管理(CRUD),基于数据库实现动态授权,ehcache缓存权限,shiro标签,菜单权限展示)
- Spring -- <tx:annotation-driven>注解基于JDK动态代理和CGLIB动态代理的实现Spring注解管理事务(@Trasactional)的区别。
- 基于JDK动态代理和CGLIB动态代理的实现Spring注解管理事务(@Trasactional)到底有什么区别
- 由service层接口有什么用?引申到基于JDK原生和CGLIB动态代理实现spring事务管理的机制的思考
- 基于JDK动态代理和CGLIB动态代理的实现Spring注解管理事务(@Trasactional)到底有什么区别。
- 基于cglib实现的动态代理原理与源码解析
- 基于jdk和cglib实现的动态代理
- spring aop学习7:Cglib动态代理(基于继承代理)
- 基于JDK动态代理和CGLIB动态代理的实现Spring注解管理事务(@Trasactional)到底有什么区别。
- 基于JDK和CGLib的链式动态代理
- 基于JDK动态代理和CGLIB动态代理的实现Spring注解管理事务(@Trasactional)到底有什么区别。
- 基于JDK动态代理和CGLIB动态代理的实现Spring注解管理事务(@Trasactional)到底有什么区别。
- Spring aop 基于JDK动态代理和CGLIB代理的原理以及为什么JDK代理需要基于接口
- 基于JDK动态代理和CGLIB动态代理的实现Spring注解管理事务(@Trasactional)到底有什么区别。