IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> 设计模式之代理模式 -> 正文阅读

[Java知识库]设计模式之代理模式

1.简要概述

  • 代理模式就是通过代理对象来控制对真实对象的访问,也就是详细的控制访问某个对象的方法,从而将一些统一的流程代码放到代理类中处理。
  • 代理模式中,被代理的对象可以是远程对象、创建开销大的对象、需要安全控制的对象。
  • 代理模式是面向切面编程的核心实现思想。

2.模式分类

  • 静态代理

    在静态代理中,需要定义一个公共接口,代理对象和被代理对象都要实现这个公共接口中的方法。

    // 教师接口
    public interface CommonTeacher{
        void teach();
    }
    
    // 真实教师角色
    public class RealTeacher implements CommonTeacher{
        @Override
        public void teach(){
            System.out.println("开始上课");
        }
    }
    
    // 代理教师角色
    public class ProxyTeacher implements CommonTeacher{
        private CommonTeacher realTeacher;
        
        public ProxyTeacher(CommonTeacher realTeacher){
            this.realTeacher = realTeacher;
        }
        
        @Override
        public void teach(){
            System.out.println("通知某个教师");
           	realTeacher.teach();
        }
    }
    
    // 测试客户端
    public class Client{
        public static void main(String[] args) {
    		ProxyTeacher proxy = new ProxyTeacher(new RealTeacher());
    		
    		proxy.teach();
    	}
    }
    

    👉优点:在不修改目标对象功能的前提下,能够通过代理对象实现对目标对象的扩展。

    👉缺点:由于代理对象和目标对象都要实现统一的接口,一旦接口中增加新的功能方法,那么二者都需要进行更改实现。

  • JDK动态代理

    在JDK动态代理中,需要定义一个接口,被代理对象要实现这个接口中的方法。但代理对象不需要实现接口,而是利用JDK中提供的API,动态的在内存中构建代理对象。

    请添加图片描述

    // 教师接口
    public interface CommonTeacher{
        void teach();
    }
    
    // 真实教师角色
    public class RealTeacher implements CommonTeacher{
        @Override
        public void teach(){
            System.out.println("开始上课");
        }
    }
    
    // 代理教师角色
    public class ProxyTeacher implements InvocationHandler{
        private CommonTeacher realTeacher;
        
        public ProxyTeacher(CommonTeacher realTeacher){
            this.realTeacher = realTeacher;
        }
        
        @Override
        public Object invoke(Object proxy, Method method, Object[] args){
    		if(method.getName().equals("teach"))
    		{
                System.out.println("通知某个教师");
    			method.invoke(realTeacher, args);
    		}
    		
    		return null;
    	}
        
        public Object getProxy(){
            return Proxy.newProxyInstance(
                        ClassLoader.getSystemClassLoader(), 
                        new Class[] {CommonTeacher.class},
                        realTeacher);
        }
    }
    
    // 测试客户端
    public class Client{
        public static void main(String[] args) {
    		ProxyTeacher proxy = new ProxyTeacher(new RealTeacher());
    		CommonTeacher teacher = (CommonTeacher) proxy.getProxy();
    	
    		teacher.teach();
    	}
    }
    

    👉优点:它是Java原生支持的API,不需要任何其它第三方依赖

    👉缺点:它只能基于接口进行实现

  • Cglib代理

    在Cglib动态代理中,不需要定义接口,需要定义一个类去实现Cglib包中的MethodInterceptor类,然后在重写的intercept方法中完成被代理对象的调用,最后再通过Enhance工具类生成被代理对象的一个子类,让这个子类充当代理对象。Cglib是一个高性能的代码生成包,底层是通过使用字节码处理框架ASM来转换并生成新的类。

    请添加图片描述

    请添加图片描述

    // 真实教师角色
    public class RealTeacher{
        public void teach(){
            System.out.println("开始上课");
        }
    }
    
    // 代理教师角色
    public class ProxyTeacher implements MethodInterceptor{
        private RealTeacher realTeacher;
        
        public ProxyTeacher(RealTeacher realTeacher){
            this.realTeacher = realTeacher;
        }
        
        @Override
        public Object intercept(
            Object arg0, Method arg1, Object[] arg2, MethodProxy arg3){
            
    		System.out.println("通知某个教师");
            Object result = arg3.invokeSuper(arg0, arg2);
    		
    		return result;
    	}
        
        public Object getProxy(){
            Enhancer enhancer = new Enhancer();
    		enhancer.setSuperclass(RealTeacher.class);
    		enhancer.setCallback(realTeacher);
    
            return (RealTeacher) enhancer.create();
        }
    }
    
    // 测试客户端
    public class Client{
        public static void main(String[] args) {
    		ProxyTeacher proxy = new ProxyTeacher(new RealTeacher());
    		ProxyTeacher teacher = (ProxyTeacher) proxy.getProxy();
    
    		teacher.teach();
    	}
    }
    

    👉优点:它与代理的目标对象没有使用限制,无需定义和实现任何接口

    👉缺点:无法处理被final修饰的方法,因为在创建子类对象的时候无法继承

3.模式结构

👉通常由一个抽象角色( 负责定义真实角色和代理角色的一些公共方法 ),一个代理角色( 负责通过真实角色的业务逻辑方法来实现抽象方法,并附加一些别的操作 ),一个真实角色( 负责实现抽象角色,定义真实角色所要实现的业务逻辑供代理角色调用 ),一个客户类( 负责调用代理对象,完成对真实角色的访问)共同组成。

请添加图片描述

4.实现代码

举例 💡 :假设我们现在要租房,而房东希望我们先和中介进行商量已确定价格,然后我们才给房东进行付钱,那么这个处理过程我们就可以使用代理模式处理。

房子(抽象角色)

public interface House {
	// 谈价格
	void talk();
    
    // 付租金
	void pay();
}

房子中介(代理角色)

public class HouseProxy implements House{
	
	private Landlord landlord;
	
	public HouseProxy(Landlord landlord) {
		this.landlord = landlord;
	}

    @Override
	public void talk() {
		System.out.println("找中介谈价格");
	}

    @Override
	public void pay() {
		landlord.pay();
	}
}

房东(真实角色)

public class Landlord implements House{
	@Override
	public void talk() {
		System.out.println("");
	}
    
	@Override
	public void pay() {
		System.out.println("给房东付钱");
	}
}

客户类

// 测试客户端
public class HouseClient{
    public static void main(String[] args) {
        House proxy = new HouseProxy(new Landlord());
		
		proxy.talk();
		proxy.pay();
    }
}

5.优点好处

  • 代理对象可以在客户端和目标对象之间起到中介的作用,这样就起到了保护了目标对象的作用。
  • 代理对象可以扩展目标对象的功能。
  • 代理模式能将客户端与目标对象分离,在一定程度上降低了系统的耦合度。

6.缺点弊端

  • 在客户端和目标对象之间增加一个代理对象,会造成请求处理速度变慢。
  • 一定程度上增加了系统的复杂度。

7.应用场景

  • 当我们想通过代理来控制对远程对象的访问,可以使用远程代理。
  • 当我们想利用权限来控制对对象的访问,以此来屏蔽对真实对象的直接访问,可以使用安全代理。
  • 当我们需要创建开销很大的对象,先加载一个轻量级的代理对象,以便延迟对真实对象的访问,可以使用虚拟代理。
  • 当我们在处理真实对象的时候,希望代理去处理另外一些事情,可以使用智能代理。

8.应用示例

Spring源码中的AOP面向切面编程

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2021-10-19 11:44:20  更:2021-10-19 11:45:29 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 21:08:34-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码