zoukankan      html  css  js  c++  java
  • 动态代理

    1.什么是代理(中介)

    目标对象/被代理对象 ------ 房主:真正的租房的方法

    代理对象 ------- 黑中介:有租房子的方法(调用房主的租房的方法)

    执行代理对象方法的对象 ---- 租房的人

    流程:我们要租房----->中介(租房的方法)------>房主(租房的方法)

    抽象:调用对象----->代理对象------>目标对象

    2.动态代理

    动态代理:不用手动编写一个代理对象,不需要一一编写与目标对象相同的方法,这个过程,在运行时 的内存中动态生成代理对象。------字节码对象级别的代理对象

     

    动态代理的API:

    在jdk的API中存在一个Proxy中存在一个生成动态代理的的方法newProxyInstance

    static Object

    newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)

    返回值:Object就是代理对象

    参数:loader:代表与目标对象相同的类加载器-------目标对象.

    getClass().getClassLoader()

    interfaces:代表与目标对象实现的所有的接口字节码对象数组

    h:具体的代理的操作,InvocationHandler接口

    注意:JDK的Proxy方式实现的动态代理 目标对象必须有接口 没有接口不能实现jdk版动态代理

    public interface TargetInterface {
        
        public abstract void method();
        
        public abstract String method2(String str);
        
        public abstract int method3(int i);
    
    }
    public class Target implements TargetInterface {
    
        @Override
        public void method() {
            System.out.println("method");
        }
    
        @Override
        public String method2(String str) {
            
            return str;
        }
    
        @Override
        public int method3(int i) {
            
            return i;
        }    
    }
    /**
     * 动态代理
     * 获得动态的代理对象:
     * 在运行时 在内存中动态的为Target创建一个虚拟的代理对象
     * @author vanguard
     *
     */
    public class ProxyTest {
        @Test
        public void test() {
            //objProxy是代理对象  根据参数确定是谁的代理对象
            TargetInterface objProxy = (TargetInterface)Proxy.newProxyInstance(
                    Target.class.getClassLoader(),  //代表与目标对象相同的类加载器
                    new Class[]{TargetInterface.class}, //代表与目标对象实现的所有的接口字节码对象数组
                    new InvocationHandler() { //具体的代理操作
                        //invoke:代表的是执行代理对象的方法
                        @Override
                        //method:代表的是目标对象的方法字节码对象
                        //args:代表目标对象的响应的方法的参数
                        public Object invoke(Object proxy, Method method, Object[] args)
                                throws Throwable {
                            System.out.println("执行方法前");
                            //执行目标对象的方法
                            Object invoke = method.invoke(new Target(), args);
                            System.out.println("执行方法后");
                            return invoke;
                        }
                    });
            objProxy.method();
            String str = objProxy.method2("xxxx");
            System.out.println(str);
        }
    }

    动态代理方式实现全局编码问题

     1 /**
     2  * 解决全局乱码问题
     3  * 在传递request之前对reqeust的getParameter()方法进行增强
     4  * 动态代理实现对方法的增强
     5  * @author vanguard
     6  *
     7  */
     8 public class EncodingFilter02 implements Filter {
     9 
    10 
    11     @Override
    12     public void doFilter(ServletRequest request, ServletResponse response,
    13             FilterChain chain) throws IOException, ServletException {
    14         //POST方式
    15         //request.setCharacterEncoding("UTF-8");
    16         //在传递request之前对reqeust的getParameter()方法进行增强
    17         //被增强的对象
    18         final HttpServletRequest req = (HttpServletRequest) request;
    19         //动态代理创建对象
    20         HttpServletRequest enhanceRequest = (HttpServletRequest)Proxy.newProxyInstance(
    21                 req.getClass().getClassLoader(), 
    22                 req.getClass().getInterfaces(), 
    23                 new InvocationHandler() {
    24                     
    25                     @Override
    26                     public Object invoke(Object proxy, Method method, Object[] args)
    27                             throws Throwable {
    28                         //如果方法是否是getParameter,如果是,进行增强
    29                         if(method.getName().equals("getParameter")) {
    30                             String invoke = (String) method.invoke(req, args);
    31                             if(invoke != null) {
    32                                 try {
    33                                     //进行编码
    34                                     invoke = new String(invoke.getBytes("ISO-8859-1"), "UTF-8");
    35                                 } catch (UnsupportedEncodingException e) {
    36                                     
    37                                     e.printStackTrace();
    38                                 }
    39                             }
    40                             return invoke;
    41                         }
    42                         return method.invoke(req, args);
    43                     }
    44                 });
    45         //放行
    46         chain.doFilter(enhanceRequest, response);
    47     }
    48 
    49     @Override
    50     public void destroy() {
    51     }
    52     @Override
    53     public void init(FilterConfig arg0) throws ServletException {
    54     }
    55 
    56 }
  • 相关阅读:
    [原创] 上海好买基金招聘测试经理/测试主管/测试工程师/测试开发工程师(长期有效)
    [原创]表达沟通SCQA架构思维导图
    [原创]PostMan接口测试神器
    [原创]2015年测试人员薪水分布图
    [推荐]大型网站开发知识介绍
    使用C#版OpenCV进行圆心求取
    使用C#版Tesseract库
    OCR库Tesseract初探
    pip的基本使用
    IPAddress.Any 解决本地ip和服务器ip切换问题
  • 原文地址:https://www.cnblogs.com/guodong-wang/p/7440996.html
Copyright © 2011-2022 走看看