Java动态代理
代理的作用是为了实现某业务时,增强业务的能力,例如记录业务操作,记录业务时间,为业务的异常提供回滚等,通常由JDK代理和CGLIB代理两种模式,JDK是通过实现的同一个接口来实现代理,CGLIB是通过继承目标类,来增强
JDK代理代码实现
interface MyInterface{
// 接口方法
public void myMethod();
}
class MyInterfaceImpl implements MyInterface{
// 子类重写
@Override
public void myMethod() {
System.out.println("实现类方法调用");
}
}
public static void main(String[] args) {
// 目标对象
MyInterfaceImpl myInterfaceImpl = new MyInterfaceImpl();
// 代理对象
MyInterface myInterface = (MyInterface)Proxy.newProxyInstance(myInterfaceImpl.getClass().getClassLoader(), myInterfaceImpl.getClass().getInterfaces(), (proxy, method, args1) -> {
System.out.println("前置增强");
Object invoke = method.invoke(myInterfaceImpl);
System.out.println("后置增强");
return invoke;
});
myInterface.myMethod();
}
JDK代理原理分析
JDK代理:使用Java反射包中的类和接口来实现的动态代理功能
使用的技术 java.lang.reflex反射包:
- import java.lang.reflect.InvocationHandler;
- import java.lang.reflect.Method;
- import java.lang.reflect.Proxy;
三个反射工具的使用
1.Method可以代表某个方法,调用invoke(谁想调用该方法,方法的参数)时,就可以执行该对象的该方法
2.InvocationHandler接口中需要实现invoke方法
public Object invoke(Object proxy, Method method, Object[] args)
- proxy:JDK生成的proxy对象
- method:调用代理类时执行的目标方法,JDK提供
- args:方法需要的参数
3.Proxy用来生成代理对象,使用Proxy.newProxyInstance(类构造器,接口数组,InvocationHandler实现类),生成代理对象后,直接强转成需要的实现类,就可以调用接口方法实现了
JDK代理生成的代理对象是在内存中生成的,该代理对象也是接口的实现类
JDK在内存中生成的动态类的大致结构
public final class $Proxy0 extends Proxy implements MyInterface {
/**
* 每个接口方法都会被生成一个Method类
*/
private static Method m;
public $Proxy0(InvocationHandler h) {
super(h);
}
static {
// 直接将方法需要的方法赋值好
m = Class.forName("接口全类名").getMethod("方法名");
}
/**
* 方法实现实际上就是调用InvocationHandler的invoke方法,Method参数就是在该类中获得的
*/
@Override
public void myMethod() {
this.h.invoke(this,m,null);
}
}
CGLIB动态代理代码实现
全称 Code Generation Library,代码生成器,可以通过继承代理目标来实现动态代理,而不需要实现接口,是对JDK代理的补充(JDK只能代理接口实现类)
// 方法拦截器,设置增强逻辑
class MyMethodInterception implements MethodInterceptor{
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("前置增强");
Object o1 = methodProxy.invokeSuper(o, objects);
System.out.println("后置增强");
return o1;
}
}
public static void main(String[] args) {
Enhancer enhancer = new Enhancer();
// 设置对应的父类
enhancer.setSuperclass(MyInterfaceImpl.class);
// 设置回调对象
enhancer.setCallback(new MyMethodInterception());
// 创建
MyInterface myinterface = (MyInterface)enhancer.create();
// 方法调用
myinterface.myMethod();
}
Java动态代理总结
至此两种代理方法的实现方法和原理就分析完成了,接下来就看一下Spring的AOP是如何实现的