https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html#beans-factory-scopes
Bean范围
创建bean定义时,将创建一个配方,用于创建该bean定义所定义的类的实际实例。您可以从一个配方中创建许多对象实例。
您不仅可以控制要插入到从特定bean定义创建的对象中的各种依赖项和配置值,还可以控制从特定bean定义创建的对象的范围。可以将Bean定义为部署在多个范围之一。
Spring Framework支持六个范围,其中只有在使用web感知时才可用ApplicationContext。
Singleton:(默认)将每个Spring IoC容器的单个bean定义范围限定为单个对象实例。
Prototype:将单个bean定义的作用域限定为任意数量的对象实例。
Request:将单个bean定义的范围限定为单个HTTP请求的生命周期。也就是说,每个HTTP请求都有一个在单个bean定义后面创建的bean实例。仅在可感知网络的Spring ApplicationContext上下文中有效。
Session:将单个bean定义的范围限定为HTTP的生命周期Session。仅在可感知网络的Spring ApplicationContext上下文中有效。
Application:将单个bean定义的作用域限定为的生命周期ServletContext。仅在可感知网络的Spring ApplicationContext上下文中有效。
Websocket:将单个bean定义的作用域限定为的生命周期WebSocket。仅在可感知网络的Spring ApplicationContext上下文中有效。
从Spring 3.0开始,线程作用域可用,但默认情况下未注册。
Singleton Scope
仅管理一个singleton bean的一个共享实例,并且所有对具有ID或与该bean定义相匹配的ID的bean的请求都将导致该特定的bean实例由Spring容器返回。
换句话说,当您定义一个bean定义并且其作用域为单例时,Spring IoC容器将为该bean定义所定义的对象创建一个实例。该单个实例存储在此类单例bean的缓存中,并且对该命名bean的所有后续请求和引用都返回缓存的对象。
Prototype Scope
每次对特定bean提出请求时,bean部署的非单一原型范围都会导致创建一个新bean实例。也就是说,将Bean注入到另一个Bean中,或者您可以通过getBean()容器上的方法调用来请求它。通常,应将原型作用域用于所有有状态Bean,将单例作用域用于无状态Bean。
与其他作用域相比,Spring不能管理原型Bean的完整生命周期。容器实例化,配置或组装原型对象,然后将其交给客户端,而无需对该原型实例的进一步记录。因此,尽管在不考虑作用域的情况下在所有对象上都调用了初始化生命周期回调方法,但在原型的情况下,不会调用已配置的销毁生命周期回调。客户端代码必须清除原型作用域内的对象并释放原型Bean拥有的昂贵资源。
为了使Spring容器释放原型作用下的bean所拥有的资源,请尝试使用自定义bean后处理器,其中包含对需要清理的bean的引用。
在某些方面,Spring容器在原型作用域bean方面的角色是Java new
运算符的替代。超过该时间点的所有生命周期管理必须由客户端处理。(有关Spring容器中bean生命周期的详细信息,请参阅Lifecycle Callbacks。)
定义Bean的性质
Spring框架提供了许多接口,可用于自定义Bean的性质。本节将它们分组如下:
生命周期回调
ApplicationContextAware
和 BeanNameAware
其他Aware
介面
生命周期回调
为了与容器对bean生命周期的管理进行交互,可以实现Spring InitializingBean和DisposableBean接口。
通常,JSR-250 @PostConstruct和@PreDestroy注释被认为是在现代Spring应用程序中接收生命周期回调的最佳实践。使用这些注释意味着您的bean没有耦合到特定于Spring的接口。
在内部,Spring Framework使用BeanPostProcessor
实现来处理它可以找到的任何回调接口并调用适当的方法。如果您需要自定义功能或其他生命周期行为,Spring默认不提供,则您可以BeanPostProcessor
自己实现。有关更多信息,请参见 容器扩展点。
除了初始化和销毁回调外,Spring托管的对象还可以实现Lifecycle接口,以便这些对象可以在容器自身生命周期的驱动下参与启动和关闭过程。
初始化回调
org.springframework.beans.factory.InitializingBean
容器在bean上设置了所有必需的属性后,该接口使bean可以执行初始化工作。
我们建议您不要使用该InitializingBean
接口,因为它不必要地将代码耦合到Spring。另外,我们建议使用@PostConstruct
注释或指定POJO初始化方法。对于基于XML的配置元数据,可以使用init-method
属性指定具有无效无参数签名的方法的名称。通过Java配置,您可以使用的initMethod
属性 @Bean
。
销毁回调
org.springframework.beans.factory.DisposableBean
当包含该接口的容器被销毁时,实现该接口可使Bean获得回调。
我们建议您不要使用DisposableBean
回调接口,因为它不必要地将代码耦合到Spring。另外,我们建议使用@PreDestroy
注释或指定bean定义支持的通用方法。使用基于XML的配置元数据时,您可以在destroy-method
上使用属性
。通过Java配置,您可以使用的destroyMethod
属性@Bean
。
ApplicationContextAware和BeanNameAware
当ApplicationContext创建创建实现该org.springframework.context.ApplicationContextAware接口的对象实例时,该实例将获得对该 接口的引用ApplicationContext。以下清单显示了ApplicationContextAware接口的定义:
public interface ApplicationContextAware {
void setApplicationContext(ApplicationContext applicationContext) throws BeansException;
}
因此,bean可以ApplicationContext通过ApplicationContext接口或通过将引用转换为该接口的已知子类(例如ConfigurableApplicationContext,公开其他功能)来以编程方式操纵创建它们的bean 。一种用途是通过编程方式检索其他bean。有时,此功能很有用。但是,通常应避免使用它,因为它将代码耦合到Spring,并且不遵循控制反转样式,在该样式中,将协作者作为属性提供给bean。
ApplicationContext提供的其他方法提供对文件资源的访问,发布应用程序事件以及访问MessageSource。
自动装配是获得对ApplicationContext的引用的另一种方法。
传统的 constructor
和byType
自动装配模式(在所描述的自动装配协作者)可以提供类型的依赖 ApplicationContext
于构造器参数或设置器方法参数。
要获得更大的灵活性,包括能够自动连接字段和使用多个参数方法,请使用基于注释的自动装配功能。如果您这样做,则将ApplicationContext自动将其连接到需要该ApplicationContext类型的字段,构造函数参数或方法参数中(如果相关的字段,构造函数或方法带有@Autowired注释)。
当ApplicationContext创建一个实现该 org.springframework.beans.factory.BeanNameAware接口的类时,该类将获得对其关联对象定义中定义的名称的引用。以下清单显示了BeanNameAware接口的定义:
public interface BeanNameAware {
void setBeanName(String name) throws BeansException;
}
其他Aware介面
除了ApplicationContextAware和BeanNameAware,Spring还提供了各种各样的Aware回调接口,这些接口使bean可以向容器指示它们需要某种基础结构依赖性。通常,名称表示依赖项类型。下表总结了最重要的Aware接口:
ApplicationContextAware:声明ApplicationContext。
ApplicationEventPublisherAware:事件发布者。
BeanClassLoaderAware:类加载器,用于加载Bean类。
BeanFactoryAware:声明BeanFactory。
BeanNameAware:声明bean的名称。
LoadTimeWeaverAware:用于在加载时处理类定义。
MessageSourceAware:解决消息的已配置策略(支持参数化和国际化)。
NotificationPublisherAware:Spring JMX通知发布者。
ResourceLoaderAware:配置的加载程序,用于对资源的低级别访问。
ServletConfigAware:当前ServletConfig容器在其中运行。仅在可感知网络的Spring ApplicationContext中有效。
ServletContextAware:当前容器在ServletContext中运行。仅在可感知网络的Spring ApplicationContext中有效。
https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html#beans-factory-extension