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

    一、代理模式_动态代理

      静态代理和动态代理要代理的角色都是一样的,这个代理角色前面静态代理中已经提到,此处不做过多解释。

    二、动态代理示例

      2.1抽象角色  

    package edu.aeon.model.dynamicproxy_v1;
    
    /**
     * [说明]:抽象角色
     * 
     * @author aeon(qq:1584875179)
     *
     */
    public interface AbstractRole {
        /***
         * 房屋出租
         */
        void rent();
    }

      2.2真实角色(被代理角色)  

    package edu.aeon.model.dynamicproxy_v1;
    
    /**
     * [说明]:房东(真实角色)
     * 
     * @author aeon(qq:1584875179)
     *
     */
    public class HouseOwner implements AbstractRole {
    
        @Override
        public void rent() {
            System.out.println("HouseOwner.rent()_房屋出租");
        }
    }

      2.3动态代理类(重点)  

    package edu.aeon.model.dynamicproxy_v1;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    /**
     * [说明]:能动态生成代理角色并执行被代理角色行为的类
     * @author aeon(qq:1584875179)
     *
     */
    public class ProxyInvocationHandler implements InvocationHandler{
        //被代理角色接口类型
        private AbstractRole abstractRole;
        public void setAbstractRole(AbstractRole abstractRole) {
            this.abstractRole = abstractRole;
        }
        /**
         * 生成代理类
         * @return 返回生成的代理类实例
         */
        public Object getProxy(){
            return Proxy.newProxyInstance(this.getClass().getClassLoader(), abstractRole.getClass().getInterfaces(), this);
        }
        /**
         * 执行代理的方法
         */
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            before();
            //abstractRole:被代理角色类型,此处为了它的接口类型    args:被代理角色执行方法参数
            Object result=method.invoke(abstractRole, args);
            after();
            return result;
        }
        /**
         * 执行代理前做某些工作
         */
        public void before(){
            System.out.println("ProxyInvocationHandler.before()_执行代理前做某些工作...");
        }
        /**
         * 执行代理后做某些工作
         */
        public void after(){
            System.out.println("ProxyInvocationHandler.after()_执行代理后做某些工作...");
        }
    }

      2.4测试动态代理

    package edu.aeon.model.dynamicproxy_v1;
    /**
     * [说明]:测试动态代理
     * @author aeon(qq:1584875179)
     *
     */
    public class Test {
    
        public static void main(String[] args) {
            //真实角色
            HouseOwner houseOwner=new HouseOwner();
            //动态代理类实例
            ProxyInvocationHandler proxyInvocationHandler=new ProxyInvocationHandler();
            //设置被代理类为:houseOwner
            proxyInvocationHandler.setAbstractRole(houseOwner);
            //得到代理类实例
            AbstractRole abstractRole = (AbstractRole)proxyInvocationHandler.getProxy();
            //执行被代理的方法
            abstractRole.rent();
        }
    
    }

      执行结果截图如下:

      

    三、静态代理和动态代理

      静态代理的代理类是固定的且每一个业务类都要对应一个代理类,而动态代理的代理类是动态生成的、一个万能动态代理类可以代理所有类要做的事。

    四、通用动态代理类

      4.1通用动态代理类

    package edu.aeon.model.dynamicproxy_v2;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    /**
     * [说明]:通用动态生成代理角色并执行被代理角色行为的类
     * @author aeon(qq:1584875179)
     *
     */
    public class ProxyInvocationHandler implements InvocationHandler{
        //通用被代理角色接口类型
        private Object target;
        public void setTarget(Object target) {
            this.target = target;
        }
        /**
         * 生成代理类
         * @return 返回生成的代理类实例
         */
        public Object getProxy(){
            return Proxy.newProxyInstance(this.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
        }
        /**
         * 执行代理的方法
         */
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            before();
            //abstractRole:被代理角色类型,此处为了它的接口类型    args:被代理角色执行方法参数
            Object result=method.invoke(target, args);
            System.out.println("执行了"+method.getName()+"方法!");
            after();
            return result;
        }
        /**
         * 执行代理前做某些工作
         */
        public void before(){
            System.out.println("ProxyInvocationHandler.before()_执行代理前做某些工作...");
        }
        /**
         * 执行代理后做某些工作
         */
        public void after(){
            System.out.println("ProxyInvocationHandler.after()_执行代理后做某些工作...");
        }
    }

      4.2通用动态代理类测试  

    package edu.aeon.model.dynamicproxy_v2;
    
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * [说明]:测试动态代理类
     * @author aeon(qq:1584875179)
     *
     */
    public class Test {
    
        public static void main(String[] args) {
            //真实角色
            HouseOwner houseOwner=new HouseOwner();
            //动态代理类实例
            ProxyInvocationHandler proxyInvocationHandler=new ProxyInvocationHandler();
            //设置被代理类为:houseOwner
            proxyInvocationHandler.setTarget(houseOwner);
            //得到代理类实例
            AbstractRole abstractRole = (AbstractRole)proxyInvocationHandler.getProxy();
            //执行被代理的方法
            abstractRole.rent();
            System.out.println("不光可以代理以上类、还可以代理所有类,示例如下:");
            proxyInvocationHandler.setTarget(new ArrayList());
            List proxyList=(List) proxyInvocationHandler.getProxy();
            proxyList.add("test");
            proxyList.size();
            proxyList.get(0);
        }
    
    }

      测试结果截图如下:

      

    如有任何疑问可联系邮箱: 给我发邮件、或直接联系QQ:1584875179 || 点返回首页

  • 相关阅读:
    mybatis 从数据库查询的信息不完整解决办法
    Mybatis关联查询,查询出的记录数量与数据库直接查询不一致,如何解决?
    UltraEdit快捷键大全-UltraEdit常用快捷键大全
    使用UltraEdit 替换解决---文字中含有逗号的文件,如何把逗号自动转换成为:回车换行呢?
    在对文件进行随机读写,RandomAccessFile类,如何提高其效率
    雷军:曾经干掉山寨机,现在干掉山寨店(将性价比进行到底)
    tbox的项目:vm86(汇编语言虚拟机),tbox(类似dlib),gbox(c语言实现的多平台图形库)
    Delphi XE8 iOS与Android移动应用开发(APP开发)教程[完整中文版]
    人和动物的最大区别,在于能否控制自己
    CWnd和HWND的区别(hWnd只是CWnd对象的一个成员变量,代表与这个对象绑定的窗口)
  • 原文地址:https://www.cnblogs.com/aeon/p/10280331.html
Copyright © 2011-2022 走看看