1 实现一个类MyInputStream读取文件,且不能抛出异常
public class TestDemo { public static void main(String[] args) throws Exception { InputStream in = new MyInputStream("d:/a/a.txt"); byte[] b = new byte[1024]; int len = 0; while((len=in.read(b))!=-1){ String s = new String(b,0,len); System.err.print(s); } in.close(); } }
class MyInputStream extends InputStream { //成为inputstream的子类,即is a. private InputStream in; public MyInputStream(String fileName) { try { in = new FileInputStream(fileName); } catch (FileNotFoundException e) { e.printStackTrace(); } } public int read(byte[] b){ int len=-1; try { len = in .read(b); } catch (IOException e) { e.printStackTrace(); } return len; } public void close(){ try { in.close(); } catch (IOException e) { e.printStackTrace(); } } @Override public int read() throws IOException { return 0; } }
2 以下通过包装[W1] 实现对close方法的修改,以回收连接
1:实现Connection接口,拥有一个Connection的成员。
2:修改close方法。
3:其他的方法都调用成员变量的connection。
public class MyDataSource implements DataSource { private LinkedList<Connection> pool = new LinkedList<Connection>(); public MyDataSource() { try { Class.forName("com.mysql.jdbc.Driver"); String url = "jdbc:mysql:///db909?characterEncoding=UTf8"; for (int i = 0; i < 3; i++) { //创建原生的连接,// [email protected] Connection con = DriverManager.getConnection(url, "root", "1234"); //声明包装类 MyConn conn = new MyConn(con); pool.add(conn);//将包装类添加到池中去 } } catch (Exception e) { e.printStackTrace(); } } //此方法来自于datasource,用于返回一个连接 public Connection getConnection() throws SQLException { synchronized (pool) { if (pool.size() == 0) { try { pool.wait(); } catch (InterruptedException e) { e.printStackTrace(); } return getConnection(); } Connection con = pool.removeFirst(); System.err.println("siize:" + pool.size()); return con; } }
以下包装connection
class MyConn implements Connection { // 声明被包装类的成员 private Connection conn; //[email protected] // 通过构造接收MySql的connection的对象[email protected] public MyConn(Connection con) { this.conn = con; } //关闭连接 public void close() throws SQLException { synchronized (pool) { //有人调用了关闭方法,不能关 System.err.println("有人还连接了。。。。"+this); pool.add(this); pool.notify(); } } }
3、用包装处理get方式的乱码
package cn.itcast.utils; import java.io.IOException; import java.lang.reflect.Method; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; import javax.servlet.http.HttpServletResponse; public class BaseServlet extends HttpServlet { @Override public void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { req.setCharacterEncoding("UTF-8"); String methodName = req.getParameter("cmd"); try{ Method mm = this.getClass().getMethod(methodName,HttpServletRequest.class,HttpServletResponse.class); //声明包装类 MyRequest mr = new MyRequest(req); mm.invoke(this,mr,resp); }catch(Exception e){ e.printStackTrace(); } } } //包装request class MyRequest extends HttpServletRequestWrapper{ private HttpServletRequest req; public MyRequest(HttpServletRequest request) { super(request); this.req=request; } //修改getparameter方法 @Override public String getParameter(String name) { String value = req.getParameter(name); if(req.getMethod().equals("GET")){ System.err.println("转码"); try{ value = new String(value.getBytes("ISO-8859-1"),"UTF-8"); }catch(Exception e){ } } return value; } }
总结:
1:代理或是包装都是对某个类的方法进行增强。
代理:必须要根据给定的接口,在内存中创建这个接口的子类。$Proxy0。
包装:不需要接口,但声明声明一个类,变成被包装类的子类,同时拥有一个被包装类的成员。
2:代理基本代码:
Object proxyedObj =
Proxy.newProxyInstance(ClassLoader,
New class[]{被代理的类的接口数组.class},
New InvocationHandler(){//执行句柄
Public Object invode(Object 代理,Method 方法反射,object[] args){
Reutrn method.invode(被代理类,args);
}
}
3:包装:
如果一个类是某个类的包装类,则:
A extends B{
Privet B b;
}
4:什么情况下,使用包装,什么情况下使用代理
如果官方(SUN)提供了包装类适配器,则应该优先使用包装。如HttpServletRequest,它的包装类就是HtpServletRequestWraper.
如果官方没有提供包装类的适配器,则可以使用动态代理。如Connection。
时间: 2024-10-09 08:40:08