Java的动态代理分为两种:
1、基于原生Java API实现,依赖于反射机制;
要点:
A、被代理类必须实现接口
B、代理处理类要实现接口:java.lang.reflect.InvocationHandler,实现invoke方法,通过反射方式完成逻辑调用,同时可以分装入前置、后置的代理逻辑;
C、通过Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), this)获取代理对象;
2、cglib提供的基于修改字节码的方式实现,底层依赖于asm字节码处理包,基本逻辑是:基于现有类的class,生成其子类,然后再针对子类方法做代理调用;
要点:
A、被代理类可以不用实现接口;
B、依赖于cglib包;
3、代理处理类要实现接口:net.sf.cglib.proxy.MethodInterceptor,实现intercept方法,通过反射完成逻辑调用,同样可以增加自己的增强代码;
3、通过net.sf.cglib.proxy.Enhancer对象来构造新代理对象,其中,需要指定父类、回调类;
应用场景:日志、事务等无侵入式的AOP代理切入;
示例代码:
1、要被代理的业务逻辑类
/**
* 业务逻辑接口
*/
public interface IBusinessService {
void business();
}
/**
* 业务逻辑类
*/
public class BusinessServiceImpl implements IBusinessService {
public void business() {
System.out.println("我是业务逻辑");
}
}
2、JDK动态代理类
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* 基于JDK的动态代理
*/
public class JdkProxy implements InvocationHandler {
private Object targetObject;
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("JdkProxy代理开始");
Object resultObj = method.invoke(targetObject, args);
System.out.println("JdkProxy代理结束");
return resultObj;
}
public Object getObject(Object obj) {
this.targetObject = obj;
return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), this);
}
}
3、CGLIB动态代理类
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
/**
* 基于cglib的动态代理
*/
public class CglibProxy implements MethodInterceptor {
private Object targetObject;
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
System.out.println("CglibProxy代理开始");
Object resultObj = method.invoke(targetObject, args);
System.out.println("CglibProxy代理结束");
return resultObj;
}
public Object getObject(Object obj) {
this.targetObject = obj;
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(obj.getClass());
enhancer.setCallback(this);
return enhancer.create();
}
}
4、测试类
import upup.snail.dynamicproxy.cglib.CglibProxy;
import upup.snail.dynamicproxy.jdk.JdkProxy;
/**
*
*/
public class DynamicProxyTest {
public void testCglibProxy() {
CglibProxy cglibProxy = new CglibProxy();
IBusinessService businessService = (IBusinessService) cglibProxy.getObject(new BusinessServiceImpl());
businessService.business();
}
public void testJdkProxy() {
JdkProxy jdkProxy = new JdkProxy();
IBusinessService businessService = (IBusinessService) jdkProxy.getObject(new BusinessServiceImpl());
businessService.business();
}
public static void main(String[] args) {
DynamicProxyTest dpt = new DynamicProxyTest();
dpt.testJdkProxy();
System.out.println();
dpt.testCglibProxy();
}
}
输出结果: