动态代理(Dynamic Proxy):
两种机制:JDK CGLIB
对比:
JDK只能代理实现了接口的类(聚合)
CGLIB针对类来实现代理,产生目标类的子类,覆盖目标类的某些方法,从而实现代理(继承)
一、JDK动态代理
1、动态代理类:
1> 它是在运行时生成的class
2> 该class需要实现一组interface
3> 使用动态代理类时,必须实现Invocationhandler接口(这里实现具体的代理业务功能)
2、动态代理实现步骤:
1> 创建一个实现接口InvocationHandler的类,它必须实现invoke方法.
2> 创建被代理的类以及接口
3> 调用Proxy的静态方法,创建一个代理类
newProxyInstance(loader,interfaces,h)
4> 通过代理调用方法
1)TimeHandler.java
package com.zy.jdkproxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class TimeHandler implements InvocationHandler {
// 构造方法,把被代理类引入
public TimeHandler(Object target) {
super();
this.target = target;
}
private Object target;
/**
* proxy 被代理对象 method 被代理对象的方法 args 方法的参数
*
* 返回值: Object 方法调用的返回值
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
Long starttime = System.currentTimeMillis();
System.out.println("汽车开始行驶...");
// 调用被代理类的方法
method.invoke(target);
Long endtime = System.currentTimeMillis();
System.out.println("汽车结束行使.." + (endtime - starttime) + "毫秒");
// move方法没有返回值则返回null
return null;
}
}
2)Test.java 测试类
package com.zy.jdkproxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import com.zy.proxy.Car;
import com.zy.proxy.Moveable;
public class Test {
/**
* JDK动态代理测试类
*/
public static void main(String[] args) {
Car car = new Car();
// 获取时间代理对象
InvocationHandler h = new TimeHandler(car);
// 获取别代理类的类加载器
Class<?> cls = car.getClass();
/**
* Proxy.newProxyInstance(loader, interfaces, h);
* loader:类加载器
* interfaces 实现接口
* h InvocationHandler
*/
//动态获取代理类
Moveable m = (Moveable) Proxy.newProxyInstance(cls.getClassLoader(), cls.getInterfaces(), h);
m.move();
}
}
二、CGLIB动态代理
实现步骤:
1> 创建被代理的类
2> 创建一个实现接口MethodInterceptor的类,它必须实现intercept方法,对代理类方法进行拦截并加入代理业务功能代码.并且创建一个根据属性产生代理类的getProxy方法.
3> 新建代理类,通过代理类调用方法
1) Train.java
package com.zy.cglibproxy;
public class Train {
public void move() {
System.out.println("火车行驶中...");
}
}
2) CglibProxy.java
package com.zy.cglibproxy;
import java.lang.reflect.Method;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
public class CglibProxy implements MethodInterceptor {
// 创建代理类的属性
private Enhancer enhance = new Enhancer();
// 产生指定类的代理类
public Object getProxy(Class clazz) {
// 设置产生子类的类(即为那个类创建代理类)
enhance.setSuperclass(clazz);
// 设置回调
enhance.setCallback(this);
// 创建对应属性的代理类并返回
return enhance.create();
}
/**
* 拦截所有目标类方法的调用 obj 目标类的实例 m 目标方法的反射对象 args 方法的参数 proxy 代理类的实例
*/
@Override
public Object intercept(Object obj, Method m, Object[] args,MethodProxy proxy) throws Throwable {
System.out.println("日志开始...");
// 代理类调用父类的方法
proxy.invokeSuper(obj, args);
System.out.println("日志结束...");
return null;
}
}
3) Test.java 测试类
package com.zy.cglibproxy;
public class Test {
/**
* @param args
*/
public static void main(String[] args) {
CglibProxy proxy = new CglibProxy();
Train t = (Train) proxy.getProxy(Train.class);
t.move();
}
}