设计模式之代理模式

  1. 理解:顾名思义就是代替别人做事情,在Java中就是为其他对象提供一种代理,以控制对这个对象的访问,起到一个中介的作用,就向火车票代售点,房产中介,职介所等这一类的工作,为被代理的对象如火车站,房子的业主,用人单位提供自己本身的卖票,卖房/租房,招聘等工作
  2. 分类:
    1. 远程代理:C/S模式
    2. 虚拟代理:根据需要将消耗资源很大的对象进行延迟创建,在真正需要时进行创建
    3. 保护代理:控制一个对象的访问权限
    4. 智能引用代理:提供对象的一些其他代理
  3. 举例智能引用代理中的静态代理和动态代理
    1. 静态代理:代理类和目标对象的类在编译期间就被确定下来了,都实现了相同的接口或者继承了同一个类,实现静态代理采用聚合的代码开发方式,便于代理类的功能扩展。同时,每一个代理类只能为一个接口服务,这样一来程序开发过程中必定要产生更多的代理
      按照实现接口的方式实现静态代理
package com.fgy.delegate;
public interface Ticket {    
    public abstract void sellTickets();
}

目标对象

package com.fgy.delegate;
public class TrainStation implements Ticket {
    @Override
    public void sellTickets() {
       System.out.println("火车站卖的票!!!!");
    }

}

代理对象

package com.fgy.delegate;

public class SalePoint implements Ticket {

    TrainStation trainstation;
    public SalePoint(TrainStation trainStation) {
        this.trainstation = trainStation;
    }
    @Override
    public void sellTickets() {
       System.out.println("代售点操作卖票");
       trainstation.sellTickets();
       System.out.println("代售点卖完票了");
    }

}

运行结果
这里写图片描述

②动态代理:就是在代理类和被代理类中间加了一个InvocationHandler,不指定代理类,让程序动态的创建代理。
③创建一个动态代理要解决的问题
1)如何根据加载到内存中的被代理对象,动态的去创建代理对象
2)如何通过代理类的对象调用接口中的方法时,实现对被代理对象的同名方法的调用
举例:
first:创建一个被代理类实现的接口

public interface Human {
    void fly();
    void say();
}
sec:创建一个被代理类对象
package com.fgy.delegate;

public class SuperMan implements Human {

    @Override
    public void fly() {
        System.out.println("我是超人,我怕谁!!!!God!!!");
    }
    @Override
    public void say() {
        System.out.println("I believe I can fly!!!");
    }

}

Third:创建一个实现InvocationHandler接口的类

package com.fgy.delegate;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class MyInvocationHandler implements InvocationHandler {

    private Object obj;//被代理对象

    //将被代理对象绑定到
    public void bind(Object obj) {
        this.obj = obj;
    }

    //通过代理对象调用接口方法时,就会调用如下的handler
    /**
     * proxy:被代理对象
     * method:被代理对象的方法
     * args:方法的参数
     * 
     * Object:方法的返回值
     * 
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object result = method.invoke(obj);
        return result;
    }

}

用来专门生产代理的类

package com.fgy.delegate;

import java.lang.reflect.Proxy;

public class ProxyFactory {

    //返回代理对象
    public static Object getProxyInstance(Object obj) {//形参是被代理对象

        MyInvocationHandler myInvocationHandler = new MyInvocationHandler();
        myInvocationHandler.bind(obj);
        return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), myInvocationHandler);
    }
}

测试类:

package com.fgy.delegate;

public class TestDelegate {

    public static void main(String[] args) {
        //创建被代理对象
        SuperMan superMan = new SuperMan();
        Object proxy = ProxyFactory.getProxyInstance(superMan);
        Human human = (Human) proxy;
        human.fly();
        human.say();
    }

}

测试结果
这里写图片描述
以上就是动态代理的例子
Cglib动态代理和JDK动态代理的区别:
1. JDK 动态代理只能代理实现了接口的类,没有实现接口的类不能实现动态代理
2. Cglib是针对类来实现代理的,对指定目标类产生一个子类,通过方法拦截技术拦截所有父类方法的调用

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值