动态代理与Spring Aop

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


动态代理

  1. JDK 动态代理 使用JAVA反射包中的类和接口实现动态代理的功能,JAVA.lang.reflect包;主要是三个类:

InvocationHandler,Method,Proxy;

  1. CGLIB动态代理,第三方工具类库,创建代理对象,cglib的原理是继承,通过继承目标类,创建它的子类,在子类中重写父类中同名的方法,实现功能的修改

    注意:cglib是继承,重写方法,所以要求目标类不能是final修饰的,方法也不能是final的,cglib的要求目标类比较宽松,只要继承就可以了,cglib在很多的框架中使用,比如mybatis,spring框架中都有使用

JDK动态代理

  1. Method类表示方法,目标类的方法;通过Method可以执行某个目标类的方法 Method.invoke();

  2. InvocationHandler接口(调用处理器) 就一个方法Invoke方法

public Object invoke(Object proxy, Method method, Object[] args)
 throws Throwable;
  1. Proxy类:核心的对象 创建代理对象

    @param ClassLoader 目标类加载器 getClass().getClassLo ader()

    @param interfaces 接口 目标类实现的接口 也是反射获取的

    @param InvocationHandler 代理类要完成的功能 我们自己写的

    @return 目标对象的代理对象

public static Object newProxyInstance(ClassLoader loader,
                                   Class<?>[] interfaces,
                                   InvocationHandler h){}

AOP

动态代理与Spring Aop
动态代理与Spring Aop


Spring三级循环依赖

三级缓存是如何避免循环依赖

动态代理与Spring Aop


@Autowired(类型注入),@Resource(名称注入) 注解依赖注入如何避免循环依赖

如果存在循环依赖,即 Bean A 依赖于 Bean B,而 Bean B 又依赖于 Bean A,则 Spring 会先创建 Bean A,并将其注入到 Bean B 中的代理对象中,然后再创建 Bean B,并将代理对象注入到 Bean A 中。代理对象可以避免循环依赖问题,因为它并不是完整的 Bean 实例,而是一个动态生成的代理对象,只有在真正需要使用 Bean 实例时才会触发创建。


AOP过程中生成的代理对象是谁管理的

AOP 产生的代理对象实际上是 Bean 实例的一种,因此代理对象会被放到 IOC 容器中管理。但是,代理对象并不是通过三级缓存来管理的,而是通过 BeanPostProcessor 接口来创建和管理

**BeanPostProcessor 接口是 Spring 中非常重要的接口之一,**它定义了在 Bean 创建过程中的两个回调方法:postProcessBeforeInitialization() 和 postProcessAfterInitialization()。在 Bean 创建过程中,当 Spring 创建一个 Bean 实例后,会先调用 postProcessBeforeInitialization() 方法,然后再调用 postProcessAfterInitialization() 方法。


代理对象直接替换掉原来的bean吗

在 Spring 中,AOP 产生的代理对象是通过 BeanPostProcessor 接口来创建和管理的。当 Spring 创建一个 Bean 实例时,如果该 Bean 需要使用 AOP,会先创建一个代理对象,然后将代理对象注入到 Bean 实例中。

具体来说,代理对象的注入过程分为以下几个步骤:

  1. Spring 通过 BeanPostProcessor 接口的 postProcessAfterInitialization() 方法创建代理对象。
  2. Spring 将代理对象作为参数传递给 postProcessAfterInitialization() 方法,同时也会将 Bean 的名称和类型等信息传递给该方法。
  3. 在 postProcessAfterInitialization() 方法中,如果需要创建代理对象,则可以使用 Spring 提供的 AOP API(例如 ProxyFactoryBean)来创建代理对象,并将其注入到 Bean 实例中。
  4. Spring 将代理对象注入到 Bean 实例中,替换原来的 Bean 实例。

原来的 Bean 实例已经完成了所有的初始化工作(包括属性注入、生命周期回调等),而代理对象则是在这个基础上进行的增强。因此,在使用 AOP 时,需要确保代理对象的增强不会影响到 Bean 实例的初始化和生命周期回调等操作


Bean容器与三级缓存容器的相关

Bean 实例是按照名称或类型进行管理的。

存放 Bean 的容器和三级缓存的三个容器虽然都是 Map 集合,但是它们的作用和管理方式是不同的。存放 Bean 的容器是用于管理所有 Bean 实例的,它负责创建和管理 Bean 实例,并将 Bean 实例按照名称或类型进行分类和管理。而三级缓存则是用于解决循环依赖问题的,它只在出现循环依赖时才会被使用。

在 Spring 中,存放 Bean 的容器和三级缓存的三个容器之间的关系可以简单描述如下:

  1. 当 Spring 创建一个 Bean 实例时,首先会检查该 Bean 实例是否已经被创建。如果该 Bean 实例已经被创建,则直接从存放 Bean 的容器中获取该 Bean 实例,否则进入下一步。
  2. 如果该 Bean 实例还未被创建,则会检查该 Bean 实例是否处于循环依赖中。如果该 Bean 实例处于循环依赖中,则会将该 Bean 实例放入三级缓存中的第一个 Map 集合中,否则进入下一步。
  3. 如果该 Bean 实例既不处于循环依赖中,也没有被创建过,则会创建该 Bean 实例,并将其放入存放 Bean 的容器中进行管理。

三级缓存解决了循环依赖之后,会生成bean实例

总之,在 Spring 中,三级缓存最终会生成 Bean 实例。当一个 Bean 实例处于循环依赖中时,Spring 会将其放入三级缓存中的第一级缓存中,并在后续的处理中逐步生成该 Bean 实例。三级缓存中的 Bean 实例是按照依赖关系顺序进行创建的,并最终被放入存放 Bean 的容器中进行管理。需要注意的是,不是所有的 Bean 实例都会进入三级缓存中,只有处于循环依赖中的 Bean 实例才会进入三级缓存。


可以理解为三级缓存只是暂时的缓存bean示例工具,最后解决完依赖注入之后,将bean放回到bean容器中

三级缓存只是 Spring 中用于解决循环依赖问题的一个临时工具,它并不是用来管理所有的 Bean 实例的。当 Spring 创建 Bean 实例时,如果发现该 Bean 实例处于循环依赖中,就会将该 Bean 实例放入三级缓存中,在后续处理中逐步生成该 Bean 实例。当所有的 Bean 实例都创建完成后,Spring 会将它们放入存放 Bean 的容器中进行管理。

需要注意的是,三级缓存只是一个暂时的缓存工具,它并不是用来管理 Bean 实例的长期存储工具。一旦 Bean 实例被创建成功并放入存放 Bean 的容器中进行管理,它们就不再需要被存储在三级缓存中了。因此,在 Spring 中,三级缓存只是一个用于解决循环依赖问题的辅助工具,其生命周期和作用范围是有限的。


Bean容器

Bean 容器的构造实际上是由 ApplicationContext 接口的实现类来完成的。ApplicationContext 接口是 Spring 中应用上下文的核心接口,它继承了 BeanFactory 接口,提供了更多的功能,例如国际化支持、事件传播、应用上下文层次结构等

ApplicationContext 接口的实现类的构造过程一般包括以下几个步骤:

  1. 解析配置文件:ApplicationContext 接口的实现类需要解析配置文件,将配置文件中定义的 Bean 实例信息解析成相应的 Java 对象,例如 BeanDefinition 对象等。

  2. 创建 Bean 实例:ApplicationContext 接口的实现类需要根据配置文件中定义的 Bean 实例信息,创建相应的 Bean 实例。这个过程一般包括 Bean 实例化、属性注入、生命周期回调等步骤。

  3. 注册 Bean 实例:ApplicationContext 接口的实现类需要将创建好的 Bean 实例注册到 Bean 容器中。在注册 Bean 实例时,需要将 Bean 实例按照名称或类型进行分类和管理。

  4. 处理 Bean 实例之间的依赖关系:ApplicationContext 接口的实现类需要处理 Bean 实例之间的依赖关系。这个过程一般包括解析依赖关系、查找依赖对象、注入依赖对象等步骤。

  5. 初始化容器:ApplicationContext 接口的实现类需要初始化容器,包括初始化事件监听器、初始化 AOP 相关的对象、初始化国际化相关的对象等。

  6. 启动容器:ApplicationContext 接口的实现类需要启动容器,使得容器能够开始工作。在启动容器时,需要完成容器的预处理、事件监听器的注册、AOP 代理的生成等步骤。

ApplicationContext 接口的实现类可以有多种方式来完成 Bean 容器的构造。例如,ClassPathXmlApplicationContext 类可以使用 XML 配置文件来构造 Bean 容器;AnnotationConfigApplicationContext 类可以使用 Java 配置类来构造 Bean 容器;WebApplicationContext 接口的实现类可以在 Web 应用程序中构造 Bean 容器等。不同的实现方式可能会有一些细节上的差异,但是它们的基本构造过程都是类似的。


IOC

spring的IOC是通过什么实现的?

pring中IOC的实现主要是由BeanFactoryApplicationContext这两个核心接口以及它们的多个实现类来完成的。

  • BeanFactory是IOC容器的基础接口,提供了最基本的IOC功能,例如根据名称或类型获取bean等。
  • ApplicationContextBeanFactory的基础上增加了更多的企业级功能,例如国际化支持、事件驱动、AOP等。它是Spring应用程序中使用最广泛的容器。

在具体实现上,Spring IOC的核心代码在spring-core模块中,其中通过XmlBeanDefinitionReader等类对XML配置文件进行解析,并将解析结果存储在BeanDefinition对象中,然后将BeanDefinition对象注册到IOC容器中。当应用程序需要访问某个bean时,IOC容器根据BeanDefinition信息创建相应的bean并返回给应用程序。

除了XML配置方式外,Spring还支持注解和Java配置方式来定义bean,从而更加灵活地满足不同场景下的需求。文章来源地址https://www.toymoban.com/news/detail-501569.html

到了这里,关于动态代理与Spring Aop的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • spring的aop动态代理对象注入时机

    bean生命周期: bean实例化 populateBean填充属性 invokeAwareMethods调用aware方法 postProcessBeforeInitialization后置处理器before方法 initializeBean初始化bean postProcessAfterAfterInitialization后置处理器after方法 代理对象注入有两种情况:提前和非提前生成代理对象 1. 非提前生成代理对象 依赖于bea

    2024年02月12日
    浏览(22)
  • Spring AOP 学习(动态代理、JdbcTemplate、Junit)

    Proxy  jdk动态代理,面向接口 cglib   第三方动态代理,面向父类 在 不修改原有代码 ,或者没有办法修改原有代码的情况下, 增强对象功能 ,使用代理对象代替原来的对象去完成功能,进而达到拓展功能的目的 JDK Proxy 动态代理是 面向接口 的动态代理,一定要有接口和实现

    2024年02月08日
    浏览(17)
  • JDK 动态代理(Spring AOP 的原理)(面试重点)

            也叫委托模式.定义:为其他对象提供⼀种代理以控制对这个对象的访问.它的作⽤就是通过提供⼀个代理类,让我们 在调⽤⽬标⽅法的时候,不再是直接对⽬标⽅法进⾏调⽤,⽽是通过代理类间接调⽤,在某些情况下,⼀个对象不适合或者不能直接引⽤另⼀个对象,⽽代

    2024年01月22日
    浏览(21)
  • 54.Spring的AOP是在哪里创建的动态代理?

    正常的Bean会在Bean的生命周期的‘初始化’后, 通过BeanPostProcessor.postProcessAfterInitialization创建aop的动态代理 还有一种特殊情况: 循环依赖的Bean会在Bean的生命周期‘属性注入’时存在的循环依赖的情况下, 也会为循环依赖的Bean 通过MergedBeanDefinitionPostProcessor.postProcessMergedBe

    2024年02月02日
    浏览(16)
  • spring动态代理失效,AOP失效,事务@Transactional失效原因

    事务基于@Transactional注解和AOP(动态代理) 对于基于接口动态代理的 AOP 事务增强来说,由于接口的方法都必然是 public 的,这就要求实现类的实现方法也必须是 public 的(不能是 protected、private 等),同时不能使用 static 的修饰符。所以,可以实施接口动态代理的方法只能是

    2024年02月15日
    浏览(21)
  • Java反射机制,动态代理,hook以及在Retrofit源码中的应用

    1.反射的基础知识: Java的反射机制是指在程序的运行状态中,可以构造任意一个类的对象,可以了解任意一个对象所属的类,可以了解任意一个类的成员变量和方法,可以调用任意一个对象的属性和方法。这种动态获取程序信息以及动态调用对象的功能称为Java语言的反射机

    2024年02月13日
    浏览(18)
  • Spring5系列学习文章分享---第三篇(AOP概念+原理+动态代理+术语+Aspect+操作案例(注解与配置方式))

    开篇: 欢迎再次来到 Spring 5 学习系列!在这个博客中,我们将深入研究 Spring 框架的AOP概念+原理+动态代理+术语+Aspect+操作案例(注解与配置方式)。 概念 什么是AOP (1)面向切面编程(方面),利用 AOP 可以对业务逻辑的各个部分进行隔离,从而使得 业务逻辑各部分之间的

    2024年01月24日
    浏览(27)
  • Spring 使用注解开发、代理模式、AOP

    在Spring4之后,要使用注解开发,必须要保证AOP的包导入了 项目搭建: 在配置文件中导入约束,增加注解支持 bean 实体类 @Component 注解 xml配置 测试: 属性如何注入 衍生的注解 @Component 有几个衍生的注解,我们在web开发中,会按照MVC三层架构分层 dao层: @Repository 等价于poj

    2024年02月13日
    浏览(21)
  • spring boot 使用AOP+自定义注解+反射实现操作日志记录修改前数据和修改后对比数据,并保存至日志表

    使用FieldMeta自定义注解,看个人业务自行觉得是否需要重新定义实体 实现类 :通过该实现类获取更新前后的数据。 该实现类的实现原理为:获取入参出入的id值,获取sqlSessionFactory,通过sqlSessionFactory获取selectByPrimaryKey()该方法,执行该方法可获取id对应数据更新操作前后的数

    2024年01月23日
    浏览(30)
  • Java动态代理、反射

    动态代理就是无侵入式的给代码增加新的功能,通过接口保证后面的对象和代理需要实现同一个接口,接口中就是被代理的所有方法,代理里面就是对象要被代理的方法。 因为一个对象觉得自己身上的功能太多,就会将一部分功能代理出去,对象中什么方法想要被代理,在代

    2024年02月11日
    浏览(21)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包