代理模式是 Java 中的常用设计模式,代理类通过调用被代理类的相关方法,提供预处理、过滤、事后处理等服务,动态代理及通过反射机制动态实现代理机制。
JDK的动态代理,就是在程序运行的过程中,根据被代理的接口来动态生成代理类的class文件,并加载运行的过程。JDK 中的 java.lang.reflect.Proxy 类可以用来实现动态代理。
主题接口:
package cn.com.proxy;
/**
* @author water
* @version 创建时间:2016年6月6日 下午4:01:37
* 代理类和被代理对象需要实现的接口
*/
public interface IDBQuery {
String request();
}
主题类:
package cn.com.proxy;
/**
* @author water
* @version 创建时间:2016年6月6日 下午4:02:59
* 被代理对类
*/
public class DBQuery implements IDBQuery {
/**
* 在这里我们让请求方法睡眠5秒
*/
@Override
public String request() {
// TODO Auto-generated method stub
try{
Thread.sleep(5000);
}catch(Exception e){
e.printStackTrace();
}
System.out.println("you have accessed request method");
return "OK";
}
}
Jdk处理逻辑类
package cn.com.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
/**
* @author water
* @version 创建时间:2016年6月7日 上午9:55:10
* JDK动态代理需要实现一个主题处理方法的Handler,用于实现代理方法的逻辑
*/
public class JdkDBQueryHandler implements InvocationHandler {
IDBQuery realOb;//真实主题
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// TODO Auto-generated method stub
if(realOb == null)
realOb = new DBQuery();//第一次调用,则生成真是对象
return realOb.request();//使用真实主题完成实际操作
}
}
jdk动态代理类
package cn.com.proxy;
import java.lang.reflect.Proxy;
/**
* @author water
* @version 创建时间:2016年6月7日 上午10:00:05
* 动态代理类,用于生成动态代理对象
*/
public class JdkDBQueryProxy {
/**
* 创建JDK动态代理对象
* @return
*/
public static IDBQuery createJdkProxy(){
//使用Proxy创建代理对象
IDBQuery jdkProxy = (IDBQuery) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(),
new Class[]{IDBQuery.class}, new JdkDBQueryHandler());
return jdkProxy;
}
}
jdk动态代理测试类
package cn.com.proxy;
/**
* @author water
* @version 创建时间:2016年6月7日 上午10:06:41
* Jdk动态代理测试类
*/
public class JdkDBQueryProxyTest {
public static void main(String[] args) {
//调用动态代理类生成代理对象
IDBQuery dbQueryProxy = JdkDBQueryProxy.createJdkProxy();
//实现代理对象的请求方法
dbQueryProxy.request();
}
}
CGLIB动态代理
cglib处理逻辑类
package cn.com.proxy;
import java.lang.reflect.Method;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
/**
* @author water
* @version 创建时间:2016年6月7日 上午10:14:55
* 实现CGLib的动态代理,首先要实现一个处理代理逻辑的切入类
*/
public class CGLibDBQueryMethodInterceptor implements MethodInterceptor {
IDBQuery realOb;//真实主题
@Override
public Object intercept(Object paramObject, Method paramMethod, Object[] paramArrayOfObject,
MethodProxy paramMethodProxy) throws Throwable {
// TODO Auto-generated method stub
if(realOb == null)
realOb = new DBQuery();//第一次调用,则生成真是对象
return realOb.request();//使用真实主题完成实际操作
}
}
cglib代理类
package cn.com.proxy;
import net.sf.cglib.proxy.Enhancer;
/**
* @author water
* @version 创建时间:2016年6月7日 上午10:17:03
* CGLib动态代理类
*/
public class CGLibDBQueryProxy {
//创建动态代理对象
public static IDBQuery createDBQueryProxy(){
Enhancer enhancer = new Enhancer();
//指定切入器,定义代理类逻辑
enhancer.setCallback(new CGLibDBQueryMethodInterceptor());
//指定实现逻辑的接口
enhancer.setInterfaces(new Class[]{IDBQuery.class});
//创建动态代理类的实例
IDBQuery cglibProx = (IDBQuery) enhancer.create();
return cglibProx;
}
}
cglib测试类
package cn.com.proxy;
/**
* @author water
* @version 创建时间:2016年6月7日 上午10:06:41
* CGLib动态代理测试类
*/
public class CGLibDBQueryProxyTest {
public static void main(String[] args) {
//调用动态代理类生成代理类的实例
IDBQuery dbQueryProxy = CGLibDBQueryProxy.createDBQueryProxy();
//实现代理类的实例的逻辑
dbQueryProxy.request();
}
}