zoukankan      html  css  js  c++  java
  • 代理模式

    
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * 装饰器模式: 侧重于对目标类中核心逻辑的扩展, 依然是以目标类为中心
     * 代理模式  : 侧重于对目标类的访问限制于处理,或者对其添加一些重用性且与 核心业务逻辑无关的功能, 例如日志.
     */
    public class ProxyModel {
    
    }
    interface IDao{
        void add(Object o);
        void delete(Object o);
        void update(int id,Object o);
        Object find(int id);
    }
    class SimpleDao implements IDao{
    
        private List<Object> mDataBase = new ArrayList<>();
    
        @Override
        public void add(Object o) {
            mDataBase.add(o);
        }
    
        @Override
        public void delete(Object o) {
            mDataBase.remove(o);
        }
    
        @Override
        public void update(int id,Object o) {
            mDataBase.remove(id);
            mDataBase.add(id,o);
        }
    
        @Override
        public Object find(int id) {
            return mDataBase.get(id);
        }
    }
    class DaoProxy implements IDao{
    
        private IDao iDao;
    
        public DaoProxy() {
        }
    
        public DaoProxy(IDao iDao) {
            this.iDao = iDao;
        }
    
        private void beginTransaction(){
            System.out.println("开始操作数据库");
        }
        private void commit(){
            System.out.println("结束操作数据库");
        }
    
        @Override
        public void add(Object o) {
            this.beginTransaction();
            iDao.add(o);
            this.commit();
        }
    
        @Override
        public void delete(Object o) {
            this.beginTransaction();
            iDao.delete(o);
            this.commit();
        }
    
        @Override
        public void update(int id, Object o) {
            this.beginTransaction();
            iDao.update(id,o);
            this.commit();
        }
    
        @Override
        public Object find(int id) {
            this.beginTransaction();
            Object o = iDao.find(id);
            this.commit();
            return o;
        }
    }
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * 动态代理: 相对于静态代理, 动态代理中的代理类不需要事先与目标类相同的接口, 而且不依赖于接口的具体实现, 理论上可以代理所有类的所有方法. 但因为要考虑到涉及到的业务, 所以要求面向接口代理.
     * 实现机制: 运行时创建一个虚拟的代理类, 在代理的目标方式实际执行时, 通过java的反射技术获取到该防范对象, 并在执行前后后添加需要的操作, 这需要实现一个`InvocationHandler接口
     */
    public class ProxyModel {
        public static void main(String[] args) {
            SimpleDao simpleDao = new SimpleDao();
            IDao proxy = new DaoProxy().createProxy(simpleDao);
            proxy.add("ss");
        }
    }
    
    interface IDao {
        void add(Object o);
    
        void delete(Object o);
    
        void update(int id, Object o);
    
        Object find(int id);
    }
    class SimpleDao implements IDao{
    
        private List<Object> mDataBase = new ArrayList<>();
    
        @Override
        public void add(Object o) {
            mDataBase.add(o);
        }
    
        @Override
        public void delete(Object o) {
            mDataBase.remove(o);
        }
    
        @Override
        public void update(int id,Object o) {
            mDataBase.remove(id);
            mDataBase.add(id,o);
        }
    
        @Override
        public Object find(int id) {
            return mDataBase.get(id);
        }
    }
    
    class DaoProxy {
        /*这里需要注意, 返回值只能是一个接口, 而不能使具体的实现类. */
        public IDao createProxy(IDao target) {
            /*此方法生成的虚拟类是根据目标的Class文件拿到的父类接口生成的, 因此不能强制转换成实现类 */
            return (IDao) Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(),
                    new InvocationHandler() {
                        @Override
                        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                            beginTransaction();
                            Object invoke = method.invoke(target, args);
                            commit();
                            return invoke;
                        }
                    });
        }
    
        private void beginTransaction() {
            System.out.println("读写开始前,开启数据库!");
        }
    
        private void commit() {
            System.out.println("读写结束,关闭数据库!");
        }
    }
    
    
    /**
     * 不关心接口的实现逻辑, 只需要取到备操作类即可.
     */
    public class ProxyModel {
        public static void main(String[] args) {
            IDao proxy = new LogProxy().createProxy(SimpleDao.class);
            proxy.add("item");
            proxy.delete("asd");
            proxy.update(1,"asd");
        }
    }
    
    interface IDao {
        void add(Object o);
    
        void delete(Object o);
    
        void update(int id, Object o);
    
        Object find(int id);
    }
    class SimpleDao implements IDao{
    
    
        @Override
        public void add(Object o) {
            System.out.print("添加:  "+o.toString()+"    ");
        }
    
        @Override
        public void delete(Object o) {
            System.out.print("删除:  "+o.toString()+"    ");
        }
    
        @Override
        public void update(int id,Object o) {
            System.out.print("更新:  "+id+"    "+o.toString()+"    ");
        }
    
        @Override
        public Object find(int id) {
            System.out.print("查找:  "+id+"    ");
            return null;
        }
    }
    
    class LogProxy {
    
        public <T> T createProxy(Class<T> target) {
            return (T) Proxy.newProxyInstance(target.getClassLoader(), target.getInterfaces(),
                    (proxy, method, args) -> {
                        System.out.print("开始输出日志------->");
                        System.out.print("调用方法:" + method.getName() + makeArgsText(args));
                        method.invoke(target.newInstance(),args);
    
    
                        System.out.print("<-------日志输出结束");
                        System.out.println();
                        return null;
                    });
        }
    
        private String makeArgsText(Object[] args) {
            StringBuilder builder = new StringBuilder();
            builder.append(",   共有").append(args.length).append("个参数:  ");
            for(Object item : args) {
                builder.append(item.toString()).append(" & ");
            }
            return builder.toString();
        }
    }
    
    import org.springframework.cglib.proxy.Enhancer;
    import org.springframework.cglib.proxy.MethodInterceptor;
    import org.springframework.cglib.proxy.MethodProxy;
    import java.lang.reflect.Method;
    
    /**
     * 如果目标类没有实现接口, 那么`Spring AOP`会选择使用`CGLIB`来动态代理目标类.
     * CGLIB(Code Generation Library), 是一个代码生成的类库, 可以在运行时动态的生成某个类的子类.
     * CGLIB是通过继承的方式做的动态代理, 因此如果某个类被标记为Final,那么它是无法使用CGLIB做动态代理的.
     */
    class SimpleDao {
    
        public void add(Object o) {
            System.out.println("添加:  " + o.toString() + "    ");
        }
    
        public void delete(Object o) {
            System.out.println("删除:  " + o.toString() + "    ");
        }
    
        public void update(int id, Object o) {
            System.out.println("更新:  " + id + "    " + o.toString() + "    ");
        }
    
        public Object find(int id) {
            System.out.println("查找:  " + id + "    ");
            return null;
        }
    }
    
    class MyMethodInterceptor implements MethodInterceptor {
    
        /**
         * sub:cglib生成的代理对象
         * method:被代理对象方法
         * objects:方法入参
         * methodProxy: 代理方法
         */
        @Override
        public Object intercept(Object sub, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
            System.out.println("======插入前置通知======");
            Object object = methodProxy.invokeSuper(sub, objects);
            System.out.println("======插入后者通知======");
            return object;
        }
    }
    
    class Client {
        public static void main(String[] args) {
            // 通过CGLIB动态代理获取代理对象的过程
            Enhancer enhancer = new Enhancer();
            // 设置enhancer对象的父类
            enhancer.setSuperclass(SimpleDao.class);
            // 设置enhancer的回调对象
            enhancer.setCallback(new MyMethodInterceptor());
            // 创建代理对象
            SimpleDao proxy = (SimpleDao) enhancer.create();
            // 通过代理对象调用目标方法
            proxy.add("add");
        }
    }
    
  • 相关阅读:
    变量可变性问题
    Android 创建Listener监听器形式选择:匿名内部类?外部类?
    linux下安装zookeeper
    翻页工具类
    将哈夫曼树转化成二叉树
    Activity的启动流程分析
    题目1186:打印日期
    数据库设计--数据流图(DFD)
    c#基础之数组
    10.3.1 一个CONNECT BY的样例
  • 原文地址:https://www.cnblogs.com/A-FM/p/10085401.html
Copyright © 2011-2022 走看看