结构型模式之代理模式

结构型模式之代理模式

代理模式:访问对象不适合直接引用目标对象,代理对象作为访问对象和目标对象之间的中介。
角色:

  • 抽象主题(Subject)类:通过接口或抽象类声明真实主题和代理对象实现的业务方法。
  • 真实主题(Real Subject)类:实现了抽象主题中的具体业务,是代理对象所代表的真实对象,是最终要引用的对象。
  • 代理(Proxy)类:提供与真实主题相同的接口,其内部包含对真实主题的引用,它可以访问、控制或扩展真实主题的功能。

一般代理分三种模式:

  • 静态代理:代理类实现抽象主题类,聚合真实主题类,在实现抽象主题类中的业务方法中调用真实主题类进行扩展。
  • JDK动态代理:JDK动态代理通过Proxy.newProxyInstance方法进行动态代理,其中又主要用到了InvocationHandler接口中的invoke方法;聚合真实主题类,方法返回值为抽象主题类。本质是与真实主题类实现共有接口,通过多态性实现开闭原则。
	/**
	 * 代理工厂,生产代理对象
	 * 代理类也实现了对应的接口
	 */
	public class ProxyFactory {
	    // 目标对象
	    TrainStation trainStation = new TrainStation();
	
	    // 获取代理对象的方法。
	    public SellTickets getProxyObject(){
	        // 返回代理对象即可
	        return  (SellTickets) Proxy.newProxyInstance(trainStation.getClass().getClassLoader(),
	                trainStation.getClass().getInterfaces(),
	                new InvocationHandler() {
	                    @Override
	                    public Object invoke(Object proxy,
	                                         Method method,
	                                         Object[] args)
	                            throws Throwable {
	                        System.out.println("代理点收取服务费");
	                        // 执行目标对象的方法
	                        Object invoke = method.invoke(trainStation, args);
	                        return invoke;
	                    }
	                });
	    }
	}
  • CGLib动态代理:为JDK动态代理进行很好的补充,若目标代理类没有实现任何共有接口,JDK动态代理无法实现。CGLib动态代理需要实现MethodInterceptor接口,聚合真实对象类,实现intercept方法进行动态代理。
	/**
	 * 代理对象工厂 -- 获取代理对象
	 *      代理对象 -- 目标对象的子类
	 */
	public class ProxyFactory implements MethodInterceptor {
	    // 声明目标对象
	    TrainStation trainStation = new TrainStation();
	
	    public TrainStation getProxyObject() {
	        // 创建Enhancer对象,类似于JDK代理中的Proxy类
	        Enhancer enhancer = new Enhancer();
	        // 设置父类的类对象
	        enhancer.setSuperclass(TrainStation.class);
	        // 设置回调函数
	        enhancer.setCallback(this);
	        // 创建代理对象
	        TrainStation proxyObject = (TrainStation) enhancer.create();
	        return proxyObject;
	    }
	
	    @Override
	    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
	        System.out.println("代售点收取费用");
	        // 调用目标
	        Object invoke = method.invoke(trainStation, objects);
	        return invoke;
	    }
	}

JDK动态代理与CGLib动态代理区别

JDK动态代理的思想是通过与真实主题对象实现共有接口,调用代理方法,代理方法中可以对真实主题对象进行扩展和调用等操作,达到代理的模式。
CGLib动态代理思想,通过继承真实对象,实现MethodInterceptor中的intercept方法对真实主题对象进行代理。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值