实习面试:Java达人必知必会(1)

68 阅读3分钟

Spring Bean的加载过程

image-20230927092840201

image-20230927093200197

  1. 初始化Bean:这个步骤主要包括将初始化好的Bean放入Spring的缓存中,并填充预设的属性进行后置处理等操作。
  2. 依赖注入:这个步骤主要是将Bean的所有属性进行依赖注入,即根据配置文件中的信息,将相关的Bean依赖注入到目标Bean中。
  3. 调用BeanNameAware接口:如果Bean实现了BeanNameAware接口,那么在此步骤中,将会调用setBeanName()方法获取xml配置文件中该Bean的id。
  4. 调用BeanFactoryAware接口:如果Bean实现了BeanFactoryAware接口,那么在此步骤中,将会调用setBeanFactory()方法获取实例化该Bean的工厂实例的引用。
  5. 调用ApplicationContext接口:如果Bean实现了ApplicationContext接口,那么在此步骤中,将会调用setApplicationContext()方法获取applicationContext容器实例。
  6. 预初始化:如果Bean实现了BeanPostProcessor接口,那么在此步骤中,将会调用预初始化方法。
  7. 初始化:如果Bean实现了initlizalingBean接口,那么在此步骤中,将会调用初始化方法。
  8. 调用xml中配置的init-method方法:如果有在XML配置文件中定义init-method,那么在这个步骤中将会被调用。
  9. 后初始化:如果Bean实现了BeanPostProcessor接口,那么在此步骤中,将会调用后初始化方法。

SpringBean生命周期

  1. 实例化:当Spring容器启动时,会根据配置文件或者注解等方式来创建Bean的实例。这个阶段完成后,Bean就成为了一个真正的实体。
  2. 属性赋值:在实例化后,Spring会自动为Bean的属性进行注入。这个步骤是根据配置文件或者注解等方式进行的。
  3. 初始化:这个阶段包括了所有的初始化操作,比如对Bean的配置、对Bean的依赖注入等。在这个阶段,可以通过执行一些自定义的初始化方法或者通过AOP来增强Bean的功能。
  4. 使用
  5. 销毁:当容器被销毁时,会执行一些清理工作。例如,释放资源、关闭连接等。

三级缓存

Spring三级缓存是为了解决对象间的循环依赖问题。

A依赖B,B依赖A,这就是一个简单的循环依赖

只能解决单例Bean,因为单例Bean只会创建一次,然后放在缓存中

如果是多例,那么使用时就会重新创建,所以就用不到缓存

循环依赖

img

名称作用
singletonObjects一级缓存,存放完整的 Bean。
earlySingletonObjects二级缓存,存放提前暴露的Bean,Bean 是不完整的,未完成属性注入和执行 初始化(init) 方法。
singletonFactories三级缓存,存放的是 Bean 工厂,主要是生产 Bean,存放到二级缓存中。

为什么要三级缓存

我们创建的bean所依赖的对象是一个需要被Aop代理的对象,怎么办?遇到这种情况,我们肯定不能够直接把创建完成的对象放到缓存中去的!为什么,因为我们期望的注入的是一个被代理后的对象,而不是一个原始对象! 所以这里并不能够直接将一个原始对象放置到缓存中,我们可以直接进行判断,如果需要Aop的话进行代理之后放入缓存!

但是Aop的操作是在哪里做的?是在Spring声明周期的最后一步来做的!如果我们进行判断创建的话,Aop的代理逻辑就会在创建实例的时候就进行Aop的代理了,这明显是不符合Spring对于Bean生命周期的定义的!