代理模式(Proxy)
是通过代理对象访问目标对象,在不修改目标对象方法的基础上增强目标方法,例如日志,事务等功能。代理模式又具体分为两类,静态代理和动态代理。
一、静态代理
代理对象很明确的知道被代理对象是谁,一般在代理类中包含目标类对象属性,为了实现代理对象和被代理对象方法的一致,代理类必须和被代理类实现相同接口。代码示例:
public class DemoDAOImpl implements IDemoDAO{
@Override
public void executeInsert() {
System.out.println("[数据访问操作]:1.连接数据库");
System.out.println("[数据访问操作]:2.执行InsertSQL");
System.out.println("[数据访问操作]:3.处理结果");
}
@Override
public void executeUpdate() {
System.out.println("[数据访问操作]:1.连接数据库");
System.out.println("[数据访问操作]:2.执行UpdateSQL");
System.out.println("[数据访问操作]:3.处理结果");
}
}
public class DemoDAOProxy implements IDemoDAO{
private IDemoDAO demoDao=new DemoDAOImpl();
@Override
public void executeInsert() {
long begin=System.currentTimeMillis();
System.out.println("[增强]开始执行时间:"+new Date());
demoDao.executeInsert();
long end=System.currentTimeMillis();
System.out.println("[增强]执行结束时间:"+new Date());
System.out.println("[增强]执行总耗时:"+(end-begin));
}
@Override
public void executeUpdate() {
}
}
二、动态代理
代理对象在编译期不知道被代理对象是谁,只有等到运行期才会动态的得到被代理对象的信息,依赖于反射机制。动态代理主要分为两种,基于JDK的动态代理和cglib动态代理,两者的主要区别在于,前者基于接口实现,后者基于父类继承实现,在SpringAOP中首选第一种,当目标对象没有实现接口时,再选择后者,一般以目标对象为父类继承实现动态代理。 1.基于JDK的动态代理 一般步骤为实现反射包中的InvocationHandler接口,重写invoke方法,用于增强被调用方法,再调用Proxy类的newProxyInstance()方法产生代理对象。 代码示例:
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Date;
public class JdkProxyFactory implements InvocationHandler,ProxyFactory{
private Object targetObject;
public JdkProxyFactory(Object targetObject) {
super();
this.targetObject = targetObject;
}
public Object createProxy() {
Class targetClass=targetObject.getClass();
Object proxyObject=Proxy.newProxyInstance(targetClass.getClassLoader(),targetClass.getInterfaces(), this);
return proxyObject;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
long begin=System.currentTimeMillis();
System.out.println("[增强]开始执行时间:"+new Date());
Object returnVal=method.invoke(targetObject, args);
long end=System.currentTimeMillis();
System.out.println("[增强]执行结束时间:"+new Date());
System.out.println("[增强]执行总耗时:"+(end-begin));
return returnVal;
}
}
2.基于cglib的动态代理 一般代理工厂需要实现MethodInterceptor(Callback的子接口)接口,并重写intercept方法,用于在代理对象回调时增强目标被代理对象的目标方法,然后调用Enhancer类的create()方法产生代理对象,具体代码如下:
import java.lang.reflect.Method;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
public class CglibProxyFactory implements MethodInterceptor,ProxyFactory {
private Object target;
public CglibProxyFactory(Object target) {
super();
this.target = target;
}
public Object createProxy() {
Enhancer enhancer=new Enhancer();
enhancer.setSuperclass(target.getClass());
enhancer.setCallback(this);
Object proxy=enhancer.create();
return proxy;
}
@Override
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy arg3) throws Throwable {
System.out.println("********************************************");
Object returnval= method.invoke(target, args);
System.out.println("********************************************");
return returnval;
}
}
以上就是我对代理模式的理解,谢谢阅读,欢迎斧正。
|