版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_40646143/article/details/85109086
代理模式核心作用:
- 通过代理,控制对对象的防问
- 可以详细控制访问某个(某类)对象的方法 , 在调用这个方法前做前置处理 , 调用这个方法后做后置处理 。 (即 : AOP的微观实现)
代理模式(proxy pattern)
- 核心角色 -- 定义代理角色和真实角色的公共对外方法 。
- 真实角色 -- 实现抽象角色 , 定义真实角色所要实现的业务逻辑,供代理角色调用 。 -- 关注真正的业务逻辑
- 代理角色 -- 实现抽象角色,是真实角色的代理 ,通过真实角色的业务逻辑方法来实现抽象方法 ,并添加自己的操作。-将统一的流程放到代理橘色中处理
应用场景:
- 安全代理 : 屏蔽对真实角色的直接访问 。
- 远程代理 : 通过代理类处理远程方法调用(RMI) 。
- 延迟代理 : 先加载轻量级的代理角色 ,真正需要时在加载真实对象 。
分类
- 静态代理 -- 静态定义代理类
- 动态代理 -- 动态生成代理类
- 1),JDK自带的动态代理
- 2), javaassist字节码操作库实现
- 3), CCLIB
- 4),ASM(底层使用激光指令,可维护性比较差)
我们以用户租房子找中介来实现静态代理 入下
1),创建房东和中介公共接口类
/**房东/中介抽象接口类
* @author 晓电脑
*/
public interface IntermediaryProxy {
/**
* 看房子
*/
void houseInspection();
/**
* 签合同
*/
void signAcontract();
/**
* 租房子
*/
void RentAnApartment();
/**
* 付钱
*/
void Pay();
}
2),创建真实角色 房东
/**房东 真实角色
* @author 晓电脑
*/
public class RealRole implements IntermediaryProxy {
@Override
public void houseInspection() {
System.out.println("看房子");
}
@Override
public void signAcontract() {
System.out.println("签合同");
}
@Override
public void RentAnApartment() {
System.out.println("三室一厅值得拥有,租下这个房子");
}
@Override
public void Pay() {
System.out.println("付钱");
}
}
3),创建中介公司
/** 中介公司
* @author 晓电脑
*/
public class IntermediaryAgent implements IntermediaryProxy {
private IntermediaryProxy intermediaryProxy;
public IntermediaryAgent(IntermediaryProxy intermediaryProxy) {
this.intermediaryProxy = intermediaryProxy;
}
@Override
public void houseInspection() {
System.out.println("带客户去看房子");
}
@Override
public void signAcontract() {
System.out.println("带客户签合同");
}
@Override
public void RentAnApartment() {
//真实房源
intermediaryProxy.RentAnApartment();
}
@Override
public void Pay() {
System.out.println("付钱");
}
}
- 中介与房东 共同实现于 抽象的接口类
- 中介类中含有真实角色的房源 如 intermediaryProxy.RentAnApartment();
4),创建客户来租房子
/**
* 相当于租房子的客户
*
* @author 晓电脑
*/
public class Client {
public static void main(String[] args) {
//创建真实角色
IntermediaryProxy intermediaryProxy = new RealRole();
//使用代理
IntermediaryAgent agent = new IntermediaryAgent(intermediaryProxy);
agent.houseInspection();
agent.signAcontract();
agent.RentAnApartment();
agent.Pay();
}
}
绘制uml图
下面我们来看一下动态代理
- 动态代理相对于静态代理的优点
- 抽象角色中(接口)声明的所以方法都被转移到调用处理器一个集中的方法中处理 , 这样,我们可以更加灵活和统一的处理众多的方法。
JDK自带动态代理
- java.lang.reflect.Proxy -- 作用: 动态生成代理类和对象
- java. lang. reflect . InvocationHandler(处理器接口)
- 1),可以通过invoke方法实现对真实角色的代理访问
- 2),每次通过Proxy 生成代理类对象对象时都要指定对象的处理器对象
1),创建明星抽象接口
public interface Star {
/**
* 签合同
*/
void SignAcontract();
/**
* 唱歌
*/
void sing();
/**
* 付钱
*/
void pay();
}
2),创建真实明星 实现与抽象接口类
/**创建真实角色
* @author 晓电脑
*/
public class RealStar implements Star {
@Override
public void SignAcontract() {
System.out.println("签合同");
}
@Override
public void sing() {
System.out.println("周杰伦唱歌");
}
@Override
public void pay() {
System.out.println("付钱");
}
}
3),创建动态代理类 需要实现与 InvocationHandler
/**使用JDK 自带的动态代理类
* @author 晓电脑
*/
public class StarHandler implements InvocationHandler {
private RealStar realStar;
public StarHandler(RealStar realStar) {
this.realStar = realStar;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//将核心方法进行隐藏 除了核心方法做了统一的流程处理
System.out.println("真正方法执行前");
System.out.println("签合同");
if (method.getName().equals("sing")){
method.invoke(realStar,args);
}
System.out.println("真正方法执行后");
System.out.println("付钱");
return null;
}
}
4),创建测试的客户端类 Client类
/**
* 测试动态代理客户端
*
* @author 晓电脑
*/
public class Cilent {
public static void main(String[] args) {
//创建真实角色
RealStar star = new RealStar();
//创建代理类实例
StarHandler handler = new StarHandler(star);
//生成代理对象
Star star1 = (Star) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(),
new Class[]{Star.class},
handler);
star1.sing();
}
}
运行如下