• 静态代理和动态代理


    一、静态代理:代理类和目标类实现同一个接口,具备目标类的部分功能。

    静态代理类优缺点 
    优点:业务类只需要关注业务逻辑本身,保证了业务类的重用性。这是代理的共有优点。 
    缺点: 
    1)代理对象的一个接口只服务于一种类型的对象,如果要代理的方法很多,势必要为每一种方法都进行代理,静态代理在程序规模稍大时就无法胜任了。 
    2)如果接口增加一个方法,除了所有实现类需要实现这个方法外,所有代理类也需要实现此方法。增加了代码维护的复杂度。 

    1.代理接口

    public interface Base {
        //获得连接
        boolean getConnection();
        //查询数据
        ResultSet selectSQL(String sql, Object...obj);
        //增删改查
        int updateSQL(String sql,Object...obj);
        //关闭连接
        void closeConnection();
    
    }

    2.委托类

    public class BaseDao implements Base{
    
        Connection connection=null;
        PreparedStatement pre=null;
        ResultSet resultSet=null;
        //关闭连接
        public void closeConnection(){
            if(resultSet!=null) {
                try {
                    resultSet.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if(pre!=null){
                try {
                    pre.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if(connection!=null){
                try {
                    connection.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
        //连接数据库
        public boolean getConnection(){
            String jdbc = ConfigManager.getInstance().getInfo("jdbc");
            String url = ConfigManager.getInstance().getInfo("url");
            String user = ConfigManager.getInstance().getInfo("user");
            String pwd = ConfigManager.getInstance().getInfo("pwd");
            try {
                //加载驱动
                Class.forName(jdbc);
                //获取连接
                connection = DriverManager.getConnection(url, user, pwd);
            } catch (Exception e) {
                e.printStackTrace();
                return false;
            }
            return true;
        }
        //查询语句
        public ResultSet selectSQL(String sql,Object...obj){
           // String sql="select * from student where stuname=?";
            try {
                pre = connection.prepareStatement(sql);
                for(int i=0;i<obj.length;i++){
                    pre.setObject(i+1,obj[i]);
                }
                resultSet= pre.executeQuery();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            return resultSet;
        }
        //增删改查
        public int updateSQL(String sql,Object...obj){
            int num=0;
            try {
                pre=connection.prepareStatement(sql);
                for(int i=0;i<obj.length;i++){
                    pre.setObject(i+1, obj[i]);
                }
               num= pre.executeUpdate();
    
            } catch (SQLException e) {
                e.printStackTrace();
            }
            return num;
        }
    }

    3.静态代理类

    public class BaseAgent implements Base{
        Base base=new BaseDao();
    
        @Override
        public boolean getConnection() {
    
            return base.getConnection();
        }
    
        @Override
        public ResultSet selectSQL(String sql, Object... obj) {
            base.getConnection();
            ResultSet resultSet = base.selectSQL(sql, obj);
    //        base.closeConnection();
            return resultSet;
        }
    
        @Override
        public int updateSQL(String sql, Object... obj) {
            base.getConnection();
            int num=base.updateSQL(sql,obj);
            base.closeConnection();
            return num;
        }
    
        @Override
        public void closeConnection() {
            base.closeConnection();
        }
    }

    4.测试类

    public class TestCase {
        public static void main(String[] args) throws Exception{
            BaseAgent ba=new BaseAgent();
            String sql="select stuname from student where stuid=? or stuid=?;";
            ResultSet resultSet = ba.selectSQL(sql, 2,3);
            while(resultSet.next()){
                System.out.println(resultSet.getString("stuname"));
            }
            ba.closeConnection();
        }
    }

    二、动态代理 
    动态代理类的源码是在程序运行期间由JVM根据反射等机制动态的生成,所以不存在代理类的字节码文件。代理类和委托类的关系是在程序运行时确定。

    1.代理接口

    public interface DoSame {
        void doSomething();
        void say();
    }

    2.目标类(实现代理接口)

    public class DoSameImp implements DoSame {
        @Override
        public void doSomething() {
            System.out.println("必须做些什么!");
        }
    
        @Override
        public void say() {
            System.out.println("要说些什么?");
        }

    3. 实现InvocationHandler接口创建自己的调用处理器

    public class DoSameHandler implements InvocationHandler {
        private DoSame doSame;
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            System.out.println("before========");
            //利用反射机制将请求分派给委托类处理。Method的invoke返回Object对象作为方法执行结果。
            Object invoke = method.invoke(doSame, args);
            System.out.println("after=========");
            return invoke;
        }
        //构造函数
        public DoSameHandler(){}
        public DoSameHandler(DoSame doSame){
            this.doSame=doSame;
        }
    }

    4.测试类

    public class TestCase {
        public static void main(String[] args) throws Exception {
            DoSame doSame=new DoSameImp();
            // 通过 Proxy 直接创建动态代理类实例
            DoSame o =(DoSame) Proxy.newProxyInstance(doSame.getClass().getClassLoader(), new Class[]{DoSame.class},
                    new DoSameHandler(doSame));
            System.out.println("目标对象调用如下:");
            doSame.doSomething();
            System.out.println("代理对象调用如下:");
            o.doSomething();
            //打印内存中的代理类
            byte[] bytes= ProxyGenerator.generateProxyClass("$Proxy0",new Class[]{DoSame.class});
            FileOutputStream fos=new FileOutputStream("$Proxy0.class");
            fos.write(bytes);
            fos.close();
        }
    }
  • 相关阅读:
    MySQL函数大全
    Hibernate的理论知识点
    捕获异常
    重定向到其他的页面
    Jquery中val、text、html的区别
    条件注释判断浏览器<!--[if !IE]><!--[if IE]><!--[if lt IE 6]><!--[if gte IE 6]>
    inline-block元素的4px空白间距解决方案
    img标签中alt属性与title属性
    3像素文本偏移bug 解决方案
    google Ip
  • 原文地址:https://www.cnblogs.com/TFE-HardView/p/11178001.html
Copyright © 2020-2023  润新知