基于cglib动态代理的缓存框架

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

相关文章
相关标签/搜索