目录
题目一:IOC 原理
题目二:IOC 的使用场景?
题目三:IOC 中 Bean 有几种注入方式?
题目四:Spring 的生命周期?(高薪常问)
题目五:Spring 支持 bean 的作用域有几种吗? 每种作用域是什么样的?(必会)
题目六:BeanFactory 和 ApplicationContext 有什么区别(了解)
题目七:介绍一下Spring bean 的生命周期、注入方式和作用域
题目八:请写出 spring 中常用的依赖注入方式。
题目九:简述Spring中IOC容器常用的接口和具体的实现类
题目十:请解释Spring Bean的生命周期?
题目十一:简述Spring 中bean的作用域
题目十二:IOC容器的初始化过程
题目十三:Spring 提供了多种依赖注入的方式
题目十四:Spring中,如何给对象的属性赋值?
题目十五:bean对象创建的细节(动力节点)
题目十六:Bean的生命周期(动力节点)
题目十七:Bean的作用域(动力节点)
题目一:IOC 原理
解析流程:
SpringBean new A()
根据路径、资源名称等方式,将
xml
文件、注解类加载到容器中
通过
BeanDefinitionReader
将对象解析成
BeanDefinition
实例
创建
BeanFactory
工厂
(
注册前后需要添加
bean
前置、后置处理器
)
通过
BeanFactory
工厂将对象实例化、对象初始化
(
初始化前后执行前置、后置处理
器
)
总结以上步骤,核心主干主要就是五部分构成:
1.
构造
Bean
对象
2.
设置
Bean
属性
3.
初始化回调
4. Bean
调用
5.
销毁
Bean
题目二:IOC 的使用场景?
正常情况下我们使用一个对象时都是需要
new Object()
的。而
ioc
是把需要使用的
对象提前创建好,放到
spring
的容器里面。需要使用的时候直接使用就行,而且可
以设置单例或多例,非常灵活。
我们在
service
层想调用另外一个
service
的方法,不需要去
new
了,直接把它交给
spring
管理,然后用注解的方式引入就能使用。
•
通过
XML
配置实例化
Bean
,将
bean
的信息配置
.xml
文件里,通过
Spring
加载
文件为我们创建
bean
和配置
bean
属性
•
通过注
解声明配置
通过在类上加注解的方式,来声明一个类交给
Spring
管理,
Spring
会自动扫描带有
@Component
,
@Controller
,
@Service
,
@Repository
这
四个注解的类,然后帮我们创建并管理,前提是需要先配置
Spring
的注解扫描
器。
–@Component
:可以用于注册所有
bean
–@Repository
:主要用于注册
dao
层的
bean
–@Controller
:主要用于注册控制层的
bean
–@Service
:主要用于注册服务层的
bean
•
通过
配置类
将类的创建交给我们配置的
JavcConfig
类来完成,
Spring
只负责维
护和管理创建一个配置类
–
添加
@Configuration
注解声明为配置类
–
方法上加上
@bean
,该方法用于创建实例并返回
题目三:IOC 中 Bean 有几种注入方式?
•
构造器依赖注入
:构造器依赖注入通过容器触发一个类的构造器来实现的,该
类有一系列参数,每个参数代表一个对其他类的依赖。
•
Setter
方法注入
:
Setter
方法注入是容器通过调用无参构造器或无参
static
工
厂方法实例化
bean
之后,调用该
bean
的
Setter
方法,即实现了基于
Setter
的依赖注入。
•
基于注解的注入
:最好的解决方案是用构造器参数实现强制依赖,
Setter
方法
实现可选依赖。
题目四:Spring 的生命周期?(高薪常问)
1. 实例化一个 Bean,也就是我们通常说的 new
2. 按照 Spring 上下文对实例化的 Bean 进行配置,也就是 IOC 注入
3. 如果这个 Bean 实现 dao 了 BeanNameAware 接口,会调用它实现的
setBeanName(String beanId)方法,此处传递的是 Spring 配置文件中 Bean 的 ID
4. 如果这个 Bean 实现了 BeanFactoryAware 接口,会调用它实现的 setBeanFactory(),
传递的是 Spring 工厂本身(可以用这个方法获取到其他 Bean)
5. 如果这个 Bean 实现了 ApplicationContextAware 接口,会调用
setApplicationContext(ApplicationContext)方法,传入 Spring 上下文,该方式同样可
以实现步骤 4,但比 4 更好,以为 ApplicationContext 是 BeanFactory 的子接口,有更多
的实现方法
6. 如果这个 Bean 关联了 BeanPostProcessor 接口,将会调用
postProcessBeforeInitialization(Object obj, String s)方法,BeanPostProcessor 经常被
用作是 Bean 内容的更改,并且由于这个是在 Bean 初始化结束时调用 After 方法,也可用
于内存或缓存技术
7. 如果这个 Bean在 Spring 配置文件中配置了 init-method 属性会自动调用其配置的初始
化方法
8. 如果这个 Bean 关联了 BeanPostProcessor 接口,将会调用
postAfterInitialization(Object obj, String s)方法
注意:以上工作完成以后就可以用这个 Bean 了,那这个 Bean 是一个 single 的,所以
一般情况下我们调用同一个 ID 的 Bean 会是在内容地址相同的实例
9. 当 Bean 不再需要时,会经过清理阶段,如果 Bean 实现了 DisposableBean 接口,会
调用其实现的 destroy 方法
10. 最后,如果这个 Bean 的 Spring 配置中配置了 destroy-method 属性,会自动调用其
配置的销毁方法
题目五:Spring 支持 bean 的作用域有几种吗? 每种作用域是什么样的?(必会)
Spring 支持如下 5 种作用域:
(1)singleton:默认作用域,单例 bean,每个容器中只有一个 bean 的实例。
(2)prototype:每次请求都会为 bean 创建实例。
(3)request:为每一个 request 请求创建一个实例,在请求完成以后,bean 会失效
并被垃圾回收器回收。
(4)session:与 request 范围类似,同一个 session 会话共享一个实例,不同会话
使用不同的实例。
(5)global-session:全局作用域,所有会话共享一个实例。如果想要声明让所有会
话共享的存储变量的话,那么这全局变量需要存储在 global-session 中。
题目六:BeanFactory 和 ApplicationContext 有什么区别(了解)
BeanFactory:
Spring 最顶层的接口,实现了 Spring 容器的最基础的一些功能, 调用起来比较麻烦, 一般面向 Spring 自身使用
BeanFactory 在启动的时候不会去实例化 Bean,从容器中拿 Bean 的时候才会去 实例化
ApplicationContext:
是 BeanFactory 的子接口,扩展了其功能, 一般面向程序员身使用
ApplicationContext 在启动的时候就把所有的 Bean 全部实例化了
题目七:介绍一下Spring bean 的生命周期、注入方式和作用域
(1)默认情况下,IOC容器中bean的生命周期分为五个阶段:
- 调用构造器 或者是通过工厂的方式创建Bean对象
- 给bean对象的属性注入值
- 调用初始化方法,进行初始化, 初始化方法是通过init-method来指定的.
- IOC容器关闭时, 销毁Bean对象.
(2)当加入了Bean的后置处理器后,IOC容器中bean的生命周期分为七个阶段:
- 调用构造器 或者是通过工厂的方式创建Bean对象
- 给bean对象的属性注入值
- 执行Bean后置处理器中的 postProcessBeforeInitialization
- 调用初始化方法,进行初始化, 初始化方法是通过init-method来指定的.
- 执行Bean的后置处理器中 postProcessAfterInitialization使用
- IOC容器关闭时, 销毁Bean对象
注入方式:
通过 setter 方法注入
通过构造方法注入
Bean的作用域
总共有四种作用域:
- Singleton 单例的
- Prototype 原型的
- Request
- Session
题目八:请写出 spring 中常用的依赖注入方式。
通过 setter 方法注入
通过构造方法注入
题目九:简述Spring中IOC容器常用的接口和具体的实现类
- BeanFactory SpringIOC容器的基本设置,是最底层的实现, 面向框架本身的.
- ApplicationContext BeanFactory的子接口, 提供了更多高级的特定. 面向开发者的.
- ConfigurableApplicationContext, ApplicationContext的子接口,扩展出了 close 和 refresh等 关闭 刷新容器的方法
- ClassPathXmlApplicationContext:从classpath的XML配置文件中读取上下文,并生成上下文定义。应用程序上下文从程序环境变量中取得。
- FileSystemXmlApplicationContext :由文件系统中的XML配置文件读取上下文。
- XmlWebApplicationContext:由Web应用的XML文件读取上下文。
题目十:请解释Spring Bean的生命周期?
(1)默认情况下,IOC容器中bean的生命周期分为五个阶段:
- 调用构造器 或者是通过工厂的方式创建Bean对象
- 给bean对象的属性注入值
- 调用初始化方法,进行初始化, 初始化方法是通过init-method来指定的.
- 使用
- IOC容器关闭时, 销毁Bean对象.
(2)当加入了Bean的后置处理器后,IOC容器中bean的生命周期分为七个阶段:
- 调用构造器 或者是通过工厂的方式创建Bean对象
- 给bean对象的属性注入值
- 执行Bean后置处理器中的 postProcessBeforeInitialization
- 调用初始化方法,进行初始化, 初始化方法是通过init-method来指定的.
- 执行Bean的后置处理器中 postProcessAfterInitialization
- 使用
- IOC容器关闭时, 销毁Bean对象
题目十一:简述Spring 中bean的作用域
总共有四种作用域:
- Singleton 单例的
- Prototype 原型的
- Request
- Session
题目十二:IOC容器的初始化过程
IOC容器的初始化主要包括Resource定位,载入和注册三个步骤,接下来我们依次介绍。
Resource资源定位:
Resouce定位是指BeanDefinition的资源定位,也就是IOC容器找数据的过程。Spring中使用外部资源来描述一个Bean对象,IOC容器第一步就是需要定位Resource外部资源。由ResourceLoader通过统一的Resource接口来完成定位。
BeanDefinition的载入:
载入过程就是把定义好的Bean表示成IOC容器内部的数据结构,即BeanDefinition。在配置文件中每一个Bean都对应着一个BeanDefinition对象。
通过BeanDefinitionReader读取,解析Resource定位的资源,将用户定义好的Bean表示成IOC容器的内部数据结构BeanDefinition。
在IOC容器内部维护着一个BeanDefinitionMap的数据结构,通过BeanDefinitionMap,IOC容器可以对Bean进行更好的管理。
BeanDefinition的注册:
注册是将前面的BeanDefition保存到Map中的过程,通过BeanDefinitionRegistry接口来实现注册。
题目十三:Spring 提供了多种依赖注入的方式
Set 注入
构造器注入
接口注入
注解注入
Spring启动时读取应用程序提供的Bean 配置信息,并在Spring 容器中生成一份相应的Bean 配置注册表,然后根据这张注册表实例化Bean,装配好Bean 之间的依赖关系,为上层应用提供准备就绪的运行环境。其中Bean 缓存池为HashMap 实现
题目十四:Spring中,如何给对象的属性赋值?
1. 通过构造函数
2. 通过set方法给属性注入值
3. 自动装配
byName 通过参数名自动装配,如果一个bean的name 和另外一个bean的 property 相同就自动装配。
byType 通过参数的数据类型自动自动装配,如果一个bean的数据类型和另 外一个bean的property属性的数据类型兼容,就自动装配必须确保 该类型在IOC容器中只有一个对象;否则报错。
题目十五:bean对象创建的细节(动力节点)
1) 对象创建: 单例/多例
scope="singleton", 默认值, 即 默认是单例 【service/dao/工具类】
scope="prototype", 多例; 【Action对象】
Spring的单例bean不是线程安全的(可以用局部变量使线程安全)
2) 什么时候创建?
scope="prototype" 在用到对象的时候,才创建对象。
scope="singleton" 在启动(容器初始化之前), 就已经创建了bean,且整个应用只有一个。
3)是否延迟创建
lazy-init="false" 默认为false, 不延迟创建,即在启动时候就创建对象
lazy-init="true" 延迟初始化, 在用到对象的时候才创建对象(只对单例有效)
4) 创建对象之后,初始化/销毁
init-method="init_user" 【对应对象的init_user方法,对象创建之后执行】 destroy-method="destroy_user" 【在调用容器对象的destriy方法时候执行,(容器用实现类)】
题目十六:Bean的生命周期(动力节点)
Bean 容器找到配置文件中 Spring Bean 的定义。
Bean 容器利用 Java Reflection API 创建一个Bean的实例。
如果涉及到一些属性值利用 set()方法设置一些属性值。
如果 Bean 实现了 BeanNameAware 接口,调用 setBeanName()方法,传入Bean的名字。
如果 Bean 实现了 BeanClassLoaderAware 接口,调用 setBeanClassLoader()方法,传入 ClassLoader对象的实例。
与上面的类似,如果实现了其他 *.Aware接口,就调用相应的方法。
如果有和加载这个 Bean 的 Spring 容器相关的 BeanPostProcessor 对象,执行postProcessBeforeInitialization() 方法
如果Bean实现了InitializingBean接口,执行afterPropertiesSet()方法。
如果 Bean 在配置文件中的定义包含 init-method 属性,执行指定的方法。
如果有和加载这个 Bean的 Spring 容器相关的 BeanPostProcessor 对象,执行postProcessAfterInitialization() 方法
当要销毁 Bean 的时候,如果 Bean 实现了 DisposableBean 接口,执行 destroy() 方法。
当要销毁 Bean 的时候,如果 Bean 在配置文件中的定义包含 destroy-method 属性,执行指定的方法。
题目十七:Bean的作用域(动力节点)
singleton : 唯一 bean 实例,Spring 中的 bean 默认都是单例的。
prototype : 每次请求都会创建一个新的 bean 实例。
request : 每一次HTTP请求都会产生一个新的bean,该bean仅在当前HTTP request内有效。
session : 每一次HTTP请求都会产生一个新的 bean,该bean仅在当前 HTTP session 内有效。
global-session: 全局session作用域,仅仅在基于portlet的web应用中才有意义,Spring5 已经没有了。Portlet是能够生成语义代码(例如:HTML)片段的小型Java Web插件。它们基于 portlet容器,可以像servlet一样处理HTTP请求。但是,与 servlet 不同,每个 portlet 都 有不同的会话