我们首先编写一个接口IUser
1 2 3 4
| public interface IUser { void show(); void update(); }
|
再写一个类来实现这个接口
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| public class UserImpl implements IUser { public UserImpl(){ } @Override public void show(){ System.out.println("show~"); } @Override public void update(){ System.out.println("update~"); } }
|
我们再编写一个动态代理类UserInvocationHandler,并覆写它的invoke方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; public class UserInvocationHandler implements InvocationHandler { IUser user; public UserInvocationHandler(){ } public UserInvocationHandler(IUser user){this.user = user;} @Override public Object invoke(Object proxy, Method method , Object[] args) throws Throwable{ System.out.println("调用了"+method.getName()); method.invoke(user,args); return null; } }
|
为了方便对比,我们再编写一个静态代理UserProxy
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| public class UserProxy implements IUser{ IUser user; public UserProxy(){ } public UserProxy(IUser user){ this.user = user;} @Override public void show(){ user.show(); System.out.println("SHOW_IN_PROXY"); } @Override public void update(){ user.update(); System.out.println("UPDATE_IN_PROXY"); } }
|
我们首先使用静态代理来调用静态代理中的方法
1 2 3 4 5 6 7 8 9 10
| public class ProxyTest { public static void main(String[] args){ IUser user = new UserImpl(); user.show(); IUser userProxy = new UserProxy(user); userProxy.show();
} }
|
如果对这里为什么有两个show有疑问,请好好看代码
那么如果我们想要向接口中增加方法,我们不仅需要增加接口中,更需要在接口的实现类中覆写,那么如果我们用动态代理类,只需要去更新接口就可以了,这样在后期维护的时候会省很多事
我们尝试用如下的代码来测试动态代理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| import java.lang.reflect.InvocationHandler; import java.lang.reflect.Proxy; public class ProxyTest { public static void main(String[] args){ IUser user = new UserImpl();
InvocationHandler userinvocationhandler = new UserInvocationHandler(user); IUser userproxy = (IUser) Proxy.newProxyInstance(user.getClass().getClassLoader(),user.getClass().getInterfaces(),userinvocationhandler); userproxy.update(); } }
|
根据输出结果我们可以轻易的发现动态代理对象每执行一个方法的时候都被转发到InvocationHandler的接口类的invoke方法来调用