代理模式实现缓存
静态代理
代理类在编译时就已经确定
创建数据查询接口
public interface DataQuery {
String query(String queryKey);
}
创建被代理类
public class MySQLDataQuery implements DataQuery {
@Override
public String query(String queryKey) {
// 查询数据库并返回结果
System.out.println("查询数据库:" + queryKey);
return queryKey;
}
}
创建代理类
public class MySQLDataQueryProxy implements DataQuery {
private final DataQuery dataQuery;
private final Map<String, String> cache = new HashMap<>(16);
public MySQLDataQueryProxy() {
this.dataQuery = new MySQLDataQuery();
}
@Override
public String query(String queryKey) {
String result = cache.get(queryKey);
if (result == null) {
System.out.println("未命中缓存:" + queryKey);
result = dataQuery.query(queryKey);
cache.put(queryKey, result);
System.out.println("已存入缓存:" + queryKey);
} else {
System.out.println("命中缓存:" + queryKey);
}
return result;
}
}
测试代码
@Test
public void testStatic() {
DataQuery dataQuery = new MySQLDataQueryProxy();
dataQuery.query("k1");
System.out.println("--------------------------------");
dataQuery.query("k1");
System.out.println("--------------------------------");
dataQuery.query("k2");
System.out.println("--------------------------------");
}
测试结果
未命中缓存:k1
查询数据库:k1
已存入缓存:k1
命中缓存:k1
未命中缓存:k2
查询数据库:k2
已存入缓存:k2
动态代理
动态代理是指代理类在运行时动态生成。
JDK动态代理
创建数据查询接口
public interface DataQuery {
String query(String queryKey);
}
创建被代理类
public class MySQLDataQuery implements DataQuery {
@Override
public String query(String queryKey) {
// 查询数据库并返回结果
System.out.println("JDK-查询数据库:" + queryKey);
return queryKey;
}
}
创建InvocationHandler接口的实现类
public class CacheInvocationHandler implements InvocationHandler {
private DataQuery dataQuery;
private Map<String, String> cache = new HashMap<>(1024);
public CacheInvocationHandler() {
dataQuery = new MySQLDataQuery();
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
String result = null;
if ("query".equals(method.getName())) {
result = cache.get(args[0].toString());
if (result != null) {
System.out.println("JDK-命中缓存:" + args[0].toString());
return result;
}
System.out.println("JDK-未命中缓存:" + args[0].toString());
result = (String) method.invoke(dataQuery, args);
cache.put(args[0].toString(), result);
System.out.println("JDK-已存入缓存:" + args[0].toString());
return result;
}
return method.invoke(dataQuery, args);
}
}
创建Proxy类的实例并测试
@Test
public void testJDK() {
ClassLoader classLoader = TestProxy.class.getClassLoader();
Class[] interfaces = new Class[]{DataQuery.class};
InvocationHandler invocationHandler = new CacheInvocationHandler();
DataQuery dataQuery = (DataQuery) Proxy.newProxyInstance(
classLoader, interfaces, invocationHandler
);
dataQuery.query("k1");
System.out.println("--------------------------------");
dataQuery.query("k1");
System.out.println("--------------------------------");
dataQuery.query("k2");
System.out.println("--------------------------------");
}
测试结果
JDK-未命中缓存:k1
JDK-查询数据库:k1
JDK-已存入缓存:k1
JDK-命中缓存:k1
JDK-未命中缓存:k2
JDK-查询数据库:k2
JDK-已存入缓存:k2
CGLIB动态代理
创建被代理类
public class MySQLDataQuery{
public String query(String queryKey) {
// 查询数据库并返回结果
System.out.println("CGLIB-查询数据库:" + queryKey);
return queryKey;
}
}
创建MethodInterceptor接口的实现类
public class CacheMethodInterceptor implements MethodInterceptor {
private HashMap<String, String> cache = new HashMap<>(16);
private MySQLDataQuery dataQuery;
public CacheMethodInterceptor() {
this.dataQuery = new MySQLDataQuery();
}
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
String result = null;
if ("query".equals(method.getName())) {
result = cache.get(args[0].toString());
if (result != null) {
System.out.println("CGLIB-命中缓存:"+args[0].toString());
return result;
}
System.out.println("CGLIB-未命中缓存:"+args[0].toString());
result = (String) method.invoke(dataQuery, args);
cache.put(args[0].toString(), result);
System.out.println("CGLIB-已存入缓存:"+args[0].toString());
return result;
}
return method.invoke(dataQuery, args);
}
}
创建Enhancer类并测试
@Test
public void testCglib(){
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(MySQLDataQuery.class);
enhancer.setCallback(new CacheMethodInterceptor());
MySQLDataQuery dataQuery = (MySQLDataQuery)enhancer.create();
dataQuery.query("k1");
System.out.println();
dataQuery.query("k1");
System.out.println();
dataQuery.query("k2");
System.out.println();
}
测试结果
CGLIB-未命中缓存:k1
CGLIB-查询数据库:k1
CGLIB-已存入缓存:k1
CGLIB-命中缓存:k1
CGLIB-未命中缓存:k2
CGLIB-查询数据库:k2
CGLIB-已存入缓存:k2