Spring依赖注入、循环依赖——三级缓存

依赖注入

背景:

实例化对象后,需要设置字段,即依赖注入,两种:set方法注入和构造方法注入。

 

流程:

先寻找整个类的注入点,就是打了@autowired的字段或方法,然后根据类型、名称去找

 

常用依赖注入注解辨析:

  • @Inject:来自JSR 330规范。按类型注入。
  • @Resource:是Java EE的一部分。先按名字注入,再按类型注入。
  • @Autowired来自spring。按类型注入,再按名字注入。
  • @Qualifier来自spring。与@autowored一起用,指定如果类型相同,需要注入的类名。
  •  

循环依赖——三级缓存

背景:

a类有b,b类有a。

a实例化,注入b,发现beanMap中没有b,开始生成b,b实例化,注入a,发现beanMap中没有a,所以生成a,生成a需要b,生成b又需要a,所以就无限循环了。

 

解决措施:

a实例化后,就放入map中,这样b就能获取到a了,b就能生成了,就能注入a,a就能接着生成了。但这有个问题,a如果有aop,则a是代理对象,但b中的a是被代理对象。所以就要三级缓存。

 

流程:

1、a实例化后,放入三级缓存map(singletonFactories),注入b,发现没有b

2、需要生成b,实例化b,注入a,从singletonFactories中获取,会执行a中lambda的方法得到a或a的代理对象(如果a有aop,则该方法会返回a代理对象,否则就返回它自己,并把代理对象或者a放入二级缓存map(earlySingletonObjects)中,如果有aop还会放入earlyProxyReferences中记录下),b注入a或a的代理对象,b初始化,b创建好

3、a注入b,a继续生命周期,a初始化,a进行或不进行aop(如果earlyProxyReferences中有a,则说明已经进行了aop就无需进行,否则需要进行aop),把a放入一级缓存(singletonObjects)

 

三级缓存:

一级singletonObjects:放完整生命周期的bean

二级earlySingletonObjects:放未经过完整生命周期的bean。

三级singletonFactories:放lambda表达式。

 

加了3级缓存流程是这样:

a需要注入b,从一级缓存中找b,有就直接获取,没有发现则从二级缓存中找b,找到就返回给a,没有发现,则从三级缓存中调用lambda获取,找到就返回给a,没找到就创建b。

 

JSR

JCP(Java Community Process,Java社区进程)是Java社区的一个重要组织,负责Java技术的标准化工作。JSR(Java Specification Request)是jcp的一个提案。

JSR 330(Java Specification Request 330)是Java社区提出的一个规范,全称为“Dependency Injection for Java”,即Java的依赖注入规范。这个规范主要是为了提供一种标准化的方式来进行依赖注入,以提高代码的可重用性、可测试性和可维护性。

JSR 330,定义了一系列用于依赖注入的注解,如@Inject@Scope@Named等。

  • @Inject:按类型注入。用于标记需要依赖注入的字段、构造方法或方法。
  • @Scope:用于指定bean的作用域,如单例(Singleton)、原型(Prototype)等。不过,需要注意的是,JSR 330的@Scope注解主要用于定义自定义作用域,而具体的作用域实现则依赖于DI框架。
  • @Named:用于为bean提供一个名称,以便在按名称进行注入时使用。类似于Spring的@Qualifier

与Spring的集成

  • 从Spring 3.0开始,Spring框架就支持JSR 330规范中的注解。这意味着开发者可以在Spring应用中使用@Inject等JSR 330注解来进行依赖注入。不过,需要注意的是,虽然Spring支持JSR 330注解,但它也提供了自己的一套注解(如@Autowired@Component@Scope等),这些注解在功能上可能与JSR 330注解有所重叠,但在某些方面可能提供了更多的灵活性和功能。

 

 

相关推荐

  1. Spring依赖注入循环依赖——三级缓存

    2024-07-12 07:34:05       31 阅读
  2. Spring 依赖注入

    2024-07-12 07:34:05       29 阅读
  3. Spring依赖注入

    2024-07-12 07:34:05       32 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-12 07:34:05       67 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-12 07:34:05       71 阅读
  3. 在Django里面运行非项目文件

    2024-07-12 07:34:05       58 阅读
  4. Python语言-面向对象

    2024-07-12 07:34:05       69 阅读

热门阅读

  1. 【WPF】Enum与Converter的使用

    2024-07-12 07:34:05       25 阅读
  2. 【CH32V305FBP6】USBD 初始化分析

    2024-07-12 07:34:05       26 阅读
  3. Ansible的Playbook

    2024-07-12 07:34:05       24 阅读
  4. Ansible

    2024-07-12 07:34:05       22 阅读
  5. RabbitMQ保证消息被成功发送和消费

    2024-07-12 07:34:05       23 阅读
  6. Python实现一对多WebSocket发送给指定多个客户端

    2024-07-12 07:34:05       26 阅读
  7. React 18 + Babel 7 + Webpack 5 开发环境搭建

    2024-07-12 07:34:05       27 阅读
  8. flutter常用库的介绍(1)

    2024-07-12 07:34:05       31 阅读
  9. 用Python和TensorFlow实现图像分类:从零开始

    2024-07-12 07:34:05       28 阅读