Annotation实现缓存

设计:
1. 定义一个接口
2. 定义一个实现类
3. 定义一个Annotation
4. 定义一个Annotation解析器
5. 定义一个Proxy
6. 定义一个proxy来代理接口实现。

代码如下:

package org.frame.base.annotation.intercept;

public interface TestI {
public int add(int a,int b);
public int xx(int a);
}


实现类

public class Test implements TestI{
public int add(int a,int b){
return a+b;
}

@EhCache(key="cacheKey")
public int xx(int a){
return a;
}
}


Annotation类

package org.frame.base.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
* Annotation indicating that a method (or all the methods on a class) can be cached.
*
* <p>The method arguments and signature are used for computing the key while the
* returned instance is used as the cache value.
*
* @author xxx
* @since 1.0
*/
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface EhCache {

/**
* Name of the caches in which the update takes place.
* <p>May be used to determine the target cache (or caches), matching the
* qualifier value (or the bean name(s)) of (a) specific bean definition.
*/
String[] value() default "";

/**
* Spring Expression Language (SpEL) attribute for computing the key dynamically.
* <p>Default is "", meaning all method parameters are considered as a key.
*/
String key() default "";

/**
* Spring Expression Language (SpEL) attribute used for conditioning the method caching.
* <p>Default is "", meaning the method is always cached.
*/
String condition() default "";
}


Annotation解析类

package org.frame.base.annotation;

import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.Set;

import org.springframework.util.Assert;

/**
* EhCache的操作对象
*
*
*/
public class EhCacheOperator {

private String name;
private Set<String> cacheNames = Collections.emptySet();//value
private String key = "";//key
private String condition = "";//condition
public Set<String> getCacheNames() {
return cacheNames;
}
public void setCacheNames(String[] cacheNames) {
Assert.notEmpty(cacheNames);
this.cacheNames = new LinkedHashSet<String>(cacheNames.length);
for (String string : cacheNames) {
this.cacheNames.add(string);
}
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public String getCondition() {
return condition;
}
public void setCondition(String condition) {
this.condition = condition;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}


代理类

package org.frame.base.annotation.intercept;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.Collection;

import org.frame.base.annotation.CachePaserImpl;
import org.frame.base.annotation.EhCacheOperator;
import org.frame.base.annotation.support.EhCacheAnnotationParser;
import org.frame.base.cache.LocalCacheManager;

/**
* 在代理层使用缓存
*
*/
public class ProxyHandler implements InvocationHandler {

EhCacheAnnotationParser ehcacheParser = new EhCacheAnnotationParser();
LocalCacheManager cacheManager = LocalCacheManager.getInstance();

private Object target;

public void setTarget(Object o){
this.target = o;
}

public ProxyHandler(Object target){
this.target = target;
}

@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
Object result = null;
Collection<EhCacheOperator> ehcacheOperators = ehcacheParser.getCacheOperations(method, target.getClass());
if(ehcacheOperators == null || ehcacheOperators.isEmpty()){
result = method.invoke(target, args);
}else{
for(EhCacheOperator ehcacheOperator:ehcacheOperators ){
if(ehcacheOperator.getName().equals(CachePaserImpl.EHCACHE)){//ehcache 注解
Object cacheObj = cacheManager.get(ehcacheOperator.getKey());
if(cacheObj == null){
result = method.invoke(target, args);
if(result != null){
cacheManager.put(ehcacheOperator.getKey(), result);
}
}else{
result = cacheObj;
}
}
}
}

return result;
}

}



代理接口实现类

package org.frame.base.annotation.support;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;

import org.frame.base.annotation.intercept.ProxyHandler;
import org.springframework.beans.factory.FactoryBean;

/**
* 代理某个对象的所有接口
*
*/
public class EhCacheFactoryBean implements FactoryBean{

private Object target;

private Object proxyObj = null;

private Class<?>[] interfaceClass = null;

public void setTarget(Object target){
this.target = target;
}

/**
* 接口反映返回对象
* 1. serviceInterface 接口
* 2. target 目标地址,IP:端口
* @throws Exception
*/
public void init() throws Exception {
interfaceClass = target.getClass().getInterfaces();
InvocationHandler handler = new ProxyHandler(target);
proxyObj = Proxy.newProxyInstance(target.getClass().getClassLoader(),
interfaceClass, handler);
}

@Override
public Object getObject() throws Exception {
return proxyObj;
}

@SuppressWarnings("unchecked")
@Override
public Class getObjectType() {
return interfaceClass[0];
}

@Override
public boolean isSingleton() {
return true;
}

}



配置如下:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans default-autowire="byName">
<!-- annotation intercept-->
<bean id="testIano"
class="org.frame.base.annotation.support.EhCacheFactoryBean" init-method="init">
<property name="target">
<ref bean = "testI"/>
</property>
</bean>

<!-- 原始结构 -->
<bean id="testI" class ="org.frame.base.annotation.intercept.Test"/>

</beans>


测试代码如下:

ApplicationContext cxt = new ClassPathXmlApplicationContext(new String[]{"annotation/ano.xml"});
//TestI testI = (TestI) cxt.getBean("testI");
TestI testI = (TestI) cxt.getBean("testIano");
int a = 10;
int b = 11;
System.out.println(testI.add(a, b));
System.out.println(testI.add(a, b));
System.out.println(testI.xx(a));
System.out.println(testI.xx(a));

可以看到配置了Ehcache的方法实现了缓存功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值