温故知新之:代理模式,静态代理和动态代理(JDK动态代理)

这篇具有很好参考价值的文章主要介绍了温故知新之:代理模式,静态代理和动态代理(JDK动态代理)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

0、前言

代理模式可以在不修改被代理对象的基础上,通过扩展代理类,进行一些功能的附加与增强。

1、静态代理

静态代理是一种代理模式的实现方式,它在编译期间就已经确定了代理对象,需要为每一个被代理对象创建一个代理类。静态代理的实现比较简单,但是每个被代理对象都需要创建一个代理类,因此在代理对象比较多时,会导致代码几余和维护成本增加。

静态代理有两种实现,继承聚合两种模式。

1.1、继承模式

需要定义接口或者父类,被代理对象与代理对象一起实现相同的接口或者继续相同父类,代理对象继承目标对象,重新目标对象的方法。

 目标对象:

package proxy.staticproxy.extends_model;

//目标对象
public class UserService {

    public void login(){
        System.out.println("login success");
    }
}

代理类:

package proxy.staticproxy.extends_model;

//代理对象
public class UserServiceProxy extends UserService{

    public void login(){
        System.out.println("开始执行--------------");
        super.login();
    }
}

 测试类:

package proxy.staticproxy;

import proxy.staticproxy.extends_model.UserServiceProxy;
import proxy.staticproxy.implements_model.FactoryOne;
import proxy.staticproxy.implements_model.FactoryOneProxy;
import proxy.staticproxy.implements_model.IFactory;

public class Test {

    @org.junit.Test
    public void extends_model(){
        UserServiceProxy proxy = new UserServiceProxy();
        proxy.login();
    }

    //  待代理类来处理
    /// 场景:当不想改动被代理类的业务逻辑,在处理开始和结束分别加上时间显示
    /// 处理核心逻辑:需要实现被代理类的接口及方法,在实现方法中田间需要添加的业务处理逻辑
    @org.junit.Test
    public void implements_model(){
        // 创建被代理类的对象
        IFactory word = new FactoryOne();

        // 创建代理类的对象
        IFactory proxyPaperFactory = new FactoryOneProxy(word);
        proxyPaperFactory.production();
    }
    // 直接调用被代理类业务处理
    @org.junit.Test
    public void test01(){
        // 创建被代理类的对象
        IFactory word = new FactoryOne();
        word.production();
    }
}

 执行结果:

开始执行--------------
login success

1.2、聚合模式

温故知新之:代理模式,静态代理和动态代理(JDK动态代理),Java基础,java,开发语言

Subject:抽象主题角色,抽象主题类可以是抽象类,也可以是接口,是一个最普通的业务类型定义,无特殊要求。
RealSubject:具体主题角色,也叫被委托角色、被代理角色。是业务逻辑的具体执行者。
Proxy:代理主题角色,也叫委托类、代理类。它把所有抽象主题类定义的方法给具体主题角色实现,并且在具体主题角色处理完毕前后做预处理和善后工作。 

Subject 接口:

package proxy.staticproxy.implements_model;

public interface IFactory {

    void production();
}

 RealSubject 类:

package proxy.staticproxy.implements_model;

public class FactoryOne implements IFactory {

    @Override
    public void production() {
        System.out.println(" 被代理类,开始初始化 ");

        System.out.println(" 生产笔记本、鼠标、键盘等等 ");

        System.out.println(" 被代理类处理完成 ");
    }
}

Proxy 类:

package proxy.staticproxy.implements_model;

public class FactoryOneProxy implements IFactory {
    private IFactory factory; // 用被代理类对象进行实例化

    public FactoryOneProxy(IFactory factory) {
        this.factory = factory;
    }

    @Override
    public void production() {
        System.out.println(" 代理开始工作 ,在此可以添加处理逻辑");
        factory.production();
        System.out.println(" 代理结束工作 ,在此可以添加处理逻辑");
    }
}

 测试类:

package proxy.staticproxy;

import proxy.staticproxy.extends_model.UserServiceProxy;
import proxy.staticproxy.implements_model.FactoryOne;
import proxy.staticproxy.implements_model.FactoryOneProxy;
import proxy.staticproxy.implements_model.IFactory;

public class Test {

    @org.junit.Test
    public void extends_model(){
        UserServiceProxy proxy = new UserServiceProxy();
        proxy.login();
    }

    //  待代理类来处理
    /// 场景:当不想改动被代理类的业务逻辑,在处理开始和结束分别加上时间显示
    /// 处理核心逻辑:需要实现被代理类的接口及方法,在实现方法中田间需要添加的业务处理逻辑
    @org.junit.Test
    public void implements_model(){
        // 创建被代理类的对象
        IFactory word = new FactoryOne();

        // 创建代理类的对象
        IFactory proxyPaperFactory = new FactoryOneProxy(word);
        proxyPaperFactory.production();
    }
    // 直接调用被代理类业务处理
    @org.junit.Test
    public void test01(){
        // 创建被代理类的对象
        IFactory word = new FactoryOne();
        word.production();
    }
}

运行结果:

 代理开始工作 ,在此可以添加处理逻辑
 被代理类,开始初始化 
 生产笔记本、鼠标、键盘等等 
 被代理类处理完成 
 代理结束工作 ,在此可以添加处理逻辑

2、动态代理

动态代理是一种代理模式的实现方式,它在运行期间根据需要动态生成代理对象,无需手动编写代理类,可以减少代码几余和维护成本。动态代理适用于需要代理的对象数量较多,代理类实现对灵活的场景,例Spring框架中的Spring AOP(面向切面编程)功能。

动态代理的实现方式也有两种,JDK动态代理CGLB动态代理两种模式。本文重点介绍JDK动态代理,

在JDK中,有一个Proxy类(名词,代理人)。Proxy类是专门完成代理的操作类,可以通过此类为一个或多个接口动态的生成实现类。Proxy类提供的有一个静态方法:newProxyInstance()方法给我们的目标对象(委托对象)返回一个代理对象。

温故知新之:代理模式,静态代理和动态代理(JDK动态代理),Java基础,java,开发语言温故知新之:代理模式,静态代理和动态代理(JDK动态代理),Java基础,java,开发语言核心方法:newProxyInstance方法的三个参数,按照顺序分别是 ClassLoader (类加载器),interfaces(一组接口,接口数组),InvocationHandler(调用处理器)。

ClassLoader (类加载器)

定义了由哪个classLoader对象来对生成的代理对象进行加载。

接口数组:

一个Interface对象的数组,表示将要给我需要代理的对象提供一组什么接口,如果我提供了一组接口给它,那么这个代理对象就宣称实现了该接口(多态),这样我就能调用这组接口中的方法了。

调用处理器:

一个InvocationHandler接口,表示代理实例的调用处理程序实现的接口。每个代理实例都具有一个关联的调用处理程席。对代理实例调用方法时,将对方法调用进行编码并将其指派到它的调用处理程序的 invoke 方法(传入InvocationHandler接口的子类)。

对象接口:

package proxy.dynamicproxy.v3;

public interface IAnimal {
    public void run();

    public void eat();

    public void sleep();
}

被代理类<Cat>:

package proxy.dynamicproxy.v3;

public class Cat implements IAnimal{

    @Override
    public void run() {
        System.out.println("Cat Run invoking!!!");
    }

    @Override
    public void eat() {
        System.out.println("Cat eat invoking!!!");
    }

    @Override
    public void sleep() {
        System.out.println("Cat sleep invoking!!!");
    }
}

被代理类<Dog>: 

package proxy.dynamicproxy.v3;

public class Dog implements IAnimal{

    @Override
    public void run() {
        System.out.println("Dog Run invoking!!!");
    }

    @Override
    public void eat() {
        System.out.println("Dog eat invoking!!!");
    }

    @Override
    public void sleep() {
        System.out.println("Dog sleep invoking!!!");
    }
}

 代理类工具类:

package proxy.dynamicproxy.v3;

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

public class ProxyUtils {

    public Object object;

    public ProxyUtils(Object object) {
        this.object = object;
    }

    public Object createProxyObj(){

        // 动态代理 顾名思义 针对接口动态生成代理类处理业务逻辑
        // 返回动态代理
        /*
        ClassLoader loader, 要实现接口的类加载器
        Class<?>[] interfaces,接口类
        InvocationHandler h 处理类
        * **/
        ClassLoader loader = object.getClass().getClassLoader();
//        Class<?>[] interfaces = new Class[]{argObj.getClass()};  // 当是接口
        Class<?>[] interfaces = object.getClass().getInterfaces(); // 当是类直接获取对应的接口方法;

        InvocationHandler handler = new IFactoryInvocationHandler();

        Object object = Proxy.newProxyInstance(loader, interfaces, handler);
        return object;
    }

    public class IFactoryInvocationHandler implements InvocationHandler {

        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            System.out.println("IFactoryInvocationHandler invoke Before!!!");
            Object rtn = method.invoke(object, args);
            System.out.println("IFactoryInvocationHandler invoke After!!!");
            return rtn;
        }
    }

}

测试类:

package proxy.dynamicproxy;

import proxy.dynamicproxy.v3.Cat;
import proxy.dynamicproxy.v3.IAnimal;
import proxy.dynamicproxy.v3.ProxyUtils;

public class Test {

    @org.junit.Test
    public void v3_common_test() {

        // 实例化代理工具类
        ProxyUtils proxyUtils = new ProxyUtils(new Cat());

        // 创建代理对象
        IAnimal animal = (IAnimal)proxyUtils.createProxyObj();

        // 调用被代理类的方法
        animal.eat();
        System.out.println("========================================================");
        animal.run();
        System.out.println("========================================================");
        animal.sleep();
        System.out.println("========================================================");
    }
}

 运行结果:

IFactoryInvocationHandler invoke Before!!!
Cat eat invoking!!!
IFactoryInvocationHandler invoke After!!!
========================================================
IFactoryInvocationHandler invoke Before!!!
Cat Run invoking!!!
IFactoryInvocationHandler invoke After!!!
========================================================
IFactoryInvocationHandler invoke Before!!!
Cat sleep invoking!!!
IFactoryInvocationHandler invoke After!!!
========================================================

Process finished with exit code 0

3、动态代理原理

JDK动态代理是一种实现代理模式的方式。它利用Java的反射机制,在运行时动态地创建代理对象,实现对目标对象的代理。

JDK动态代理的原理如下:
定义接口:首先需要定义一个接口,用于描述目标对象和代理对象的共同行为。
实现InvocationHandler接口:创建一个实现InvocationHandler接口的代理处理器类,该类负责对目标对象的方法进行代理。
获取代理类:通过java.lang.reflect.Proxy的静态方法newProxyInstance()创建代理类,该方法需要传入ClassLoader、接口数组和InvocationHandler实例。
调用代理对象:通过代理对象调用方法时,实际上是调用InvocationHandler的invoke()方法。
在invoke()方法中,可以进行一些额外的操作,比如在调用目标方法之前进行预处理、在调用目标方法后进行后处理等。文章来源地址https://www.toymoban.com/news/detail-680610.html

4、总结

到了这里,关于温故知新之:代理模式,静态代理和动态代理(JDK动态代理)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • .net 温故知新【14】:Asp.Net Core WebAPI 缓存

    缓存指在中间层中存储数据的行为,该行为可使后续数据检索更快。 从概念上讲,缓存是一种性能优化策略和设计考虑因素。 缓存可以显著提高应用性能,方法是提高不常更改(或检索成本高)的数据的就绪性。 在最新的缓存控制规范文件RFC9111中,详细描述了浏览器缓存和

    2024年02月05日
    浏览(58)
  • Linux学习第31天:Linux MISC 驱动实验:温故知新

    Linux版本号4.1.15   芯片I.MX6ULL                                     大叔学Linux    品人间百味  思文短情长           学习是一个不断重复的过程。只有不断的使用、修正,才能越记越牢。将学习到的新的知识点应用到以往的项目经验中,才能不断提升自我,长此以往

    2024年02月06日
    浏览(42)
  • .net 温故知新【17】:Asp.Net Core WebAPI 中间件

    到这篇文章为止,关于.NET \\\"温故知新\\\"系列的基础知识就完结了,从这一系列的系统回顾和再学习,对于.NET core、ASP.NET CORE又有了一个新的认识。 不光是从使用,还包括这些知识点的原理,虽然深入原理谈不上,但对于日常使用也够了,我想的是知其然,知其所以然。 在实际

    2024年01月18日
    浏览(55)
  • .net 温故知新【11】:Asp.Net Core WebAPI 入门使用及介绍

    在Asp.Net Core 上面由于现在前后端分离已经是趋势,所以asp.net core MVC用的没有那么多,主要以WebApi作为学习目标。 我使用的是VS2022, .Net 7版本。 在创建界面有几项配置: 配置Https 启用Docker 使用控制器 启用OpenAPI支持 不使用顶级语句 其中配置Https 是WebApi是否使用https协议,启

    2024年02月07日
    浏览(42)
  • 【温故而知新】JavaScript类、类继承、静态方法

    JavaScript是一种广泛使用的编程语言,主要用于Web开发。它是一种脚本语言,这意味着它不需要像编译语言那样预先编译,而是在运行时解释和执行。JavaScript可以直接在浏览器中运行,这使得它在前端开发中特别重要,可以用于动态生成和更改网页内容、响应用户交互、发送

    2024年01月22日
    浏览(46)
  • 设计模式之代理模式(静态代理&动态代理)

    目录 1、什么是代理模式 2、代理模式的结构 3、代理模式的实现 3.1 静态代理和动态代理概念 3.2 静态代理 3.3 动态搭理 3.3.1 代码实现 3.3.2 Proxy类讲解 4、动态代理VS静态代理 5、代理模式优缺点 由于某些原因需要给某对象提供一个代理以控制对该对象的访问。这时,访问对象

    2024年02月03日
    浏览(32)
  • 代理模式--静态代理和动态代理

    定义:代理模式就是代替对象具备真实对象的功能,并代替真实对象完成相应的操作并且在不改变真实对象源代码的情况下扩展其功能,在某些情况下,⼀个对象不适合或者不能直接引⽤另⼀个对象,⽽代理对象可以在客户端和⽬标对象之间起到中介的作⽤ 使用代理模式可以

    2024年02月15日
    浏览(38)
  • Java代理模式——静态代理与动态代理

    代理模式允许你为其他对象提供一个代理,以控制对这个对象的访问。代理模式在不改变实际对象的情况下,可以在访问对象时添加额外的功能。 可以理解为代理模式为被代理对象创造了一个替身,调用者可以通过这个替身去实现这个被代理对象的功能,这个替身也可以为被

    2024年02月13日
    浏览(44)
  • 代理设计模式——静态代理和动态代理

    代理模式 在代理模式(Proxy Pattern)中,一个类代表另一个类的功能。这种类型的设计模式属于结构型模式,在代理模式中,我们创建具有现有对象的对象,以便向外界提供功能接口。 意图: 为其他对象提供一种代理以控制对这个对象的访问。 主要解决: 在直接访问对象时

    2024年02月13日
    浏览(42)
  • 代理模式:静态代理+JDK/CGLIB 动态代理

    代理模式是一种比较好理解的设计模式。简单来说就是 我们使用代理对象来代替对真实对象(real object)的访问,这样就可以在不修改原目标对象的前提下,提供额外的功能操作,扩展目标对象的功能。 代理模式的主要作用是扩展目标对象的功能,比如说在目标对象的某个方法

    2024年02月13日
    浏览(35)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包