一、什么是动态代理
动态,顾名思义就是动态去给某个接口类去代理,它不需要像静态代理一样,每个接口都要实现一个代理,如果项目做大之后,静态代理类的数量和维护的工作将是不能想象的
二、动态代理的实现方式
动态代理是通过Java反射的方式来实现的,实现InvocationHandler接口并通过Proxy类来动态的生成代理类
既然知道了需要实现接口InvocationHandler,我们可以先来看一下InvocationHandler源码
InvocationHandler is the interface implemented by the invocation handler of a proxy instance
源码第一行就说了,InvocationHandler是一个接口,它是被代理实例调用处理类实现的接口
这个接口类里面只有一个invoke方法,我们只需要实现InvocationHandler接口并重写invoke方法就可以了
总结一句话就是通过set方法注入接口实现类,然后通过Proxy.newProxyInstance动态生成代理类
重写了invoke方法之后就会被代理
public class dynamicProxyInvocationHandler implements InvocationHandler {
private Object object;
public void setObject(Object object) {
this.object = object;
}
public Object getProxy() {
return Proxy.newProxyInstance(this.getClass().getClassLoader(), object.getClass().getInterfaces(), this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result = method.invoke(object, args);
return result;
}
}
写一个测试类
dynamicProxyInvocationHandler handler = new dynamicProxyInvocationHandler();
Man man = new Man();
handler.setObject(man);
Human human = (Human) handler.getProxy();
human.work();
Human是接口类,分别由Man和Woman来继承实现,new了一个dynamicProxyInvocationHandler之后,下面就要告诉代理,哪一个实现类要被托管,通过handler.setObject告诉代理,Human的Man实现类要被托管了,可以动态生成代理实例了,然后下面的handler.getProxy就会来动态生成,由于Man和Woman是实现Human的,所以动态生成的代理都可以用Human来接,这样通过调用父类方法就会被代理到哪个字类来执行
三、动态代理的应用场景
通过上面的例子应该可以看到动态代理的优点,就是不需要每个接口都生成一个代理
实际应用场景:
有一个接口,可以被一个或者多个业务来实现,这种情况可以用动态代理来实现,当请求过来的时候,只需要告诉代理是哪一个子类被托管了,这时候调用接口类的方法就会被代理到具体的实现类的业务上