Spring的Bean被指定为prototype以及singleton有什么区别

这两者分别指的是多例和单例模式,singleton即单例模式,指对象在整个系统中只存在一份;prototype即多例模式系统中可以有多个实例。

如果一个bean是单例模式的,在处理多次请求的时候,在ioc容器中只实例化一个bean,这个对象会被保存在一个map中,当有请求来的时候,会先从map中查看,如果有就直接使用这个对象,没有才会实例化新的对象。

如果是多例模式的bean,每次请求来的时候,会直接实例化新的bean,没有map缓存的过程。

在spring的ioc容器中的bean默认都是单例的,如果需要使用多例,可以指定scope属性:scope=”prototype”

BeanFactory和ApplicationContext有什么区别

BeanFactory接口是IOC容器的核心接口,定义了管理bean的最基本方法,比如实例化,配置,管理,获取bean的方法

ApplicationContext接口是BeanFactory接口的子接口,除了继承BeanFactory中所有管理bean的方法,还拥有环境、国际化、资源、事件等服务相关的接口

BeanFactory是延迟加载,ApplicationContext是迫切加载

BeanFactory和FactoryBean的区别

BeanFactory接口是IOC容器的核心接口,定义了管理bean的最基本方法,比如实例化,配置,管理,获取bean的方法

FactoryBean是IOC容器创建bean的一种形式,可以通过实现此接口来创建实例化过程比较复杂的bean

IOC容器是如何保证Bean的单例的?

IOC容器会将单例模式的bean放入一个ConcurrentHashMap中,需要这个bean时直接到这个map中获取,如果没有找到才会实例化这个bean。而ConcurrentHashMap本身时线程安全的,也就保证了Bean是单例的

Spring如何解决Bean的循环依赖

循环依赖分为三种,构造器注入循环依赖 ,setter方式注入循环依赖,多例模式Bean的循环依赖。而Spring解决了单例bean的setter注入循环依赖

setter循环依赖的解决主要使用了三级缓存

  • 一级缓存,用来缓存已经实例化好的bean,即单利Bean缓存池
  • 二级缓存,用来缓存正在创建的bean
  • 三级缓存,用来缓存创建bean的实例工厂ObjectFactory

假设有两个bean,A依赖B,B依赖A

当实例化好A,在属性注入环境,发现A依赖了B,会先将正在创建的A的实例工厂ObjectFactory放入三级缓存,然后去创建B的实例。

走Bean的实例化流程创建B,在B的属注入环节发现,B依赖了A,这个时候就会去三级缓存中,找到A的创建工厂ObjectFactory获取A的实例,并注入到B中。此时B就初始化好了,然后将B实例放入一级缓存。最后将B实例注入到A中,A也就创建好了

在getBean的时候,如果单例Bean缓存池没有Bean,就会走二级缓存尝试获取,如果也没有,就会走三级缓存拿到Bean的ObjectFacory创建Bean,然后把Bean放入二级缓存。

Spring构造器注入能循环依赖吗

构造注入不能解决循环依赖的原因是:如果A的构造其中依赖了B B的构造器中又依赖了A 在getSingleton中三级缓存需要调用getObject()构造器,来构造提早暴露但未设置属性的bean,此时就会产生无限递归创建

多例模式下Bean是不做缓存的,所以就没法暴露ObjectFactory,也就没办法解决循环依赖