20191225 Spring官方文档(Core 1.5)

1.5。Bean Scopes

创建bean定义时,将创建一个配方,用于创建该bean定义所定义的类的实际实例。Bean定义是配方的想法很重要,因为它意味着与类一样,您可以从一个配方中创建许多对象实例。

Spring Framework支持六个作用域,四个仅在Web环境的Spring ApplicationContext中可用。您还可以创建自定义作用域。

范围 描述
singleton (默认)将每个Spring IoC容器的单个bean定义范围限定为单个对象实例。
prototype 将单个bean定义的作用域限定为任意数量的对象实例。
request 将单个bean定义的范围限定为单个HTTP请求的生命周期。也就是说,每个HTTP请求都有一个在单个bean定义后面创建的bean实例。仅在Web环境的Spring ApplicationContext中可用。
session 将单个bean定义的范围限定为HTTP Session的生命周期。仅在Web环境的Spring ApplicationContext中可用。
application 将单个bean定义的作用域限定为ServletContext的生命周期。仅在Web环境的Spring ApplicationContext中可用。
websocket 将单个bean定义的作用域限定为WebSocket的生命周期。仅在Web环境的Spring ApplicationContext中可用。

从Spring 3.0开始,线程作用域可用,但默认情况下未注册。有关更多信息,请参见的文档 SimpleThreadScope

通常,应将原型作用域用于所有有状态Bean,将单例作用域用于无状态Bean。

Spring Boot读取xml配置文件的代码过程:

lambda$loadBeanDefinitionsFromImportedResources$0:379, ConfigurationClassBeanDefinitionReader (org.springframework.context.annotation)
accept:-1, 351656492 (org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader$$Lambda$167)
forEach:684, LinkedHashMap (java.util)
loadBeanDefinitionsFromImportedResources:346, ConfigurationClassBeanDefinitionReader (org.springframework.context.annotation)
loadBeanDefinitionsForConfigurationClass:147, ConfigurationClassBeanDefinitionReader (org.springframework.context.annotation)
loadBeanDefinitions:120, ConfigurationClassBeanDefinitionReader (org.springframework.context.annotation)
processConfigBeanDefinitions:337, ConfigurationClassPostProcessor (org.springframework.context.annotation)
postProcessBeanDefinitionRegistry:242, ConfigurationClassPostProcessor (org.springframework.context.annotation)
invokeBeanDefinitionRegistryPostProcessors:275, PostProcessorRegistrationDelegate (org.springframework.context.support)
invokeBeanFactoryPostProcessors:95, PostProcessorRegistrationDelegate (org.springframework.context.support)
invokeBeanFactoryPostProcessors:706, AbstractApplicationContext (org.springframework.context.support)
refresh:532, AbstractApplicationContext (org.springframework.context.support)
refresh:747, SpringApplication (org.springframework.boot)
refreshContext:397, SpringApplication (org.springframework.boot)
run:315, SpringApplication (org.springframework.boot)
run:1226, SpringApplication (org.springframework.boot)
run:1215, SpringApplication (org.springframework.boot)
main:13, Application (study.hwj.spring)

1.5.2。原型作用域

与其他作用域相比,Spring不能管理原型Bean的完整生命周期。容器实例化,配置或组装原型对象,然后将其交给客户端,而无需对该原型实例的进一步记录。因此,尽管在不考虑作用域的情况下在所有对象上都调用了初始化生命周期回调方法,但在原型的情况下,不会调用已配置的销毁生命周期回调。客户端代码必须清除原型作用域内的对象并释放原型Bean拥有的昂贵资源。为了使Spring容器释放原型作用下的bean所拥有的资源,请尝试使用自定义bean后置处理器,其中包含对需要清理的bean的引用。【???怎么用后置处理器处理原型Bean的销毁方法】

在某些方面,Spring容器在原型作用域bean方面的角色是Java new运算符的替代。超过该时间点的所有生命周期管理必须由客户端处理。

1.5.3。具有原型Bean依赖关系的Singleton Bean

当您使用对原型Bean有依赖性的单例作用域Bean时,请注意,依赖性在实例化时已解决。因此,如果您将原型范围的bean注入到单例范围的bean中,则将实例化新的原型bean,然后将依赖项注入到该singleton Bean中。原型实例是曾经提供给单例范围的bean的唯一实例。

但是,假设您希望单例作用域的bean在运行时重复获取原型作用域的bean的新实例。您不能将原型作用域的bean依赖项注入到您的单例bean中,因为当Spring容器实例化单例bean并解析并注入其依赖项时,该注入仅发生一次。如果在运行时不止一次需要原型bean的新实例,请参见方法注入

1.5.4。Request, Session, Application, 和WebSocket范围

只有当你使用一个基于web的Spring ApplicationContext实现(例如 XmlWebApplicationContext),requestsessionapplication,和websocket作用域可用。如果您将这些作用域与常规的Spring IoC容器(例如ClassPathXmlApplicationContext)一起使用,则会抛出未知bean作用域的IllegalStateException

request 作用域

<bean id="loginAction" class="com.something.LoginAction" scope="request"/>

@RequestScope
@Component
public class LoginAction {
    // ...
}

session 作用域

<bean id="userPreferences" class="com.something.UserPreferences" scope="session"/>

@SessionScope
@Component
public class UserPreferences {
    // ...
}

Application 作用域

<bean id="appPreferences" class="com.something.AppPreferences" scope="application"/>

@ApplicationScope
@Component
public class AppPreferences {
    // ...
}

Spring容器通过对整个Web应用程序使用appPreferences Bean定义来创建一个AppPreferences Bean 的新实例。也就是说, appPreferences bean的作用域在ServletContext级别,并存储为常规 ServletContext属性。这有点类似于Spring单例bean,但有两个重要的区别:它是每个 ServletContext 而不是每个Spring ApplicationContext 的单例(在任何给定的Web应用程序中可能都有多个),并且实际上是公开的,因此可见作为ServletContext属性。

范围Bean作为依赖项

Bean的作用域为request,session和自定义作用域级别需要使用<aop:scoped-proxy/>元素。

<bean id="userPreferences" class="com.something.UserPreferences" scope="session">
    <aop:scoped-proxy/>
</bean>

<bean id="userManager" class="com.something.UserManager">
    <property name="userPreferences" ref="userPreferences"/>
</bean>

您还可以在范围为singleton的Bean之间使用<aop:scoped-proxy/>,引用然后通过可序列化的中间代理,因此可以在反序列化时重新获得目标单例Bean。

prototype范围bean声明<aop:scoped-proxy/>时,共享代理上的每个方法调用都会导致创建新的目标实例,然后将该调用转发到该目标实例。

同样,作用域代理不是以生命周期安全的方式从较短的作用域访问bean的唯一方法。您还可以将注入点(即,构造函数或setter参数或自动装配的字段)声明为ObjectFactory<MyTargetBean>,从而允许每次需要时getObject()调用按需检索当前实例,而无需保留该实例或将其单独存储。

作为扩展变体,您可以声明ObjectProvider<MyTargetBean>,它提供了几个附加的访问变体,包括getIfAvailablegetIfUnique

被称为Provider的JSR-330变体, 在每次检索尝试中与Provider<MyTargetBean>声明和相应的get()调用一起使用。有关JSR-330总体的更多详细信息,请参见此处

选择要创建的代理类型

默认情况下,当Spring容器为使用<aop:scoped-proxy/>元素标记的bean创建代理时,将创建基于CGLIB的类代理。

CGLIB代理仅拦截公共方法调用!不要在这样的代理上调用非公共方法。它们没有被委派给实际的作用域目标对象。

另外,您可以通过指定<aop:scoped-proxy/>元素的proxy-target-class属性值为false,将Spring容器配置为为此类作用域的Bean创建基于标准JDK接口的代理。使用基于JDK接口的代理意味着您不需要应用程序类路径中的其他库即可影响此类代理。但是,这也意味着作用域Bean的类必须实现至少一个接口,并且作用域Bean注入到其中的所有协作者必须通过其接口之一引用该Bean。

1.5.5。自定义作用域

bean的作用域机制是可扩展的。您可以定义自己的作用域,甚至重新定义现有作用域,尽管后者被认为是不好的做法,您不能覆盖内置作用域singletonprototype

创建自定义作用域

需要实现org.springframework.beans.factory.config.Scope接口。

使用自定义作用域

org.springframework.beans.factory.config.ConfigurableBeanFactory#registerScope

Scope threadScope = new SimpleThreadScope();
beanFactory.registerScope("thread", threadScope);

使用自定义Scope实现,您不仅限于作用域的程序注册。您还可以使用CustomScopeConfigurer类以声明方式进行Scope注册 ,如以下示例所示:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop
        https://www.springframework.org/schema/aop/spring-aop.xsd">

    <bean class="org.springframework.beans.factory.config.CustomScopeConfigurer">
        <property name="scopes">
            <map>
                <entry key="thread">
                    <bean class="org.springframework.context.support.SimpleThreadScope"/>
                </entry>
            </map>
        </property>
    </bean>

    <bean id="thing2" class="x.y.Thing2" scope="thread">
        <property name="name" value="Rick"/>
        <aop:scoped-proxy/>
    </bean>

    <bean id="thing1" class="x.y.Thing1">
        <property name="thing2" ref="thing2"/>
    </bean>

</beans>

当您在FactoryBean实现中放置<aop:scoped-proxy/>时,作用域是工厂Bean本身,而不是从getObject()中返回的对象。

原文地址:https://www.cnblogs.com/huangwenjie/p/12098495.html

时间: 2024-10-05 05:41:44

20191225 Spring官方文档(Core 1.5)的相关文章

20191225 Spring官方文档(Core 1.6-1.8)

1.6.自定义Bean的性质 Spring框架提供了许多接口,可用于自定义Bean的性质. 1.6.1.生命周期回调 为了与容器对bean生命周期的管理进行交互,可以实现Spring的 InitializingBean和DisposableBean接口.容器调用afterPropertiesSet()和destroy()使bean在初始化和销毁bean时执行某些操作. 通常,JSR-250 @PostConstruct和@PreDestroy注释被认为是在现代Spring应用程序中接收生命周期回

20200106 Spring官方文档【归档】

目录 启动 Overview Core IoC容器 1.1.Spring IoC容器和Bean简介 1.2.容器概述 1.3.Bean总览 1.4.依赖关系 1.5.Bean Scopes 1.6.自定义Bean的性质 1.7.Bean定义继承 1.8.容器扩展点 1.9.基于注释的容器配置 1.10.类路径扫描和托管组件 1.11.使用JSR 330标准注释 1.12.基于Java的容器配置 1.13.Environment 抽象 1.14.注册一个LoadTimeWeaver 2. Reso

Spring 总览及 IOC 容器的使用 —— Spring 官方文档解读(一)

Spring 总览及 IOC 容器的使用 -- Spring 官方文档解读(一) 什么是 Spring? spring 这个词在不同情况下有不同意义.可以指 Spring 框架本身,但更多地被用来表示 Spring 整个家族的产品. 设计理念 学习框架必须要知道它的设计理念,Spring 框架有着以下的理念: Spring 让你在架构种的各个层面有更多的选择,并且允许你尽晚的做出决策.比如,你在项目完成后可以通过更改配置来切换持久层的提供者. Spring 具有强大的灵活性,它不在意你是如何完成

20200103 Spring官方文档(Core 3)

3.验证,数据绑定和类型转换 考虑将验证作为业务逻辑是有利有弊,Spring提供了一种验证(和数据绑定)设计,但并不排除其中任何一个. 具体来说,验证不应与Web层绑定,并且应该易于本地化,并且应该可以插入任何可用的验证器. 考虑到这些问题,Spring提出了一个Validator接口,该接口既基本又可以在应用程序的每一层中使用. 数据绑定对于使用户输入动态绑定到应用程序的域模型(或用于处理用户输入的任何对象)非常有用. Spring提供了恰当地命名为DataBinder的功能. Validat

20191224 Spring官方文档(Core 1.1-1.4)

1. IoC容器 1.1.Spring IoC容器和Bean简介 org.springframework.beans和org.springframework.context包是Spring框架的IoC容器的基础.BeanFactory 接口提供了一种高级配置机制,能够管理任何类型的对象. ApplicationContext是BeanFactory的子接口.它增加了: 与Spring的AOP功能轻松集成 消息资源处理(用于国际化) 活动发布 应用层特定的上下文,例如用于Web应用程序中的WebA

20200105 Spring官方文档(Core 4)

4.Spring表达式语言(SpEL) Spring表达式语言(简称 SpEL)是一种功能强大的表达式语言,支持在运行时查询和操作对象图.语言语法与Unified EL相似,但提供了其他功能,最著名的是方法调用和基本的字符串模板功能. Spring Expression Language的创建是为了向Spring社区提供一种受良好支持的表达式语言,该语言可用于该版本中的所有产品.它并不直接与Spring绑定,可以独立使用. 4.1.评价(Evaluation) 以下代码介绍了SpEL API来评

20191226 Spring官方文档(Core 1.10)

1.10.类路径扫描和托管组件 1.10.1.@Component和更多的构造型注释 @Repository批注是实现存储库(也被称为数据访问对象或DAO)角色或构造型的任何类的标记.该标记的用途是自动翻译 异常. Spring提供进一步构造型注解:@Component,@Service 和 @Controller.@Component是任何Spring托管组件的通用构造型. @Repository,@Service和@Controller是@Component针对更特定用例的专业化(分别在持久

spring 官方文档

英文 http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/ 翻译(1-6章) http://blog.csdn.net/tangtong1/article/details/51326887 翻译(7章) http://blog.csdn.net/tangtong1/article/details/51960382 翻译(1-6)

Spring官方文档——日志

2.3.2 日志 日志对于Spring来说非常重要(废话,日志对哪个系统不重要?),因为 a)它是唯一强制的外部依赖,b)每个人都希望在使用某个工具时可以看到一些友好地输出,c)Spring集成了很多其他的工具,它们也都有自己的日志依赖.应用开发者的一个目标通常是:对于整个应用来说(包括所有的外部组件),集中创建一个统一的日志配置.由于现在有如此多的日志框架,这个选择看起来会变得更难. Logging is a very important dependency for Spring becau