代理分为静态代理和动态代理。
1、静态代理
就是创建一个代理类,把要代理的对象聚合到代理类中。实际调用者调用的是代理类的方法,代理类的方法调用的是被代理者的方法,这样在代理类的方法里面,可以做些其他的操作。
Decorator装饰模式,其实就是一种代理方式。 代理类和被代理类实现相同的接口,将接口聚合到代理类中,可以实现代理的嵌套。
2、动态代理
动态代理有两种:jdk的动态代理和cglib动态代理。
1)jdk动态代理使用的是Proxy.newProxyInstance()来创建对象。
这个方法有三个参数:
第一个参数:ClassLoader,使用被代理类的classLoader即可
第二个参数:被代理类实现的接口类的数组,动态生成的代理类就会去实现这些个接口
第三个参数:new InvocationHandler 就是回调函数。也就是被代理的方法在执行的时候最终实际被调用的方法。
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class JdkProxy {
public static void main(String[] args) {
Tank tank = new Tank();
Moveable m = (Moveable)Proxy.newProxyInstance(Tank.class.getClassLoader(), new Class[]{Moveable.class}, new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("准备");
Object invoke = method.invoke(tank, args);
System.out.println("结束");
return invoke;
}
});
m.move();
}
}
class Tank implements Moveable{
@Override
public void move() {
System.out.println("kalakalakala");
}
}
interface Moveable{
void move();
}
2)cglib动态代理是使用的Enhandcer增强类进行实现,通过指定被代理者为增强器的父类,并且指定回调函数(MethodInterceptor), 然后通过enhancer的create()方法进行创建对象。
cglib通过增强类指定父类的方式进行实现代理,所以它可以代理的不仅仅是接口,普通的类也是可以。但是因为是指定父类,所以cglib不能代理final修饰的类。
public class CglibProxy {
public static void main(String[] args) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(TankNew.class);
enhancer.setCallback(new LogInterceptor());
TankNew tankNew = (TankNew) enhancer.create();
tankNew.move();
}
}
class LogInterceptor 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;
}
}
class TankNew{
public void move() {
System.out.println("kalakalakala");
}
}