bean 代指的就是那些被 IoC 容器所管理的对象。

作用域

Spring 中 Bean 的作用域通常有下面几种:

  • singleton : 唯一 bean 实例,Spring 中的 bean 默认都是单例的,对单例设计模式的应用。
  • prototype : 每次请求都会创建一个新的 bean 实例。
  • request : 每一次 HTTP 请求都会产生一个新的 bean,该 bean 仅在当前 HTTP request 内有效。
  • session : 每一次来自新 session 的 HTTP 请求都会产生一个新的 bean,该 bean 仅在当前 HTTP session 内有效。
  • global-session : 全局 session 作用域,仅仅在基于 portlet 的 web 应用中才有意义,Spring5 已经没有了。Portlet 是能够生成语义代码(例如:HTML)片段的小型 Java Web 插件。它们基于 portlet 容器,可以像 servlet 一样处理 HTTP 请求。但是,与 servlet 不同,每个 portlet 都有不同的会话。
    1. <bean id="..." class="..." scope="singleton"></bean>
  1. @Bean
  2. @Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
  3. public Person personPrototype() {
  4. return new Person();
  5. }

生命周期

简单的说: 实例化 -> 属性注入 -> 初始化 -> 销毁
spring除了通过class来记录对象信息,还通过 BeanDefinition 来记录对象信息

SpringBean - 图1

@PostConstruct

这个注解的作用是在项目初始化的时候执行注释的方法,同一类里只有一个方法可以用此注释,方法不能有参数,和返回值,非静态

  1. class A{
  2. @Autowired
  3. private B b;
  4. public A(){
  5. System.out.println("此时B还未被加载 b = "+b);
  6. }
  7. @PostConstruct
  8. public void init(){
  9. System.out.println("此时B已经被加载了 b = "+b);
  10. }
  11. }

执行的顺序为
类内的构造方法 -> @Autowired ->@PostConstruct

循环依赖

过程: 例如A 依赖B ,B也依赖A
A会先实例化,检查到B没有实例化,转头依赖B,等B实例化后,发现需要依赖A,检查到A以及实例化完成,就将B对象返回给A
原理:三级缓存
三个缓存是Map类型,分别为

    • singletonObjects(一级,日常实际获取Bean的地方); 正式对象
  1. :earlySingletonObjects(二级,还没进行属性注入,由三级缓存放进来);
  2. :singletonFactories(三级,Value是一个对象工厂);

在实例化后会把自己放入 三级缓存
依赖注入时,根据依赖将对象从三级缓存中移动 到二级缓存
初始化完成后:二级缓存对象会转移到一级缓存


源码

  • 关键源码⽅法(强烈建议⾃⼰去撸⼀遍)
  • org.springframework.context.support.AbstractApplicationContext#refresh (⼊⼝)
  • org.springframework.context.support.AbstractApplicationContext#finishBeanFactoryIniti alization (初始化单例对象⼊⼝)
  • org.springframework.beans.factory.config.ConfigurableListableBeanFactory#preInstantia teSingletons (初始化单例对象⼊⼝)
  • org.springframework.beans.factory.support.AbstractBeanFactory#getBean(java.lang.Strin g) (万恶之源,获取并创建Bean的⼊⼝)
  • org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean (实际的获取并创 建Bean的实现)
  • org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton(j ava.lang.String) (从缓存中尝试获取)
  • org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBe an(java.lang.String, org.springframework.beans.factory.support.RootBeanDefinition, java.lang.Object[]) (实例化Bean)
  • org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreate Bean (实例化Bean具体实现)
  • org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBe anInstance (具体实例化过程)
  • org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#addSingletonFa ctory (将实例化后的Bean添加到三级缓存)
  • org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populate Bean (实例化后属性注⼊)
  • org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initiali zeBean(java.lang.String, java.lang.Object, org.springframework.beans.factory.support.RootBeanDefinition) (初始化⼊⼝)

    生命周期图

image.png

image.png

Spring三级缓存图.png