* 一種方式:繼承的方式.
* 能夠控制這個類的構造的時候,才可以使用繼承.
Connection是一個接口,實現類不確定(由各廠商提供),無法使用此方法
* 二種方式:裝飾者模式方式.
* 包裝對象和被包裝的對象都要實現相同的接口.
* 包裝的對象中需要獲得到被包裝對象的引用.
***** 缺點:如果接口的方法比較多,增強其中的某個方法.其他的功能的方法需要原有調用.
* 三種方式:動態代理的方式.
* 被增強的對象實現接口就可以.
一繼承:
class Man{ public void run(){ System.out.println("跑...."); } } class SuperMan extends Man{ public void run(){ // super.run(); System.out.println("飛...."); } }
二裝飾者模式(典型案例 HttpServletRequest 解決全局亂碼問題)
public class EncodingFilter implements Filter{ @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { //request.setCharacterEncoding("UTF-8"); //在傳遞request之前對request的getParameter方法進行增強 /* * 裝飾者模式(包裝) * 1、增強類與被增強的類要實現統一接口 * 2、在增強類中傳入被增強的類 * 3、需要增強的方法重寫 不需要增強的方法調用被增強對象的 */ //被增強的對象 HttpServletRequest req = (HttpServletRequest) request; //增強對象 EnhanceRequest enhanceRequest = new EnhanceRequest(req); chain.doFilter(enhanceRequest, response); } @Override public void destroy() { } @Override public void init(FilterConfig filterConfig) throws ServletException { } } class EnhanceRequest extends HttpServletRequestWrapper{ private HttpServletRequest request; public EnhanceRequest(HttpServletRequest request) { super(request); this.request = request; } //對getParaameter增強 @Override public String getParameter(String name) { String parameter = request.getParameter(name);//亂碼 try { parameter = new String(parameter.getBytes("iso8859-1"),"UTF-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } return parameter; } }
三動態代理
接口類:Waiter public interface Waiter { public void serve(); public String sayhello(); } 實現類:Waitress public class Waitress implements Waiter { @Override public void serve() { System.out.println("您要點兒什么呢?"); } @Override public String sayhello() { System.out.println("hello world"); return null; } } 代理類:ProxyDemo public class ProxyDemo { @Test public void strengthen(){ //獲得要增強實現類的對象 final Waiter waiter = new Waitress(); /* * Proxy為代理類。 * newProxyInstance為Proxy的靜態方法,此方法用於實現動態代理 * 返回值為增強類要實現的接口對象 * 此方法需要接受三個參數:類加載器、被增強類所要實現的全部接口、處理類 * */ //類加載器 ClassLoader classLoader = waiter.getClass().getClassLoader(); //被增強類所要實現的全部接口 Class<?>[] interfaces = waiter.getClass().getInterfaces(); //處理類一般是通過創建匿名內部類來實現的。 Waiter waiterProxy = (Waiter)Proxy.newProxyInstance(classLoader, interfaces, new InvocationHandler() { /* * proxy:產生的代理對象的引用 * method:當前正在調用的目標類的方法 * params:只在執行的方法中的參數。 */ //需要注意的是我們無論調用waiterProxy中的任何方法都會執行invoke。所以我們可以在invoke中做一個判斷, //從而只執行我們想要的方法。 @Override public Object invoke(Object proxy, Method method, Object[] params) throws Throwable { //根據方法名來執行我們需求中的方法。 if("serve".equals(method.getName())){ System.out.println("歡迎光臨"); //這里我們使用了method的invoke來執行waiterProxy中的方法。 Object object = method.invoke(waiter, params); System.out.println("謝謝光臨"); return object; }else{ //只執行了原來的方法,沒有進行增強。 Object object = method.invoke(waiter, params); return object; } } }); waiterProxy.serve(); //waiterProxy.sayhello(); } }