意图
- 安全原因. 屏蔽真是对象
- 延迟加载
代码
- 定义一个接口
public interface IDBQuery {
String request();
}
- 真正实现类
public class DBQuery implements IDBQuery{
public DBQuery(){
try{
Thread.sleep(1000);
}catch (InterruptedException e){
e.printStackTrace();
}
}
public String request() {
System.out.println("request string");
return "request string";
}
}
- 代理类, 创建速度快, 用于代替DBQuery的位置
public class DBQueryProxy implements IDBQuery{
private DBQuery real = null;
public String request() {
if(real == null)
real = new DBQuery();
return real.request();
}
}
- 主函数. 用代理类替代真实类创建IDBQuery, 当真正调用时在初始化真实对象
public class Main {
public static void main(String[] args) {
IDBQuery q = new DBQueryProxy();
q.request();
}
}
动态代理
动态代理是指在运行时, 动态生成代理类. 即, 代理类的字节码将在运行时生成并载入当前的ClassLoader.
动态代理的加载过程:
- 根据指定的回调类生成Class字节码
- 通过ReflectUtils.defineClass()调用ClassLoader.defineClass(),将字节码装载到ClassLoader中
- 使用ReflectUtils.newInstance() 反射机制生成该类的实例
代码
- 使用JDK自带的动态代理
public class JdkDbQueryHandle implements InvocationHandler{
IDBQuery real = null;
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if(real == null)
real = new DBQuery();
return real.request();
}
public IDBQuery createJdkProxy(){
IDBQuery jdkProxy = (IDBQuery)Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[]{ IDBQuery.class},new JdkDbQueryHandle());
return jdkProxy;
}
}
- 使用CGLib动态代理
public class CglibDbQueryInterceptor implements MethodInterceptor{
IDBQuery real = null;
public Object intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy arg3) throws Throwable {
if(real == null)
real = new DBQuery();
return real.request();
}
//创建代理类
public IDBQuery createCglibProxy(){
Enhancer enhancer = new Enhancer();
enhancer.setCallback(new CglibDbQueryInterceptor());
enhancer.setInterfaces(new Class[]{ IDBQuery.class});
IDBQuery cglibProxy = (IDBQuery)enhancer.create();
return cglibProxy;
}
}
网友评论