1.什么是代理(中介)
目标对象/被代理对象 ------ 房主:真正的租房的方法
代理对象 ------- 黑中介:有租房子的方法(调用房主的租房的方法)
执行代理对象方法的对象 ---- 租房的人
流程:我们要租房----->中介(租房的方法)------>房主(租房的方法)
抽象:调用对象----->代理对象------>目标对象
2.动态代理
动态代理:不用手动编写一个代理对象,不需要一一编写与目标对象相同的方法,这个过程,在运行时 的内存中动态生成代理对象。------字节码对象级别的代理对象
动态代理的API:
在jdk的API中存在一个Proxy中存在一个生成动态代理的的方法newProxyInstance
|
newProxyInstance |
返回值: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 }