动态代理

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 }

 

posted @ 2017-08-27 17:52  Vanguard  阅读(206)  评论(0编辑  收藏  举报