设计模式 代理模式(静态代理 动态代理) 与 Spring Aop源码分析 具体是如何创建Aop代理的

这篇具有很好参考价值的文章主要介绍了设计模式 代理模式(静态代理 动态代理) 与 Spring Aop源码分析 具体是如何创建Aop代理的。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

代理模式

代理模式是一种结构型设计模式,它通过创建一个代理对象来控制对真实对象的访问。这种模式可以用于提供额外的功能操作,或者扩展目标对象的功能。

在代理模式中,代理对象与真实对象实现相同的接口,以便在任何地方都可以使用相同的接口来调用真实对象的方法。这样做的好处是可以在不改变原始代码的情况下,增加或修改代码的行为。

根据创建代理对象的方式和时机,代理模式可以被分为静态代理、动态代理等类型。其中,静态代理是由程序员在编译时期就定义好的代理类,而动态代理则是在程序运行时期通过Java反射机制动态生成的。

在实际生活中,有许多应用了代理模式的场景,例如租房、卖房、家政等业务,通常由中介机构作为代理来进行操作。

静态代理

静态代理在编译期间就已经确定代理类的代码。具体来说,要实现静态代理需要手动编写代理类的代码,因此这种方式的灵活性相对较差,但由于代理类是直接编写的,所以其运行效率较高。

首先定义购房者的行为

/**
 * 购房者
 *
 * @author LionLi
 */
public interface Homebuyer {

    /**
     * 需求
     */
    String need();

    /**
     * 购买
     */
    void buy();
}

定义真实购房者

/**
 * 购房者 张三
 *
 * @author LionLi
 */
public class Zhangsan implements Homebuyer {

    /**
     * 需求
     */
    @Override
    public String need() {
        String need = "100平以上三室两厅两卫";
        System.out.println("张三: " + need);
        return need;
    }

    /**
     * 购买
     */
    @Override
    public void buy() {
        System.out.println("张三: 我已付款");
    }
}
/**
 * 购房者 王五
 *
 * @author LionLi
 */
public class Wangwu implements Homebuyer {

    /**
     * 需求
     */
    @Override
    public String need() {
        String need = "70平左右两室一厅";
        System.out.println("王五: " + need);
        return need;
    }

    /**
     * 购买
     */
    @Override
    public void buy() {
        System.out.println("张三: 我已付款");
    }
}

定义房产中介

/**
 * 房产中介代理人
 *
 * @author LionLi
 */
public class HouseAgentProxy implements Homebuyer {
    private Homebuyer homebuyer;

    public HouseAgentProxy(Homebuyer homebuyer) {
        this.homebuyer = homebuyer;
    }

    @Override
    public String need() {
        System.out.println("中介: 你对房子有什么需求 放心交给我");
        String need = homebuyer.need();
        System.out.println("中介: 寻找房源中........");
        System.out.println("中介: 寻找房源中........");
        System.out.println("中介: 寻找房源中........");
        String str = "中介: 为您找到" + need + "的房子";
        System.out.println(str);
        return str;
    }

    @Override
    public void buy() {
        System.out.println("中介: 请支付购买房子");
        homebuyer.buy();
        System.out.println("中介: 合同生效中.....");
        System.out.println("中介: 房证办理中.....");
        System.out.println("中介: 恭喜您 这套房子属于您了");
    }
}

测试

/**
 * @author LionLi
 */
public class Test {

    public static void main(String[] args) {
        Homebuyer zhangsan = new Zhangsan();
        HouseAgentProxy agent1 = new HouseAgentProxy(zhangsan);
        agent1.need();
        agent1.buy();
        System.out.println("-----------------------------");
        Homebuyer wangwu = new Wangwu();
        HouseAgentProxy agent2 = new HouseAgentProxy(wangwu);
        agent2.need();
        agent2.buy();
    }
}

设计模式 代理模式(静态代理 动态代理) 与 Spring Aop源码分析 具体是如何创建Aop代理的,设计模式,springboot经验总结,代理模式,设计模式,静态代理,动态代理,spring aop源码分析

两位购房者分别根据需求在中介的带领下买到了房子 真是可喜可贺啊

动态代理

动态代理允许在运行时动态地创建代理对象。代理对象可以在调用实际对象的方法前后执行一些额外的操作,比如日志记录、权限检查等。

动态代理的实现方式有两种:基于接口和基于继承。基于接口的方式是最常用的,它使用Java的反射机制来实现代理对象。基于继承的方式则需要创建一个实现了目标类接口的子类,并重写其中的方法。

优点: 可以降低系统的耦合度,提高代码的可维护性和可扩展性。
缺点: 需要使用反射机制,性能比静态代理略低。

首先定义购房者的行为与实际购房者

使用上方代码不变

定义房产中介

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

/**
 * 动态房产中介代理人
 *
 * @author LionLi
 */
public class DynamicHouseAgentProxy implements InvocationHandler {
    private Homebuyer homebuyer;

    public Homebuyer getInstance(Homebuyer homebuyer) {
        this.homebuyer = homebuyer;
        return (Homebuyer) Proxy.newProxyInstance(homebuyer.getClass().getClassLoader(), homebuyer.getClass().getInterfaces(), this);
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        if (method.getName().equals("need")) {
            System.out.println("中介: 你对房子有什么需求 放心交给我");
            String need = (String) method.invoke(homebuyer, args);
            System.out.println("中介: 寻找房源中........");
            System.out.println("中介: 寻找房源中........");
            System.out.println("中介: 寻找房源中........");
            String str = "中介: 为您找到" + need + "的房子";
            System.out.println(str);
            return str;
        } else if (method.getName().equals("buy")) {
            System.out.println("中介: 请支付购买房子");
            Object invoke = method.invoke(homebuyer, args);
            System.out.println("中介: 合同生效中.....");
            System.out.println("中介: 房证办理中.....");
            System.out.println("中介: 恭喜您 这套房子属于您了");
            return invoke;
        }
        return null;
    }
}

测试

/**
 * @author LionLi
 */
public class Test {

    public static void main(String[] args) {
        DynamicHouseAgentProxy agent = new DynamicHouseAgentProxy();
        Homebuyer zhangsan = new Zhangsan();
        Homebuyer proxy1 = agent.getInstance(zhangsan);
        proxy1.need();
        proxy1.buy();
        System.out.println("-----------------------------");
        Homebuyer wangwu = new Wangwu();
        Homebuyer proxy2 = agent.getInstance(wangwu);
        proxy2.need();
        proxy2.buy();
    }

}

设计模式 代理模式(静态代理 动态代理) 与 Spring Aop源码分析 具体是如何创建Aop代理的,设计模式,springboot经验总结,代理模式,设计模式,静态代理,动态代理,spring aop源码分析
结果不变 两位购房者成功买到房子

Cglib动态代理

其他代码不变只变更中介类

import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

/**
 * 动态房产中介代理人
 *
 * 这里由于cglib已经不支持jdk17了 所以我们使用spring内部自带的cglib工具
 *
 * @author LionLi
 */
public class DynamicHouseAgentProxy implements MethodInterceptor {

    public Homebuyer getInstance(Homebuyer homebuyer) {
        Enhancer enhancer = new Enhancer();
        // 设置继承父类
        enhancer.setSuperclass(homebuyer.getClass());
        // 设置回调
        enhancer.setCallback(this);
        return (Homebuyer) enhancer.create();
    }

    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        if (method.getName().equals("need")) {
            System.out.println("中介: 你对房子有什么需求 放心交给我");
            String need = (String) proxy.invokeSuper(obj, args);
            System.out.println("中介: 寻找房源中........");
            System.out.println("中介: 寻找房源中........");
            System.out.println("中介: 寻找房源中........");
            String str = "中介: 为您找到" + need + "的房子";
            System.out.println(str);
            return str;
        } else if (method.getName().equals("buy")) {
            System.out.println("中介: 请支付购买房子");
            Object invoke = proxy.invokeSuper(obj, args);
            System.out.println("中介: 合同生效中.....");
            System.out.println("中介: 房证办理中.....");
            System.out.println("中介: 恭喜您 这套房子属于您了");
            return invoke;
        }
        return null;
    }
}

Spring中代理模式的应用

要说起Spring中的代理模式 要首当其冲的肯定是AOP了 接下来我们来看看在AOP中是如何使用代理模式的

这里涉及到一个注解 学过AOP的都知道 如果需要开启AOP那么需要增加这个注解

设计模式 代理模式(静态代理 动态代理) 与 Spring Aop源码分析 具体是如何创建Aop代理的,设计模式,springboot经验总结,代理模式,设计模式,静态代理,动态代理,spring aop源码分析

通过搜索找到 AspectJAutoProxyRegistrar 类, 该方法的作用就是往Spring容器中添加一个 BeanDefinition 类型为 AnnotationAwareAspectJAutoProxyCreator 用于创建代理对象

设计模式 代理模式(静态代理 动态代理) 与 Spring Aop源码分析 具体是如何创建Aop代理的,设计模式,springboot经验总结,代理模式,设计模式,静态代理,动态代理,spring aop源码分析
设计模式 代理模式(静态代理 动态代理) 与 Spring Aop源码分析 具体是如何创建Aop代理的,设计模式,springboot经验总结,代理模式,设计模式,静态代理,动态代理,spring aop源码分析

接下来我们进入 AnnotationAwareAspectJAutoProxyCreator 看看是如何创建代理的

由于 AnnotationAwareAspectJAutoProxyCreator 中并没有创建代理的方法 那么我们只能向上去父类里找, 通过不断的探索在 AnnotationAwareAspectJAutoProxyCreator -> AspectJAwareAdvisorAutoProxyCreator -> AbstractAdvisorAutoProxyCreator -> AbstractAutoProxyCreator 抽象类 AbstractAutoProxyCreator 中找到了 createProxy 方法

设计模式 代理模式(静态代理 动态代理) 与 Spring Aop源码分析 具体是如何创建Aop代理的,设计模式,springboot经验总结,代理模式,设计模式,静态代理,动态代理,spring aop源码分析
此方法是bean初始化的前置处理器 postProcessBeforeInstantiation 中使用的, 也就是说bean在初始化之前, 代理对象就已经创建好了

进入 createProxy 方法

设计模式 代理模式(静态代理 动态代理) 与 Spring Aop源码分析 具体是如何创建Aop代理的,设计模式,springboot经验总结,代理模式,设计模式,静态代理,动态代理,spring aop源码分析

进入 buildProxy 方法

设计模式 代理模式(静态代理 动态代理) 与 Spring Aop源码分析 具体是如何创建Aop代理的,设计模式,springboot经验总结,代理模式,设计模式,静态代理,动态代理,spring aop源码分析
设计模式 代理模式(静态代理 动态代理) 与 Spring Aop源码分析 具体是如何创建Aop代理的,设计模式,springboot经验总结,代理模式,设计模式,静态代理,动态代理,spring aop源码分析

这里我们可以看出 实际的代理对象是通过 ProxyFactory 工厂的 getProxyClassgetProxy 两个方法创建的

我们来看一下这两个方法具体实现

通过 getProxyClass 方法一直往下点 找到最终创建方法 DefaultAopProxyFactory#createAopProxy 为止
设计模式 代理模式(静态代理 动态代理) 与 Spring Aop源码分析 具体是如何创建Aop代理的,设计模式,springboot经验总结,代理模式,设计模式,静态代理,动态代理,spring aop源码分析
设计模式 代理模式(静态代理 动态代理) 与 Spring Aop源码分析 具体是如何创建Aop代理的,设计模式,springboot经验总结,代理模式,设计模式,静态代理,动态代理,spring aop源码分析
设计模式 代理模式(静态代理 动态代理) 与 Spring Aop源码分析 具体是如何创建Aop代理的,设计模式,springboot经验总结,代理模式,设计模式,静态代理,动态代理,spring aop源码分析

最后我们来分析最终是如何创建代理对象的

设计模式 代理模式(静态代理 动态代理) 与 Spring Aop源码分析 具体是如何创建Aop代理的,设计模式,springboot经验总结,代理模式,设计模式,静态代理,动态代理,spring aop源码分析文章来源地址https://www.toymoban.com/news/detail-807124.html

到了这里,关于设计模式 代理模式(静态代理 动态代理) 与 Spring Aop源码分析 具体是如何创建Aop代理的的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • 设计模式8:代理模式-动态代理

    上一篇:设计模式8:代理模式-静态代理 “动态”的含义是 代码生成代理类,一个代理类可以代理多个接口 。 动态区别于 死板 ,静态代理中一个代理类只能代理一个接口,其他不同的接口,就需要再手写不同的代理类,这就很 死板 。 动态代理类似于在安卓里面,我们常

    2024年02月09日
    浏览(33)
  • 设计模式的使用——模板方法模式+动态代理模式

    一、需求介绍   现有自己写的的一套审批流程逻辑,由于代码重构,需要把以前的很多业务加上审批的功能,再执行完审批与原有业务之后,生成一个任务,然后再统一处理一个任务(本来是通过数据库作业去处理的,后来说这个任务要马上去处理,只能去统一添加一个处

    2024年02月10日
    浏览(36)
  • Java 设计者模式以及与Spring关系(四) 代理模式

    目录 简介: 23设计者模式以及重点模式 代理模式(Proxy Pattern) 静态代理示例 spring中应用 动态代理 1.基于JDK的动态代理 target.getClass().getInterfaces()作用 内名内部类写法(更简洁,但不推荐) 2.基于CGLIB实现 spring中应用 本文是个系列一次会出两个设计者模式作用,如果有关联就三

    2024年01月23日
    浏览(48)
  • 设计模式——命令模式(Command Pattern)+ Spring相关源码

    类型: 行为型模式 目的: 将一个请求封装成一个对象,从而使您可以用不同的请求对客户进行参数化。 2.1.1 定义命令类接口 2.1.2 定义命令执行者 2.1.3 被处理对象Stock。 菜鸟教程定义 被处理的对象 是Stock。 2.1.4 封装处理Stock的命令 虽然 Runnable 接口本身并不是一个命令模式

    2024年02月06日
    浏览(40)
  • 设计模式——迭代器模式(Iterator Pattern)+ Spring相关源码

    类型: 行为型模式 目的: 用于顺序访问集合对象的元素,使用者不需要知道集合对象的底层表示。 2.1.1 定义迭代器接口 2.1.2 定义迭代对象接口——用于返回一个迭代器 2.1.3 实现 迭代对象 和 迭代器 2.1.4 使用 迭代器CompositeIterator 创建型模式 结构型模式 1、设计模式——装

    2024年02月05日
    浏览(43)
  • 设计模式——装饰器模式(Decorator Pattern)+ Spring相关源码

    别名:包装模式(Wrapper Pattern) 类型:结构型模式。 目的:指在不改变现有对象结构的情况下,动态地给该对象增加一些职责额外功能。 给对象添加新功能时,并不是在对象类中直接添加,而是在装饰器类中添加。 在装饰类中添加新功能,你可以增强原先对象的方法,也可

    2024年02月06日
    浏览(52)
  • JAVA设计模式第七讲:设计模式在 Spring 源码中的应用

    设计模式(design pattern)是对软件设计中普遍存在的各种问题,所提出的解决方案。本文以面试题作为切入点,介绍了设计模式的常见问题。 我们需要掌握各种设计模式的原理、实现、设计意图和应用场景,搞清楚能解决什么问题 。 本文是第七篇:设计模式在 Spring 源码中的

    2024年02月09日
    浏览(43)
  • 设计模式——观察者模式(Observer Pattern)+ Spring相关源码

    类型:行为型模式 目的:当一个对象的状态发生改变时,其所有依赖者(观察者)都会收到通知并自动更新。 2.1.1 定义观察者 2.1.2 定义被观察对象 2.1.3 使用 2.2.1 观察者接口Observer 2.2.1 被观察者对象Observable 2.3.1 观察者 2.3.2 被观察者 创建型模式 结构型模式 1、设计模式——

    2024年02月06日
    浏览(47)
  • Spring | Srping AOP (AOP简介、动态代理、基于“代理类”的AOP实现)

    作者简介 :一只大皮卡丘,计算机专业学生,正在努力学习、努力敲代码中! 让我们一起继续努力学习! 该文章 参考学习教材 为: 《Java EE企业级应用开发教程 (Spring + Spring MVC +MyBatis)》 黑马程序员 / 编著 文章以课本知识点 + 代码为主线,结合自己看书学习过程中的理解和

    2024年01月22日
    浏览(39)
  • 动态代理与Spring Aop

    JDK 动态代理 使用JAVA反射包中的类和接口实现动态代理的功能,JAVA.lang.reflect包;主要是三个类: InvocationHandler,Method,Proxy; CGLIB动态代理,第三方工具类库,创建代理对象,cglib的原理是继承,通过继承目标类,创建它的子类,在子类中重写父类中同名的方法,实现功能的修改

    2024年02月11日
    浏览(35)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包