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