Skip to content
鼓励作者:欢迎打赏犒劳

Spring

bean的生命周期

  1. 实例化bean:反射的方式生成对象
  2. 填充bean的属性
  3. 进行初始化操作,判断是否实现了initializingBean接口或者@PostConstruct
  4. 销毁流程:调用destroyMethod方法

IOC 控制反转

在传统程序中,对象A如果想使用对象B,需要自己在内部new B()。对象的创建和依赖的控制权在程序自身手中。 IoC将它反过来。程序不再主动创建依赖对象,而是被动接收一个已经创建好的对象。

其实ioc就是一个概念,那么实现这个概念的技术方案就是用到了di依赖注入

核心:DI - 依赖注入 (Dependency Injection)

实现IoC思想最常用的技术手段。由容器将依赖的对象注入到需要它的组件中(通过构造函数、setter等)

AOP - 面向切面编程

设置一个方法为切面,然后可以增加前置和后置通知。比如接口的日志打印入参和出参的数据就可以用到aop

@Autowired和@Resource区别

来源不同

  • @Autowired 是 Spring 框架提供的注解。 需要搭配@Qualifier解决别名问题
  • @Resource 是 Java 提供的注解,来自于 JSR-250 规范。

依赖查找顺序不同

  • @Autowired 先根据类型(byType)查找,如果存在多个 Bean 再根据名称(byName)进行查找。
  • @Resource 先根据名称(byName)查找,如果找不到,再根据类型(byType)进行查找。

支持的参数不同

  • @Autowired 只支持一个参数:required,用于指定是否必须注入。
  • @Resource 支持多个参数,如 name 和 type,可以更灵活地指定注入的 Bean。

spring如何解决循环依赖

核心解决方案:三级缓存

Spring解决循环依赖的核心机制是三级缓存。这三级缓存分别存储在 DefaultListableBeanFactory 的父类 DefaultSingletonBeanRegistry 中。

java
// 三级缓存 Map
/** 一级缓存:存放已经完全初始化好的、成熟的Bean */
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);

/** 二级缓存:存放早期的、不完整的Bean对象(仅实例化,还未填充属性) */
private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap<>(16);

/** 三级缓存:存放Bean工厂对象(ObjectFactory),用于生成早期暴露的Bean */
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);

当 A 依赖 B 时,会先去一级缓存找 B,没有就去二级找,没有就创建 B 的实例。 在创建过程中,如果发现 B 又依赖 A,同样的流程,先去一级找 A,这时 A 虽然是半成品,但也能从二级缓存取到, 把 A 注入给 B,B 创建好后再注入到 A,这样就解决了循环依赖。

三级缓存的核心职责:是解决bean的apo代理的特殊情况,比如说A依赖B,但是B是是一个aop的对象,那其实上应该 返回的是B的代理对象,这个时候就需要a和b都初始化之后,再从三级缓存中得到ObjectFactory,来生成aop对象。 这是一种延迟思想。

如有转载或 CV 的请标注本站原文地址