java之动态代理初探

来源:互联网 发布:软件著作权独占许可 编辑:程序博客网 时间:2024/05/16 00:29
1.什么是代理我们大家都知道微商代理,简单地说就是代替厂家卖商品,厂家“委托”代理为其销售商品。关于微商代理,首先我们从他们那里买东西时通常不知道背后的厂家究竟是谁,也就是说,“委托者”对我们来说是不可见的;其次,微商代理主要以朋友圈的人为目标客户,这就相当于为厂家做了一次对客户群体的“过滤”。我们把微商代理和厂家进一步抽象,前者可抽象为代理类,后者可抽象为委托类(被代理类)。通过使用代理,通常有两个优点,并且能够分别与我们提到的微商代理的两个特点对应起来:优点一:可以隐藏委托类的实现;优点二:可以实现客户与委托类间的解耦,在不修改委托类代码的情况下能够做一些额外的处理。写个demo看看其 如何操作的。1.一个用户 登录注册接口。public interface User { void login(); void regist();}2.实现类public class UserImpl implements User { @Override public void login() { System.out.println("执行登录方法"); } @Override public void regist() { System.out.println("注册方法执行"); }}3.创建其代理对象 测试调用。public class ProxyTest { @SuppressWarnings("unused") public static void main(String[] args) {// 使用动态代理 加强方法 三个参数:依次 类加载器 接口 handler UserDao dao = (UserDao) Proxy.newProxyInstance(userDao.getClass() .getClassLoader(), userDao.getClass().getInterfaces(), myHandler);final User user = new UserImpl(); // 使用User的代理类 修改登录 注册方法。 User newProxyInstance = (User) Proxy.newProxyInstance(user.getClass() .getClassLoader(), user.getClass().getInterfaces(), new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // 1 System.out.println("登录之前执行xxxx 用户信息的校验"); // 2 Object invoke = method.invoke(user, args); // 3 System.out.println("登录成功之后 日志信息。。。。"); return invoke; } }); newProxyInstance.login(); }}一个RunAs 执行consle 控制台:一个简单的代理 对象完成。那么这个有什么作用呢? 加强方法的调用,AOP 框架原理的实现。 还有一些,在android 中实现hook 拦截机制。构造系统代理的伪类达到方法的调用目的,在android 插件化 中就强调运用这种机制。一个典型的动态代理创建对象过程可分为以下四个步骤:1、 其中最重要的是InvocationHandler 这个类。public interface InvocationHandler { public Object invoke(Object proxy, Method method, Object[] args) throws Throwable;} 这个接口类 底层的实现,反射 invoke()方法 的调用。 通过实现InvocationHandler接口创建自己的调用处理器 IvocationHandler handler = new InvocationHandlerImpl(...);2、 接下来在看, 代理对象Proxy.newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)的调用: public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException { if (h == null) { throw new NullPointerException(); } /* * Look up or generate the designated proxy class. */ Class cl = getProxyClass(loader, interfaces); /* *Invoke its constructor with the designated invocation handler. */ try { Constructor cons = cl.getConstructor(constructorParams); return (Object) cons.newInstance(new Object[] { h }); } catch (NoSuchMethodException e) { throw new InternalError(e.toString()); } catch (IllegalAccessException e) { throw new InternalError(e.toString()); } catch (InstantiationException e) { throw new InternalError(e.toString()); } catch (InvocationTargetException e) { throw new InternalError(e.toString()); } } 通过为Proxy类指定ClassLoader对象和一组interface创建动态代理类Class clazz = Proxy.getProxyClass(classLoader,new Class[]{...}); 然后,在通过反射机制获取动态代理类的构造函数,其参数类型是调用处理器接口类型Constructor constructor = clazz.getConstructor(new Class[]{InvocationHandler.class});3、通过构造函数创建代理类实例,此时需将调用处理器对象作为参数被传入Interface Proxy = (Interface)constructor.newInstance(new Object[] (handler));完成代理对象的创建。生成的ProxySubject继承Proxy类实现Subject接口,实现的Subject的方法实际调用处理器的invoke方法,而invoke方法利用反射调用的是被代理对象的的方法(Object result=method.invoke(proxied,args))