1. 程式人生 > >動態代理——方法增強

動態代理——方法增強

一、方法增強三種方式

		** 第一種 繼承:要知道父類
		** 第二種 裝飾者模式:
			*** 兩個類實現相同的介面,得到另一類的引用
			*** 缺點:需要把接口裡面的所有的方法都實現

		** 第三種 動態代理
			*** 比如移動總部,和各地的代理商例子
			*** 通過類 Proxy裡面方法是 
			*** newProxyInstance(TestProxy02.class.getClassLoader(), interfaces, new MyInvocationHand())可以建立介面的代理的實現類。
			//三個引數:
			/*
			 * 第一個引數:類載入器
			 * 第二個引數:生成實現類的介面
			 * 第三個引數:增強接口裡面的方法,
			 * 實現邏輯寫在裡面 使用接口裡面的方法 invoke(Object proxy, Method method, Object[] args) 
			 * */

 二、Demo.java

package com.ayit.dynamicproxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * 子類繼承父類實現方法的增強
 * 
 * 介面實現類實現方法的增強,用增強類構造傳遞實現類的引用——裝飾者模式
 *
 * 介面動態代理,獲取同級實現類,使用類Proxy實現Perso介面的方法的增強,invoke指定方法增強通過引數mothod類實現——動態代理
 * @author XiaYuJia
 *
 */
public class DynamicProxy {
	public static void main(String[] args) {
		Class[] interfaces = {Person.class};
		Person per = (Person) Proxy.newProxyInstance(DynamicProxy.class.getClassLoader(),interfaces, new MyInvocationHandler());
		per.eat();
	}
}

class MyInvocationHandler implements InvocationHandler{

	@Override
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		System.out.println("200-----------------");
		return null;
	}
	
}

interface Person{
	public void eat();
}

class Lucy implements Person{
	@Override
	public void eat() {
		System.out.println("1000----------------");
	}
}

三、HttpServletRequest通用編碼處理getParameter方法增強

package com.ayit.dynamicproxy;

import java.io.IOException;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;

/**
 * request裡面方法有很多 -首先進行方法判斷,是否為getParameter -判斷提交方式。進行相應處理
 * 
 * @author XiaYuJia
 * 
 */
@WebFilter(urlPatterns = "/*")
public class MyHttpServletRequest implements Filter {
	@SuppressWarnings("all")
	@Override
	public void doFilter(ServletRequest req, ServletResponse resp,
			FilterChain chain) throws IOException, ServletException {
		
		//強制型別轉換,匿名內部類使用需要final修飾
		final HttpServletRequest request = (HttpServletRequest) req;
		
		//動態代理實現介面方法增強
		Class[] interfaces = { HttpServletRequest.class };
		//proxy三個引數:類載入器,介面類,呼叫處理內部類
		HttpServletRequest myreq = (HttpServletRequest) Proxy.newProxyInstance(
				MyHttpServletRequest.class.getClassLoader(), interfaces,
				new InvocationHandler() {
					
					//方法實現
					@Override
					public Object invoke(Object proxy, Method method,
							Object[] args) throws Throwable {
						// 判斷方法名為getParameter
						if ("getParameter".equalsIgnoreCase(method.getName())) {
							// 獲取提交的方式Post,Get
							String mtd = request.getMethod();
							if ("GET".equalsIgnoreCase(mtd)) {
								String s = (String) method
										.invoke(request, args);
								s = new String(s.getBytes("ISO-8859-1"),
										"UTF-8");
								return s;
							} else if ("POST".equalsIgnoreCase(mtd)) {
								request.setCharacterEncoding("UTF-8");
							}
						}
						return method.invoke(request, args);
					}
				});
		chain.doFilter(myreq, resp);
	}

	@Override
	public void init(FilterConfig arg0) throws ServletException {
	}

	@Override
	public void destroy() {
	}

}