首页

通过ProxyOutputStream代理输出流拦截输出流的close和flush方法的应用示例(非单例模式)

标签:非单例模式,ProxyOutputStream,InvocationHandler,反向映射,输出流控制,拦截     发布时间:2017-10-25   

一、前言

当我们把流交给下一个节点去,我们不能确定下一个节点会不会关掉流,而我们又想在下个节点调用完后继续使用流,这时我们需要对close或flush方法进行拦截,下面基于java.lang.reflect.InvocationHandler自定义DefaultInvocationHandler实现拦截代理功能,具体代码如下

import java.io.IOException;@b@import java.io.OutputStream;@b@import java.lang.reflect.InvocationHandler;@b@import java.lang.reflect.Method;@b@import java.lang.reflect.Proxy;@b@@b@ @b@public class ProxyOutputStream extends OutputStream {@b@@b@	private OutputStream os;@b@@b@	private ProxyOutputStream(OutputStream os) {@b@		this.os = os;@b@	}@b@	@b@	public static OutputStream getInstance(OutputStream os, boolean allowClose, boolean allowFlush){@b@		return (OutputStream) Proxy.newProxyInstance(@b@			ProxyOutputStream.class.getClassLoader(),@b@			new Class[]{ProxyOutputStream.class}, @b@			new DefaultInvocationHandler(@b@					new ProxyOutputStream(os), @b@					allowClose, @b@					allowFlush)@b@			);@b@	}@b@	@b@	@b@	protected static class DefaultInvocationHandler implements InvocationHandler {@b@		@b@		private OutputStream target;@b@		@b@		private boolean allowClose;@b@		@b@		private boolean allowFlush;@b@		@b@		public DefaultInvocationHandler(OutputStream os, boolean allowClose, boolean allowFlush){@b@			target = os;@b@			this.allowClose = allowClose;@b@			this.allowFlush = allowFlush;@b@		}@b@		@b@		public Object invoke(Object proxy, Method method, Object[] args)@b@				throws Throwable {@b@			if( !allowClose && "close".equals(method.getName()) ){@b@					return null;@b@			}@b@			if( !allowFlush && "flush".equals(method.getName()) ){@b@				return null;@b@			}@b@			return method.invoke(target, args);@b@		}@b@	}@b@	/**@b@	 * 实际close方法调用@b@	 * @throws IOException@b@	 */@b@	public void realClose() throws IOException {@b@		os.close();@b@	}@b@	/**@b@	 * 实际flush方法调用@b@	 */@b@	public void realFlush() throws IOException {@b@		os.flush();@b@	}@b@@b@	@Override@b@	public void write(int b) throws IOException {@b@		os.write(b);@b@	}@b@@b@}