java学习笔记—实现一个类MyInputStream(28)

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 以下通过包装实现对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++) { 
                //创建原生的连接,// com.mysql.jdbc.JDBC4Connection@8888
                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; //com.mysql.jdbc.Jdbc4Connection@1111

        // 通过构造接收MySql的connection的对象JDBC4Connection@8888
        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。

原文地址:https://www.cnblogs.com/zhenghongxin/p/4401921.html