代理模式

本文深入探讨了代理模式的定义及其实现方式,通过具体的代码示例解释了静态代理和动态代理的区别,以及如何在Java中利用动态代理实现对象的代理操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

一、代理模式的定义

二、类图

三、例子

四、动态代理例子


一、代理模式的定义

    为另一个对象提供一个替身以控制对这个对象的访问

二、类图

1、抽象对象角色(上图中的Subject接口)

    声明了目标对象和代理对象的共同接口,作用:任何可以使用目标对象的地方都可以使用代理对象

2、目标对象角色(上图中的RealSubject)

    定义了代理对象所代表的目标对象

3、代理对象角色(上图中的Proxy)

    代理对象内部含有目标对象的引用,从而可以在任何时候操作目标对象;代理对象提供一个与目标对象相同的接口,以便可以在任何时候替代目标对象

三、例子

1、抽象对象角色

/**
 *  抽象对象角色:Server
 *  声明了目标对象和代理对象的共同接口,继而在任何可以使用目标对象的地方都可以使用代理对象
 */

public interface Server {

	public String getPageTitle(String url);
}

2、目标对象角色

/**
 * 目标对象角色:SinaServer
 * 定义了代理对象所代表的目标对象
 */
public class SinaServer implements Server {

	@Override
	public String getPageTitle(String url) {
		if ("http://www.sina.com.cn/".equals(url)) {
			return "新浪首页";
		} else if ("http://http://sports.sina.com.cn/".equals(url)) {
			return "新浪体育_新浪网";
		}
		return "无页面标题";
	}

}

3、代理对象角色

/**
 *  代理对象角色:NginxProxy
 *  代理对象内部含有目标对象的引用,从而可以在任何时候操作目标对象;
 *  代理对象提供一个与目标对象相同的接口,以便可以在任何时候替代目标对象
 */
public class NginxProxy implements Server {

	private Server server;

	public NginxProxy(Server server) {
		this.server = server;
	}

	@Override
	public String getPageTitle(String url) {
		return "页面标题:" + server.getPageTitle(url);
	}

}

4、测试

public class ProxyTest {

	public static void main(String[] args) {
		Server sinaServer = new SinaServer();
		Server nginxProxy = new NginxProxy(sinaServer);
		//用户直接和nginxProxy代理打交道
		System.out.println(nginxProxy.getPageTitle("http://www.sina.com.cn/"));
        //运行结果:页面标题:新浪首页
	}
}

四、动态代理例子

1、代理类得实现 InvocationHandler 接口

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

public class NginxInvocationHandler implements InvocationHandler {

	private Object obj;

	public NginxInvocationHandler(Object obj) {
		this.obj = obj;
	}

	@Override
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		StringBuilder sb = new StringBuilder();
		sb.append("页面标题:");
		sb.append(method.invoke(obj, args));
		return sb.toString();
	}

}

2、测试

public class DynamicProxyTest {

	public static void main(String[] args) {
		Server sinaServer = new SinaServer();
		InvocationHandler invocationHandler = new NginxInvocationHandler(sinaServer);
		Server proxy = (Server) Proxy.newProxyInstance(Server.class.getClassLoader(),
				new Class[] { Server.class },invocationHandler);
		System.out.println(proxy.getPageTitle("http://www.sina.com.cn/"));

	}
}

3、思考:(1)例三和例四在实现上有何不同?(2)动态代理的原理是什么?(3)例四如果用Cglib实现,怎么做?与Cglib区别?

参考文章:https://www.cnblogs.com/xrq730/p/4907999.html(例子是参考这篇文章的,做了简单修改)

                  https://www.cnblogs.com/CarpenterLee/p/8241042.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值