Java的动态代理分为两种,JDK动态代理及cglib动态代理。动态代理与静态代理最大的区别在于动态代理可以不用将代理类与被代理类事先绑定,在程序执行前,代理类并不知道被代理类的信息
JDK动态代理
构造一般代理类实现InvocationHandler接口,并重写invoke方法。而后在实际代理对象时通过一般代理类的构造方法将被代理对象传入代理类中
public class TestProxy implements InvocationHandler {
Object object;
public TestProxy(Object object) {
this.object = object;
}
......
而后调用Proxy类的NewProxyInstance()方法,将被代理类的类加载器,被代理类实现的接口及继承的类以及创建的一般代理类依次传入其中。可以看到在NewProxyInstance()方法中
final Constructor<?> cons = cl.getConstructor(constructorParams);
final InvocationHandler ih = h;
if (!Modifier.isPublic(cl.getModifiers())) {
AccessController.doPrivileged(new PrivilegedAction<Void>() {
public Void run() {
cons.setAccessible(true);
return null;
}
});
}
return cons.newInstance(new Object[]{h});
中存在这样一段代码,大意为判断构造函数的修饰符是否是public的,若不是则调用setAccessible方法强制调用(在反射中调取非公共方法或属性时用的)。然后通过newInstance()方法创建代理对象,此时就创建了对应被代理类的代理对象了。
在调用代理对象的具体方法时实际调用的是代理类的invoke()方法
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("***************需要增强的方法***************");
return method.invoke(object, args);
}
这里就可以对原本被代理类的方法进行加强