最近学习spring aop时发现其大量使用了代理模式,于是就想着研究一下代理模式的实现原理。
代理模式
代理模式是常用的java设计模式,如上图所示,代理类和实现类实现了同一个接口,而代理类中则具有现有对象,通过代理类去操作现有对象,那么我们就可以在代理类中增加很多操作,包括前置增强、后置增强、环绕增强、异常增强等,这也就能解决我们实际当中遇到的一些问题,例如延迟对象的创建、控制对象的访问等。
静态代理
静态代理是由程序员创建或特定工具自动生成源代码,再对其编译。最大的特点就是在程序运行时代理类的.class文件就已经存在了,但是这有一个很大的缺陷即每一个代理类只能为一个接口服务。静态代理的实现如下
首先定义一个接口
//产品接口
public interface ProductBiz {
public void addProduct();
}
接着定义一个接口实现类
//产品实现类
public class ProductImpl implements ProductBiz {
@Override
public void addProduct() {
System.out.println("增加产品");
}
}
再定义一个接口代理类:
//产品实现代理类
public class ProductImplProxy implements ProductBiz {
//在代理类中必须 有一个真实对象的引用
private ProductBiz productBiz;
public ProductImplProxy(ProductBiz productBiz){
this.productBiz=productBiz;
}
@Override
public void addProduct() {
before();
productBiz.addProduct();
after();
}
private void before(){
System.out.println("********************");
System.out.println("前置增强");
System.out.println("*********************");
}
private void after(){
System.out.println("********************");
System.out.println("后置增强");
System.out.println("*********************");
}
}
测试类
public class Test {
public static void main(String[] args) {
ProductBiz pb=new ProductImplProxy(new ProductImpl());
pb.addProduct();
}
}
测试结果
动态代理
动态代理在程序运行时,利用反射机制动态创建,有jdk动态代理和cglib动态代理两种:
jdk动态代理
jdk动态代理是依靠接口实现的,没有实现接口的类是不能使用jdk动态代理的。
JDK动态代理中包含一个类和一个接口:
InvocationHandler接口:
public interface InvocationHandler {
/*Object proxy:指被代理的对象
Method method:要调用的方法
Object[] args:方法调用时所需要的参数
*/
public Object invoke(Object proxy,Method method,Object[] args) throws Throwable;
}
首先定义接口
//产品接口
public interface ProductBiz {
public void addProduct();
}
//产品实现类
public class ProductBizImpl implements ProductBiz {
@Override
public void addProduct() {
System.out.println("增加产品");
}
}
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
//产品实现代理类
public class ProductImplProxy implements InvocationHandler {
// 在代理类中必须 有一个真实对象的引用
private Object targetObject;
public Object newInstance(Object targetObject) {
this.targetObject = targetObject;
/*
* ClassLoader loader:类加载器 Class<?>[] interfaces:得到全部的接口
* InvocationHandler h:得到InvocationHandler接口的子类实例
*/
return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),
targetObject.getClass().getInterfaces(), this);
}
private void before() {
System.out.println("********************");
System.out.println("前置增强");
System.out.println("*********************");
}
private void after() {
System.out.println("********************");
System.out.println("后置增强");
System.out.println("*********************");
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
before();
Object returnValue = method.invoke(targetObject, args);
after();
return returnValue;
}
}
public class Test {
public static void main(String[] args) {
ProductImplProxy pip=new ProductImplProxy();
ProductBiz pbproxy=(ProductBiz) pip.newInstance(new ProductBizImpl());
pbproxy.addProduct();
}
}
测试结果
cglib动态代理
cglib弥补了jdk代理的不足,是针对类来实现代理的,即使没有实现接口的类,也能生成代理,他的原理是对指定的目标类生成一个子类,并覆盖其中方法实现增强,但因为采用的是继承,所以不能对final修饰的类进行代理。
cglib包下载地址:http://pan.baidu.com/s/1mglEbZM 密码:0rno
//产品接口
public interface ProductBiz {
public void addProduct();
}
//产品实现类,其实并没有实现接口
public class ProductBizImpl {
public void addProduct() {
System.out.println("增加产品");
}
}
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
//产品实现代理类
//方法拦截器
public class ProductImplProxy implements MethodInterceptor {
// 在代理类中必须 有一个真实对象的引用
private Object targetObject;
public Object newInstance(Object targetObject) {
this.targetObject = targetObject;
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(this.targetObject.getClass());
// 回调方法
enhancer.setCallback(this);
// 创建代理对象
return enhancer.create();
}
private void before() {
System.out.println("********************");
System.out.println("前置增强");
System.out.println("*********************");
}
private void after() {
System.out.println("********************");
System.out.println("后置增强");
System.out.println("*********************");
}
@Override
public Object intercept(Object obj, Method arg1, Object[] args,
MethodProxy proxy) throws Throwable {
before();
Object returnValue = proxy.invokeSuper(obj, args);
after();
return returnValue;
}
}
public class Test {
public static void main(String[] args) {
ProductImplProxy pip=new ProductImplProxy();
ProductBizImpl pbi= (ProductBizImpl) pip.newInstance(new ProductBizImpl());
pbi.addProduct();
}
}
测试结果