java中方法增強的三種方式


  * 一種方式:繼承的方式.

        * 能夠控制這個類的構造的時候,才可以使用繼承.

    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();  
    }  
}  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM