代理模式---有事找助理

        声明:文章内容根据大牛博客的内容,自己理解后,给自己做的学习笔记,文末会附上大牛博客地址链接。有需要沟通交流的可加我QQ群:425120333
        代理分为静态代理和动态代理,静态代理比较好理解,关键是构建一个代理类,里面有个属性是目标对象(被代理的对象)。
    代理类有着和目标对象一样的方法(可以是实现同一个接口来保证),然后根据需要对目标对象里的行为进行变动。
    代码示例如下:
public class StaticProxy {
    public static void main(String[] args) {
        OriginClass origin = new OriginClass();
        origin.print();
        origin.print("test");
        OriginClassProxy originProxy = new OriginClassProxy(origin);
        originProxy.print();
        originProxy.print("test");
    }
}

/**
 * @author caiqibin
 * @introduce:目标对象类
 * 
 */
class OriginClass {
    public void print() {
        System.out.println("无参方法");
    }

    public void print(String arg) {
        System.out.println("有参方法 :" + arg);
    }
}

/**
 * @author caiqibin
 * @introduce:代理类
 * 
 */
class OriginClassProxy {
    //通过持有目标对象来改变目标对象的行为
    OriginClass originClass;

    public OriginClassProxy(OriginClass originClass) {
        this.originClass = originClass;
    }

    public void print() {
        System.out.println("通过代理调用");
        originClass.print();
    }

    public void print(String arg) {
        System.out.println("不用原有的方法,而是调用代理方法:" + arg);
    }
}
    关于动态代理,并不是直接创建代理类,而是通过反射实现的,主要是为很多对象添加一样的额外行为时比较常用(像spring的AOP),
当然为单个对象通过动态代理创建额外的行为也是可行的。
    动态代理的对象要求是接口或者是实现了接口的对象(不是绝对的,可以是普通对象,但需要和接口有同名方法,并且要在代理中自己通过反射调用)
public class DynamicProxy {
    public static void main(String[] args) {
        ZhangSan zhangSan = new ZhangSan();
        Person zhangSanProxy = (Person) Proxy.newProxyInstance(DynamicProxy.class.getClassLoader(), new Class[] { Person.class }, new ZhangSanProxy(zhangSan));
        zhangSanProxy.print();
        zhangSanProxy.print("111");
    }
}

/**
 * @author caiqibin
 * @introduce:接口类
 * 
 */
interface Person {
    void print();

    void print(String arg);
}

/**
 * @author caiqibin
 * @introduce:具体实现类
 * 
 */
class ZhangSan implements Person {

    @Override
    public void print() {
        System.out.println("i am zhang san");
    }

    @Override
    public void print(String arg) {
        System.out.println("i am zhang san ,say:" + arg);
    }

}

class ZhangSanProxy implements InvocationHandler {

    ZhangSan zhangSan;

    public ZhangSanProxy(ZhangSan zhangSan) {
        this.zhangSan = zhangSan;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //通过参数和方法名判断要调用的是那个方法
        if (args != null && "print".equals(method.getName())) {
            System.out.println("方法执行前,输出");
        }
        return method.invoke(zhangSan, args);
    }

}

控制台输出:

i am zhang san
方法执行前,输出
i am zhang san ,say:111

从输出中可以看出只有有参方法,执行了代理中的输出,通过方法名和参数可以控制类中任意一个方法,去执行我们想要的操作。
这里的代理时针对ZhangSan这个具体实现类,不是针对Person接口的,如果是针对接口的,实现了该接口的所有类都会出现统一的拦截处理。
有兴趣的可以自己动手试试看看。关于动态代理的原理可参考下面的链接,
参考大牛博客链接:http://www.cnblogs.com/zuoxiaolong/p/pattern3.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值