动态代理是实现对不同类,不同方法的代理。动态代理有多种实现方式,
JDK的动态代理 和cglib的动态代理。
JDK动态代理:1)只能代理实现了某个接口的类。cglib动态代理:1)针对类来实现代理2)对指定目标类产生一个子类,通过方法拦截
技术拦截所有父类方法的调用,不能对final修饰的类进行代理3)需要引入一个jar包cglib-nodep-2.2.jar。
1.JDK代理机制:
在代理类和被代理类之间加入实现InvocationHandler接口的一个类ProxyHandler,此类有事务处理器的功能。
1)java动态代理类 在java.lang.reflect包下
a)Interface
InvocationHandler:
该接口中只定义了一个方法
public object invoke(Object obj,Method method,Object[] args):实际使用中 第一个参数
obj
一般指代理类,
method指被代理的方法 ,args是该方法的参数数组,这个抽象方法在代理类中动态实现
b)
Proxy:该类为动态代理类
static Object new
ProxyInstance
(ClassLoader loader,Class[] interface,
InvocationHandler h
):返回代理类的一个实例,返回后的代理类可以当做被代理类来用,可以调用被代理类在接口中声明过的方法
所谓的Dynamic
Proxy 是这样一个class:是在运行时生成的class,该class需要实现一组
Interface ,使用动态代理类时,必须实现
InvocationHandler接口,具体业务是在handler中进行实现的
2) 实现动态代理的步骤:
a)创建一个实现
InvocationHandler接口的类,必须实现invoke方法
b)创建被代理的类及接口
c)调用
Proxy的静态方法
static Object new
ProxyInstance
(ClassLoader loader,Class[] interface,
InvocationHandler h
)来动态创建代理类
d)通过代理调用方法
下面是一个简单的代码例子:
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) + "毫秒!");
return null;
}
}
public interface Moveable {
void move();
}
import java.util.Random;
public class Car implements Moveable {
@Override
public void move() {
//实现开车
try {
Thread.sleep(new Random().nextInt(1000));
System.out.println("汽车行驶中....");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import com.proxy.Car;
import com.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();
/**
* loader 被代理 类加载器
* interfaces 实现接口
* h InvocationHandler
*/
Moveable m = (Moveable)Proxy.newProxyInstance(cls.getClassLoader(),
cls.getInterfaces(), h); //返回的是代理对象 m就是时间的动态代理
m.move();
}
}
2
cglib动态代理
1)针对类来实现代理
2)对指定目标类产生一个子类,通过方法拦截技术拦截所有父类方法的调用,不能对final修饰的类进行代理
3)需要引入一个jar包cglib-nodep-2.2.jar
事例代码:
public class Train {
public void move(){
System.out.println("火车行驶中...");
}
}
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 enhancer = new Enhancer();
//得到代理类
public Object getProxy(Class clazz){
//设置创建子类的类
enhancer.setSuperclass(clazz);
enhancer.setCallback(this);
return enhancer.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;
}
}
public class Test{
/**
* @param args
*/
public static void main(String[] args) {
CglibProxy proxy = new CglibProxy();
Train t = (Train)proxy.getProxy(Train.class);//返回代理类的对象
t.move();
}
}