首页 > 学院 > 开发设计 > 正文

动态代理总结

2019-11-06 06:03:38
字体:
来源:转载
供稿:网友

PRoxyTest:

package app.java.proxy;    import java.lang.reflect.InvocationHandler;  import java.lang.reflect.Method;  import java.lang.reflect.Proxy;    public class ProxyTest {        public static void main(String[] args) {                    /**          * Proxy类的newProxyInstance(ClassLoader,Class[])方法:          *  * 获取对应委托类的代理对象.          *  * 参数一:指定对应委托类的类加载器. 也可以选择当前类         *  * 参数二:指定委托类的Class          *  * 参数三:InvocationHandler的实例(重写invoke)          *            *  动态代理的作用:          *   * 不需要得到对应委托类的对象.          *   * 通过代理类对象,对委托类的方法进行过滤(修改)等.          */          Star fbb = (Star)Proxy.newProxyInstance(Star.class.getClassLoader(), Fbb.class.getInterfaces(), new InvocationHandler() {              /**              * invoke(Object proxy, Method method, Object[] args)              *  * 该方法的作用:调用对应的委托类的方法.              *  * 参数一:返回的是代理类对象.              *  * 参数二:返回的是对应委托类方法的Method类型对象.              *  * 参数三:返回的是对应委托类方法接收的实参.              */              public Object invoke(Object proxy, Method method, Object[] args)                      throws Throwable {                  // 可以获取到对应委托类方法的参数.                   /*String name = (String)args[0];                 if(name.equals("zhangwuji")){                     method.invoke(new Fbb(), "zhouzhiruo");                 }*/                  // 阻止调用对应委托类的方法                  /*String methodName = method.getName();                 if(methodName.equals("movie")){                     System.out.println("范冰冰最近太累了,不能拍电影,改唱歌了!");                 }*/                  // 修改委托类方法的返回值                  String methodName = method.getName();                  if(methodName.equals("movie")){                      return "武媚娘传奇,重播了!!!";                  }                                    return null;              }          });            //      fbb.song("zhangwuji");          String value = fbb.movie();          System.out.println(value);      }        }  spring中动态代理:(具体代码在spring的AOP中)

底层:

import java.lang.reflect.InvocationHandler;  import java.lang.reflect.Method;  import java.lang.reflect.Proxy;    public class MyBeanFactory {            public static UserService createService(){          //1 目标类          final UserService userService = new UserServiceImpl();          //2切面类          final Myaspect myAspect = new MyAspect();          /* 3 代理类:将目标类(切入点)和 切面类(通知) 结合 --> 切面          *  Proxy.newProxyInstance          *      参数1:loader ,类加载器,动态代理类 运行时创建,任何类都需要类加载器将其加载到内存。          *          一般情况:当前类.class.getClassLoader();          *                  目标类实例.getClass().get...          *      参数2:Class[] interfaces 代理类需要实现的所有接口          *          方式1:目标类实例.getClass().getInterfaces()  ;注意:只能获得自己接口,不能获得父元素接口          *          方式2:new Class[]{UserService.class}             *          例如:jdbc 驱动  --> DriverManager  获得接口 Connection          *      参数3:InvocationHandler  处理类,接口,必须进行实现类,一般采用匿名内部          *          提供 invoke 方法,代理类的每一个方法执行时,都将调用一次invoke          *              参数3.1:Object proxy :代理对象          *              参数3.2:Method method : 代理对象当前执行的方法的描述对象(反射)          *                  执行方法名:method.getName()          *                  执行方法:method.invoke(对象,实际参数)          *              参数3.3:Object[] args :方法实际参数          *           */          UserService proxService = (UserService)Proxy.newProxyInstance(                                  MyBeanFactory.class.getClassLoader(),                                   userService.getClass().getInterfaces(),                                   new InvocationHandler() {                                                                            @Override                                      public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {                                                                                    //前执行                                          myAspect.before();                                                                                    //执行目标类的方法                                          Object obj = method.invoke(userService, args);                                                                                    //后执行                                          myAspect.after();                                                                                    return obj;                                      }                                  });                    return proxService;      }    }  


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表