spring中bean的作用域

spring关于Bean的作用域官方文档(6种)

链接:Core Technologies (spring.io) 版本:Version 5.3.8

spring中Bean的作用域
Scope Description
singleton

(Default) Scopes a single bean definition to a single object instance for each Spring IoC container.

(默认)将单个 bean 定义范围限定为每个 Spring IoC 容器的单个对象实例。

prototype

Scopes a single bean definition to any number of object instances.

将单个 bean 定义范围限定为任意数量的对象实例。

request

Scopes a single bean definition to the lifecycle of a single HTTP request. That is, each HTTP request has its own instance of a bean created off the back of a single bean definition. Only valid in the context of a web-aware Spring .ApplicationContext

将单个 bean 定义范围限定为单个 HTTP 请求的生命周期。 也就是说,每个 HTTP 请求都有自己的 bean 实例,该 bean 实例是在单个 bean 定义的后面创建的。 仅在 web-aware Spring .ApplicationContext 的上下文中有效。

session

Scopes a single bean definition to the lifecycle of an HTTP Session. Only valid in the context of a web-aware Spring ApplicationContext.

将单个 bean 定义范围限定为 HTTP 会话的生命周期。 仅在 web-aware Spring ApplicationContext 的上下文中有效。

application

Scopes a single bean definition to the lifecycle of a ServletContext. Only valid in the context of a web-aware Spring ApplicationContext.

将单个 bean 定义范围限定为 ServletContext 的生命周期。 仅在 web-aware Spring ApplicationContext 的上下文中有效。

websocket

Scopes a single bean definition to the lifecycle of a WebSocket. Only valid in the context of a web-aware Spring ApplicationContext.

将单个 bean 定义范围限定为 WebSocket 的生命周期。 仅在 web-aware Spring ApplicationContext 的上下文中有效。

 

spring关于Bean作用域声明

1、spring中Bean的作用域声明(通过配置文件定义)

例:

<bean id="accountService" class="com.something.DefaultAccountService" scope="singleton"/>

2、spring中Bean的作用域声明(通过注解@Scope定义)

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Scope {
    @AliasFor("scopeName")
    String value() default "";

    @AliasFor("value")
    String scopeName() default "";

    ScopedProxyMode proxyMode() default ScopedProxyMode.DEFAULT;
}

由@Target({ElementType.TYPE, ElementType.METHOD})可见@Scope注解使用在类和方法上

例:

@Scope(value="prototype")
@Bean
public User getUser(){return new User("张三",18); }
@Component
@Scope(value="prototype")
public class User{
    private String name;
    public void setName(String name){
        this.name= name;
    }
    public String getName(){
        return name;
    }
}

spring关于Bean的作用域理解及使用案例

1、@Scope(value="singleton")或@Scope(value=ConfigurableBeanFactory.SCOPE_SINGLETON)

解释:

当scope为”singleton”,即默认情况下,会在启动容器时(即实例化容器时)时实例化(饿汉模式)。但我们可以使用@Lazy来延迟初始化bean(懒汉模式),这时候,只有在第一次获取bean时才会初始化bean,即第一次请求该bean时才初始化。一个bean被声明为单例的时候,在处理多次请求的时候在spring 容器里只实例化出一个bean,后续的请求都公用这个对象,这个对象会保存在一个map里面。当有请求来的时候会先从缓存(map)里查看有没有,有的话直接使用这个对象,没有的话才实例化一个新的对象,所以这是个单例的。

  • 在单例的bean中切记声明成员属性(如Map、List集合来缓存数据等),是线程不安全的。
  • 当容器关闭时(applicationContext.close())实例化的Bean将会被销毁。
@RestController
public class TestController{

}
@SpringBootTest
class CampusServiceCenterApplicationTests {

    @Test
    void contextLoads() {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext("com.hongyao.campusservicecenter.business.controller");
        TestController bean = applicationContext.getBean(TestController.class);
        System.out.println(bean);
        TestController bean1 = applicationContext.getBean(TestController.class);
        System.out.println(bean1);
        applicationContext.close();
    }
}
com.hongyao.campusservicecenter.business.controller.TestController@100bba26
com.hongyao.campusservicecenter.business.controller.TestController@100bba26

由此可见两次请求的Bean地址一致。

2、@Scope(value="prototype")或@Scope(value=ConfigurableBeanFactory.SCOPE_PROTOTYPE)

解释:

当scope为”prototype”,容器也会延迟初始化bean,在创建容器的时候并没有实例化,而是当每次获取bean的时候都会去实例化一个新对象。

  • spring创建Bean后不对Bean整个生命周期负责。由调用者或者jvm进行销毁回收资源。
@RestController
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class TestController{

}
@SpringBootTest
class CampusServiceCenterApplicationTests {

    @Test
    void contextLoads() {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext("com.hongyao.campusservicecenter.business.controller");
        TestController bean = applicationContext.getBean(TestController.class);
        System.out.println(bean);
        TestController bean1 = applicationContext.getBean(TestController.class);
        System.out.println(bean1);
        applicationContext.close();
    }
}
com.hongyao.campusservicecenter.business.controller.TestController@56c0a61e
com.hongyao.campusservicecenter.business.controller.TestController@421ead7e

3、@Scope(value="request")或@Scope(value= WebApplicationContext.SCOPE_REQUEST)或@RequestScope

解释:

当scope为”request”,每增加一个HTTP请求,Spring就会创建一个新的bean,在请求处理完成之后便及时销毁这个bean。

4、@Scope(value="session")或@Scope(value= WebApplicationContext.SCOPE_SESSION)或@SessionScope

解释:

当scope为”session”,session中所有http请求共享同一个请求的bean实例。session结束后就销毁bean。

5、@Scope(value="application")或@Scope(value= WebApplicationContext.SCOPE_APPLICATION)或@ApplicationScope

解释:

当scope为”application”,Spring为整个web上下文创建一个AppPreferences 的bean。也就是说,这个bean作用域是在ServletContext级别,它是作为ServletContext的一个属性存在的。

这和singleton作用域很像,但是有两点不同:

  • application作用域的bean是每个ServletContext只有一个;而singleton作用域是每个SpringApplicationContext只有一个。两者的范围不同。
  • application作用域的bean是属于ServletContext的,作为ServletContext的属性,是可见的。

6、@Scope(value="websocket")

解释:

当scope为”websocket”,具体信息不详。

posted @ 2021-06-22 15:20  无法抽离的小忧伤  阅读(266)  评论(0)    收藏  举报