为什么叫动态代理呢?动态代理就是实现阶段不用关心代理谁,而是在运行阶段指定代理哪一个对象,相对来说自己写代理类的方式都是静态代理,现在有一个非常流行的框架Spring,当我们面试的时候一般都会问Spring有哪些特征,我们一般会说AOP、IOC,其实这里的AOP即面向横切面变成的实现原理就是动态代理。
接着上次小明找游戏代理说,看看使用动态代理如何实现小明找代练的场景:
与自己写代理类的不同之处是我们并没有写代理类并且多了一个接口InvocationHandler,这个接口的作用就是为我们在运行时产生一个指定的代理对象并且这个接口使用JDK提供的。
代码如下:
public interface IGamePlayer { // 登陆 public void login(String user, String pwd); // 打怪 public void daguai(); // 升级 public void upgrade(); }
public class Xiaoming implements IGamePlayer { private String name; public Xiaoming(String name) { this.name = name; } /** * @param user * @param pwd */ @Override public void login(String user, String pwd) { System.out.println("登陆名为:" + user + "的用户:" + this.name + "登陆成功"); } /** * */ @Override public void daguai() { System.out.println(this.name + "在打怪"); } /** * */ @Override public void upgrade() { System.out.println(this.name + "游戏升级了"); } }
public class GamePlayerHandler implements InvocationHandler { // 被代理类 private Class cls; // 被代理者实例 private Object object; public GamePlayerHandler(Object object) { this.object = object; } /** * 调用被代理的方法 * * @param proxy * @param method * @param args * @return * @throws Throwable * @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object, java.lang.reflect.Method, * java.lang.Object[]) */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // TODO Auto-generated method stub Object result = method.invoke(object, args); return result; } }
public class Client { public static void main(String[] args) { // 小明玩家 IGamePlayer player = new Xiaoming("小明"); // 定义一个handler InvocationHandler handler = new GamePlayerHandler(player); // 获得Class loader ClassLoader loader = player.getClass().getClassLoader(); // 动态产生一个代理 IGamePlayer proxy = (IGamePlayer) Proxy.newProxyInstance(loader, new Class[] { IGamePlayer.class }, handler); // 登陆 proxy.login("小明", "1111"); // 打怪 proxy.daguai(); // 升级 proxy.upgrade(); } }
还记的代理的作用吗?我们使用代理的目的主要是为了实现类的功能增强,那么动态代理如何增强呢?先看看通的动态代理类图:
public interface Subject { public void doSomething(); }
public class RealSubject implements Subject { /** * * @see com.huashao.chapter.chapter12_03.Subject#doSomething() */ @Override public void doSomething() { System.out.println("do some thing"); } }
public class MyInvocationHandler implements InvocationHandler { // 被代理类的对象 private Object target; public MyInvocationHandler(Object object) { this.target = object; } /** * @param proxy * @param method * @param args * @return * @throws Throwable * @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object, java.lang.reflect.Method, * java.lang.Object[]) */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object result = method.invoke(target, args); return result; } }
public class DynamicProxy<T> { public static <T> T newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler handler) { // 寻找JoinPoint 连接点,执行一个前置通知 if (true) { (new BeforeAdvice()).exec(); } return (T) Proxy.newProxyInstance(loader, interfaces, handler); } }
public interface IAdvice { public void exec(); }
public class BeforeAdvice implements IAdvice { /** * * @see com.huashao.chapter.chapter12_03.IAdvice#exec() */ @Override public void exec() { System.out.println("前置通知,执行"); } }
public class Client { public static void main(String[] args) { Subject subject = new RealSubject(); InvocationHandler handler = new MyInvocationHandler(subject); Subject proxy = DynamicProxy.newProxyInstance(subject.getClass().getClassLoader(), subject .getClass().getInterfaces(), handler); proxy.doSomething(); } }