* 一种方式:继承的方式.
* 能够控制这个类的构造的时候,才可以使用继承.
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(); } }