文章目錄
- 🍃Bean的作用域
- 🚩作用域的使用
- 🚩觀察Bean的作用域
- 🎈單例作用域
- 🎈多例作用域
- 🎈請求作用域
- 🎈會話作?域
- 🎈Application作?域
- 🎄Bean的?命周期
- ?總結
🍃Bean的作用域
Bean的作?域是指Bean在Spring框架中的某種?為模式.
比如單例作?域:表? Bean 在整個Spring 中只有?份, 它是全局共享的.那么當其他?修改了這個值之后,那么另?個?讀取到的就是被修改的值.
在Spring中?持6種作?域,后4種在Spring MVC環境才?效
-
singleton:單例作?域
-
prototype:原型作?域(多例作?域)
-
request:請求作?域
-
session:會話作?域
-
Application: 全局作?域
-
websocket:HTTP WebSocket 作?域
作?域 | 說明 |
---|---|
singleton | 每個Spring IoC容器內同名稱的bean只有?個實例(單例)(默認) |
prototype | 每次使?該bean時會創建新的實例(?單例) |
request | 每個HTTP 請求?命周期內,創建新的實例(web環境中) |
session | 每個HTTP Session?命周期內,創建新的實例(web環境中) |
application | 每個ServletContext?命周期內,創建新的實例(web環境中) |
websocket | 每個WebSocket?命周期內,創建新的實例(web環境中) |
🚩作用域的使用
簡單使用如下:
首先我們準備一個 Dog 類如下:
public class Dog {private String name;public String getName() {return name;}public void setName(String name) {this.name = name;}
}
接下來我們定義幾個不同作用域的 Bean
@Component
public class DogBean {@Beanpublic Dog dog() {Dog dog = new Dog();dog.setName("旺財");return dog;}@Bean@Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)public Dog singleDog(){Dog dog = new Dog();return dog;}@Bean@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)public Dog prototypeDog(){Dog dog = new Dog();return dog;}@Bean@RequestScopepublic Dog requestDog() {Dog dog = new Dog();return dog;}@Bean@SessionScopepublic Dog sessionDog() {Dog dog = new Dog();return dog;}@Bean@ApplicationScopepublic Dog applicationDog() {Dog dog = new Dog();return dog;}
}
需要注意的是
@RequestScope 等同于
@Scope(value =WebApplicationContext.SCOPE_REQUEST, proxyMode=ScopedProxyMode.TARGET_CLASS)
@SessionScope 等同于
@Scope(value=WebApplicationContext.SCOPE_SESSION, proxyMode=ScopedProxyMode.TARGET_CLASS)
@ApplicationScope 等同于 @Scope(value=WebApplicationContext.SCOPE_APPLICATION,proxyMode=ScopedProxyMode.TARGET_CLASS)
proxyMode?來為springbean設置代理.
proxyMode = ScopedProxyMode.TARGET_CLASS
表?這個Bean基于CGLIB實現動態代理.
Request,session和application作?域的Bean需要設置proxyMode
接下來我們再寫一些程序進行測試,測試不同作?域的Bean取到的對象是否?樣,測試程序如下:
@RestController
public class DogController {@Autowiredprivate Dog singleDog;@Autowiredprivate Dog prototypeDog;@Autowiredprivate Dog requestDog;@Autowiredprivate Dog sessionDog;@Autowiredprivate Dog applicationDog;@Autowiredprivate ApplicationContext applicationContext;@RequestMapping("/single")public String single(){Dog contextDog = (Dog)applicationContext.getBean("singleDog");return "dog:"+singleDog.toString()+"|-- --|contextDog:"+contextDog;}@RequestMapping("/prototype")public String prototype(){Dog contextDog = (Dog)applicationContext.getBean("prototypeDog");return "dog:"+prototypeDog.toString()+"|-- --|contextDog:"+contextDog;}@RequestMapping("/request")public String request(){Dog contextDog = (Dog)applicationContext.getBean("requestDog");return"dog:"+requestDog.toString()+"|-- --|contextDog:"+contextDog.toString();}@RequestMapping("/session")public String session(){Dog contextDog = (Dog)applicationContext.getBean("sessionDog");return "dog:"+sessionDog.toString()+"|-- --|contextDog:"+contextDog.toString();}@RequestMapping("/application")public String application(){Dog contextDog = (Dog)applicationContext.getBean("applicationDog");return "dog:"+applicationDog.toString()+"|-- --|contextDog:"+contextDog.toString();}
}
🚩觀察Bean的作用域
接下來我們來進行訪問
🎈單例作用域
- http://127.0.0.1:8080/single
多次訪問,得到的都是同?個對象,并且 @Autowired 和applicationContext.getBean() 也是同?個對象.
🎈多例作用域
- http://127.0.0.1:8080/prototype
觀察ContextDog,每次獲取的對象都不?樣(注?的對象在Spring容器啟動時,就已經注?了,所以多次請求也不會發?變化)
🎈請求作用域
- http://127.0.0.1:8080/request
在?次請求中, @Autowired 和 applicationContext.getBean() 也是同?個對象.但是每次請求,都會重新創建對象
🎈會話作?域
- http://127.0.0.1:8080/session
在?個session中,多次請求,獲取到的對象都是同?個.
換?個瀏覽器訪問,發現會重新創建對象.(另?個Session)
🎈Application作?域
- http://127.0.0.1:8080/application
在?個應?中,多次訪問都是同?個對象
Application scope就是對于整個web容器來說,bean的作?域是ServletContext級別的.
這個和singleton有點類似,區別在于:Application scope是ServletContext的單例,singleton是?個ApplicationContext的單例.
在?個web容器中ApplicationContext可以有多個
🎄Bean的?命周期
?命周期指的是?個對象從誕?到銷毀的整個?命過程,我們把這個過程就叫做?個對象的?命周期.
Bean的?命周期分為以下5個部分:
- 實例化(為Bean分配內存空間)
- 屬性賦值(Bean注?和裝配,?如 @AutoWired )
- 初始化
- 執?各種通知,如 BeanNameAware ,BeanFactoryAware ,ApplicationContextAware 的接??法.
- 執?初始化?法
-
- xml定義 init-method
-
- 使?注解的?式 @PostConstruct
-
- 執?初始化后置?法( BeanPostProcessor )
- 使?Bean
- 銷毀Bean
- 銷毀容器的各種?法,如 @PreDestroy , DisposableBean 接??法, destroymethod.
實例化和屬性賦值對應構造?法和setter?法的注入.
初始化和銷毀是用戶能?定義擴展的兩個階段,可以在實例化之后,類加載完成之前進??定義"事件"處理.
?如我們現在需要買?棟房?,那么我們的流程是這樣的:
- 先買房(實例化,從?到有)
- 裝修(設置屬性)
- 買家電,如洗?機,冰箱,電視,空調等([各種]初始化,可以?住);
- ?住(使?Bean)
- 賣房(Bean銷毀)
執行流程如下圖所示:
?總結
關于《【JavaEE進階】 Bean的作用域與生命周期》就講解到這兒,感謝大家的支持,歡迎各位留言交流以及批評指正,如果文章對您有幫助或者覺得作者寫的還不錯可以點一下關注,點贊,收藏支持一下!