Spring Framework ‐ Bean Scope - CCH0124/spring-sandbox GitHub Wiki
Spring 框架定義了 6 種類型的 Bean 作用域:
- singleton
- Spring 容器實例化一次,請求它的所有物件將會共用實例
- prototype
- 表示每次對其發出請求時,Spring 容器都會建立該 Bean 的新實例
- request
- 僅適用於 Web 應用程式(),表示 Spring 容器為每個 HTTP 請求建立一個新的 Bean 實例
- session
- 一旦更改該物件的值,該值將保留用於後續請求,因為為整個會話傳回相同的 Bean 實例
- application
- todo
- websocket
- todo
Singleton Scope
如果定義一個單例作用域的 Bean 時,Spring 中容器會建立該 Bean 的唯一實例,對該 Bean 名稱的所有請求都將返回相同的物件。
下面範例引用同一個 Bean 的兩個物件將具有相同的值,就算其中一個物件更改其狀態其所對應之物件還是相同,因為它們都引用同一個 Bean 實例
@Bean
@Scope(value = ConfigurableBeanFactory.SCOPE_SINGLETON)
public Cat catSingleton() {
return new Cat("Hello", 3);
}
@Test
public void givenSingletonScope_whenSetName_thenEqualNames() {
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(ScopeConfig.class);
Cat catSingletonA = (Cat) applicationContext.getBean("catSingleton");
Cat catSingletonB = (Cat) applicationContext.getBean("catSingleton");
catSingletonA.setName("set");
assertEquals(catSingletonA.getName(), catSingletonB.getName());
((AbstractApplicationContext) applicationContext).close();
}
Prototype Scope
每次從 Spring 容器請求時,具有 Prototype
屬性的 Bean 都會傳回不同的實例。
下面測試顯示兩個物件請求具有 Prototype
屬性的相同 Bean 名稱。它們將具有不同的狀態,因為它們不引用同一個 Bean 實例。
@Bean
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public Cat catPrototype() {
return new Cat();
}
@Test
public void givenPrototypeScope_whenSetNames_thenDifferentNames() {
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(ScopeConfig.class);
Cat catPrototypeA = (Cat) applicationContext.getBean("catPrototype");
Cat catPrototypeB = (Cat) applicationContext.getBean("catPrototype");
catPrototypeA.setName("Ragdoll");
catPrototypeB.setName("American Shorthair");
assertEquals("Ragdoll", catPrototypeA.getName());
assertEquals("American Shorthair", catPrototypeB.getName());
((AbstractApplicationContext) applicationContext).close();
}