注意我的 Spring 版本是 5.1.2.RELEASE, 并且主要使用注解配置. 如果你需要使用 xml 配置, 我想这篇文章应该不适合你.
IoC容器
IoC就是控制反转, 也叫依赖注入(DI).
比如, 我们现在有 A B 两个类, A 类依赖 B 类在容器在创建 Bean(对象) 的时候, 会注入这些依赖也就是将 B 对象注入到 A 对象中.
依赖注入方式
构造方法注入
private TestService testService;
@Autowired
public ScsController(TestService testService){
this.testService = testService;
}
通过属性注入
@Autowired
private TestService testService;
不管是根据构造方法注入还是通过属性注入 @Autowired
注解都是必不可少的. @Autowired
注解默认是按照类型进行注入的, 如果没有出现指定类型 Bean 时(TestService Bean) 测可以设置 required=false
表示在用到的时候进行注入.
有些情况下我们可能需要名称进行注入, 可以配合 @Qualifier
注解一起使用.
@Autowired
@Qualifier("testService")
private TestService testService;
Bean
在 Spring 中, bean 是一个由 Spring IoC 容器实例化, 组装和管理的对象.
容器帮我们管理的 Bean 都表示一个 BeanDefinition
对象, 这个对象的主要作用就是帮我们来描述 Bean 的 class 类型、构造函数参数列表、scope、属性、依赖项等等. 当容器注册 Bean 的时候就会使用 BeanDefinitionRegistry
来帮我们进行注册; 当我们如果要从容器中获取一个 Bean 时, 则需要使用 BeanFactory
.
也就是说 BeanDefinition
就是用来描述 Bean, BeanDefinitionRegistry
用来注册和管理BeanDefinition
, BeanFactory
用来管理 Bean.
要注意的是 BeanFactory
采用延迟初始化策略: 只有当访问容器中的某个对象时, 才对该对象进行初始化和依赖注入操作.
还有一个比它更高级的叫做 ApplicationContext
除了具有 BeanFactory
的所有能力之外, 还提供对事件监听机制以及国际化的支持等.
ApplicationContext
构建在
BeanFactory
上, 并且在容器启动时全部完成初始化和依赖注入操作.
Bean 作用范围(scope)
范围 | 说明 |
---|---|
singleton | 这是默认Scope,表示在整个bean容器中或者说是整个应用中只会有一个实例。 |
prototype | 多例类型,表示每次从bean容器中都会获取到一个对应bean定义全新的实例。 |
request | 仅适用于Web环境下的ApplicationContext,表示每一个HttpRequest生命周期内会有一个单独的实例,即每一个Http请求都会拥有一个单独的实例。 |
session | 仅适用于Web环境下的ApplicationContext,表示每一个HttpSession生命周期内会有一个单独的实例,即每一个HttpSession下都会拥有一个单独的实例,即每一个用户都将拥有一个单独的实例。 |
application | 仅适用于Web环境下的ApplicationContext,表示在ServletContext生命周期内会拥有一个单独的实例,即在整个ServletContext环境下只会拥有一个实例。 |
websocket | 将单个bean定义范围限定为WebSocket的生命周期。 仅在Web Spring ApplicationContext的上下文中有效。 |
可以通过注解 @Scope
进行指定
@Component
@Scope("prototype")
public class Hello {
}
如果作用范围是 request
session
application
则可以使用相应的 @RequestScope
@SessionScope
@ApplicationScope
注解.