Java动态代理分为JDK动态代理和使用CGLib的动态代理,下面针对两种动态代理给出简单实例。
一.JDK动态代理
1.创建动态代理类,继承InvocationHandler接口
package com.proxy.jdkproxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class TimerHandler implements InvocationHandler {
Object obj;
public TimerHandler(Object obj) {
this.obj = obj;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
long startTime = System.currentTimeMillis();
System.out.println("开始时间...");
method.invoke(obj);
long endTime = System.currentTimeMillis();
System.out.println("结束时间.." + (endTime - startTime) + "MS");
return null;
}
}
2.创建任务接口和被代理对象
任务接口Moveable:
package com.proxy.jdkproxy;
public interface Moveable {
public void move();
}
被代理对象Car:
package com.proxy.jdkproxy;
public class Car implements Moveable {
public void move() {
try {
System.out.println("汽车开始行驶...");
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
编写测试类测试JDK动态代理:
package com.proxy.jdkproxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
public class Test {
public static void main(String[] args) {
Car car = new Car();
InvocationHandler handler = new TimerHandler(car);
Class<?> cls = car.getClass();
Moveable m = (Moveable) Proxy.newProxyInstance(cls.getClassLoader(), cls.getInterfaces(), handler);
m.move();
}
}
二.使用CGLib的动态代理
CGLib的动态代理是基于继承的代理,针对类来实现代理,而不必像JDK动态代理一样只能代理实现接口的类。
CGLib的动态代理指定目标类产生一个子类,通过方法拦截技术拦截所有父类方法的调用。
使用CGLib需要导入相应的jar包,因为测试项目使用maven创建,所以此处在pom.xml文件中加入CGLib的dependency:
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>2.2</version>
</dependency>
1.创建动态代理类实现MethodInterceptor接口:
package com.proxy.cglibproxy;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
public class CglibProxy implements MethodInterceptor {
Enhancer enhancer = new Enhancer();
public Object getProxy(Class clazz){
enhancer.setSuperclass(clazz);
enhancer.setCallback(this);
return enhancer.create();
}
/**
*拦截所有目标类方法的调用
* @param o 目标类的实例
* @param method 目标方法的反射对象
* @param objects 方法的参数
* @param methodProxy 代理类的实例
* @return
* @throws Throwable
*/
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("日志开始...");
//代理类实例调用父类的方法
methodProxy.invokeSuper(o,objects);
System.out.println("日志结束...");
return null;
}
}
2.创建被代理对象Train:
package com.proxy.cglibproxy;
public class Train {
public void move(){
System.out.println("火车运行...");
}
}
3.创建测试类测试CGLib动态代理:
package com.proxy.cglibproxy;
public class Test {
public static void main(String[] args) {
CglibProxy proxy = new CglibProxy();
Train t = (Train) proxy.getProxy(Train.class);
t.move();
}
}
以上,是两种动态代理的简单实例。