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

    动态代理,

             1)代理对象,不需要实现接口;

             2)代理对象的生成,是利用JDKAPI, 动态的在内存中构建代理对象(需要我们指定创建 代理对象/目标对象 实现的接口的类型;);

             3)  动态代理, JDK代理, 接口代理;

    JDK中生成代理对象的API:

    |-- Proxy
    
             static Object newProxyInstance(
    
                        ClassLoader loader,       指定当前目标对象使用类加载器
    
                       Class<?>[] interfaces,     目标对象实现的接口的类型
    
                       InvocationHandler h       事件处理器
    
    ) 

    思考:

             有一个目标对象,想要功能扩展,但目标对象没有实现接口,怎样功能扩展?

             Class  UserDao{}

             // 子类的方式

             Class subclass  extends  UserDao{}                                    

             以子类的方式实现(cglib代理)


    package loaderman.b_dynamic;
    
    // 接口
    public interface IUserDao {
    
        void save();
        
    }
    package loaderman.b_dynamic;
    
    /**
     * 目标对象
     *
     */
    public class UserDao implements IUserDao{
    
        @Override
        public void save() {
            System.out.println("-----已经保存数据!!!------");
        }
    
    }
    package loaderman.b_dynamic;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    /**
     * 给所有的dao创建代理对象【动态代理】
     *
     * 代理对象,不需要实现接口
     *
     */
    public class ProxyFactory {
    
        // 维护一个目标对象
        private Object target;
        public ProxyFactory(Object target){
            this.target = target;
        }
    
        // 给目标对象,生成代理对象
        public Object getProxyInstance() {
            return Proxy.newProxyInstance(
                    target.getClass().getClassLoader(),
                    target.getClass().getInterfaces(),
                    new InvocationHandler() {
                        @Override
                        public Object invoke(Object proxy, Method method, Object[] args)
                                throws Throwable {
                            System.out.println("开启事务");
    
                            // 执行目标对象方法
                            Object returnValue = method.invoke(target, args);
    
                            System.out.println("提交事务");
                            return returnValue;
                        }
                    });
        }
    }
    package loaderman.b_dynamic;
    
    public class App {
    
        public static void main(String[] args) {
            // 目标对象
            IUserDao target = new UserDao();
            // 【原始的类型 class cn.loaderman.b_dynamic.UserDao】
            System.out.println(target.getClass());
    
            // 给目标对象,创建代理对象
            IUserDao proxy = (IUserDao) new ProxyFactory(target).getProxyInstance();
            // class $Proxy0   内存中动态生成的代理对象
            System.out.println(proxy.getClass());
    
            // 执行方法   【代理对象】
            proxy.save();
        }
    }
  • 相关阅读:
    [AGC030F] Permutation and Minimum
    nginx
    Flex建立AS项目时,如何设定发布的舞台大小
    让Flex 支持VSS
    Flex编程实用技巧
    Flash/Flex学习笔记(57):实用技巧
    sql 2000 "无法执行查询,因为一些文件缺少或未注册"的解决办法
    Flash/Flex学习笔记(56):矩阵变换
    什么是反向代理,如何利用反向代理提高网站性能
    AS3及Flex的百条常用知识
  • 原文地址:https://www.cnblogs.com/loaderman/p/10042724.html
Copyright © 2011-2022 走看看