• 代理模式+动态代理+静态代理+那些使用场景?


    什么是代理模式,什么是动态代理和静态代理?

    首先要知道什么是代理模式SpringAOP的设计模式就是动态代理

    代理模式就是一种比较优秀的设计模式,简而言之就是:我们使用代理对象来代替对目标对象的访问【相当于我们访问目标对象时,其实访问的是代理对象(代理对象中注入了目标对象所有的功能,如果我们需要对目标对象添加功能,其实添加的功能是添加给了代理对象)】,这样就能够保证在不修改原本目标对象的前提下增加额外的功能给目标对象

    代理模式的主要作用通过代理对象对目标对象的功能进行增强【其实是代理对象中注入了目标对象(将目标对象的类当作自己的成员变量),然后调用目标对象的方法,再进行扩展功能】(遵循OCP原则),比如说在目标对象的某个方法增加一些安全检测(自定义),事务,异常的统一处理等功能。

    代理模式又分为动态代理和的静态代理。

    什么是动态代理?

            在程序运行期间,创建目标对象的代理对象,通过代理对象对目标对象的功能进行增强的一种技术。其实代理对象就是将目标对象的类当作自己的成员变量,然后重写构造方法,跟目标对象实现相同的接口,从而拥有相同的方法,我们就可以对原本目标对象的方法进行前置增强或者后置增强等等。

    动态代理:

            解决静态代理的缺点,不用每个都去创建一个代理类。

    动态代理流程:

    在程序执行的过程中,使用jdk的反射机制【通过该类的字节码文件动态的获取改类的构造方法,成员方法和字段等属性】,创建代理类对象,并且动态的指定要代理的目标类。

    再详细的解释:

    1. 动态代理是指代理类对象在程序运行时由JVM根据反射机制动态生成的。动态代理不需要定义代理类的,java源文件。

    2. 动态代理其实就是jdk运行期间,动态创建class字节码并加载到JVM。

    3. 动态代理的实现方式常用的有两种:使用JDK代理,与通过CGLlB动态代理

    动态代理步骤:

    1.创建一个实现接口InvocationHandler的类,它必须实现invoke方法

    2.创建被代理的类以及接口

    3.通过Proxy的静态方法 newProxyInstance(ClassLoaderloader, Class[] interfaces, InvocationHandler h)创建一个代理对象

    4.通过代理对象调用方法

    实现动态代理的方式?

    通过反射。

    什么是反射?【SpringIOC】

    https://so.csdn.net/so/search?q=%E5%8F%8D%E5%B0%84&t=blog&u=ju_362204801

            反射就是在运行时期通过获取类的字节码文件,动态地去获取类中的信息(类的信息,方法信息,构造器信息,字段等信息),并映射成一个个对象。【要向获取类中的信息,就需要先获取该类的字节码文件对象(class)--三种方式Class.forName(全限定路径)【常用】、对象.getClass()、类名.class 】拿到映射后的构造方法,可以用它来生成对象;拿到映射后的方法,可以调用它来执行对应的方法;拿到映射后的字段,可以用它来获取或改变对应字段的值;

            动态代理又分为原生JDK动态代理方式【只适用于接口--致命缺点】和第三方cglib动态代理【可以代理未实现任何接口的类】

    什么是静态代理?

    静态代理,我们对目标对象的每个方法的增强都是手动完成的,非常不灵活(比如接口一旦新增加方法,目标对象和代理对象都要进行修改),而且麻烦(需要对每个目标类都单独写一个代理类)。几乎不使用。

    静态代理和动态代理的对比

    灵活性 :动态代理更加灵活,不需要必须实现接口,可以直接代理实现类,并且可以不需要针对每个目标类都创建一个代理类。另外,静态代理中,接口一旦新增加方法,目标对象和代理对象都要进行修改,这是非常麻烦的!

    JVM 层面 :静态代理在编译时就将接口、实现类、代理类这些都变成了一个个实际的 class 文件【直接将所有的编译成了class字节码文件,消耗资源。】而动态代理是在运行时动态**生成类字节码【需要的才进行生成,并加载到 JVM** 中的。

    3那些场景使用了动态代理?

            动态代理的使用场景Spring中的AOP(面向切面编程)。例如依赖注入 @Autowired 和事务注解 @Transactional 等,都是利用动态代理实现的。

    3.1MyBaits的Mapper接口没有实现类为什么可以用@Autowired直接注入?

            使用了JDK动态代理,赋值给mapper接口的对象其实是一个代理对象,这个代理对象是由 JDK 动态代理创建的。在解析mapper的时候,mybatis会通过java反射,获取到接口所有的方法。当调用接口中方法时,将通过接口全限定名+方法名对应找到映射文件中namespace和id匹配的sql,然后进行执行sql语句

    3.2为什么Feign的客户端接口 没有写实现类 也可以直接被依赖注入?

            自动注入的实例其实是一个jdk 动态代理对象【生成接口的代理对象,在代理对象中实现了相应的逻辑处理】,Feign会为每个方法生成相应的RestTemplate,并且封装http请求,里面包括url和请求参数等,最后把RestTemplate交个HttpClient发送请求,它根据服务名找到对应的服务,根据返回值类型、形参列表匹配相应的接口,使用ribbon负载均衡器通过负载均衡算法发起调用。

  • 相关阅读:
    KMS在腾讯云的微服务实践助力其降本50%
    《HelloGitHub》第 88 期
    qt 简单实验 画一个等边三角形
    APP瀑布流分页问题——领取,使用等操作即消失问题
    LVS+Keepalived群集部署
    【自学CSS笔记第10篇】——CSS浮动及清除浮动(此一篇足以)
    Reasoning with Language Model Prompting: A Survey
    2022年最新最详细的MYSQL数据库安装(详细图解过程、毕成功)
    多个rabbitmq配置
    oracle SQL Blob字符串太长,不能写入数据解决
  • 原文地址:https://blog.csdn.net/m0_64210833/article/details/126234926