javascript
Bean的作用域和生命周期-----Spring
1.之前學過的變量的作用域:是指變量在方法中或者作用域中的某種行為,現在我們來進行了解一下Bean的作用域
咱們的Java中的公共類稱之為Bean或者是JavaBean,Spring對象中的生命周期指的是交給SpringIOC容器的對象,所以說咱們的Spring Bean對象在進行使用的時候,無需通過new來進行創建對象,只需要通過依賴注入,從Spring要取出適用的對象即可
Bean的作用域在Spring容器里面默認是單例模式,是為了節省資源,并且沒有過多的生命周期的創建和銷毀,如果說每一次注入都創建一個新的User對象,系統的開銷就會更大的
1)什么是作用域:限定程序中變量的可用范圍就叫做作用域,或者在源代碼中定義變量的某個區域就叫做作用域,有幾種類型;
2?)但是Bean的作用域是指Bean在整個Spring框架容器里面的某種行為模式(重要),?是Bean的類型有哪些 ,比如說singLeton單例作用域,就表示Bean在整個Spring框架里面只有一份,他是全局共享的,那么當其他人修改了這個值之后,那么另一個人讀到的就是被修改的值
3)Spring容器在進行初始化一個Bean的實例的時候,同時會指定該實例的作用域,Spring有六種作用域,最后四種是針對SpringMVC生效的
因為單例模式只被初始化一次,初始化一次之后我們可以反復的進行使用,所以使用的性能比較高,所有人都是用的一個對象;
1.Bean的6種作用域:注意后四種是SpringMVC里面的作用范圍,是基于SpringMVC來進行生效的,但是普通的Spring項目(非web項目,普通的JAVA項目,SpringCore)只有前兩種;也就說明Bean在Spring里面一共有六種類型;
web項目:通過瀏覽器或者postman的方式來進行訪問一個地址的方式來進行發送Http請求,與咱們的在idea中的Spring代碼進行交互,是具有上面的5種值;
1.singleton:單例模式
描述:該作用域下的Bean在IOC容器中只存在一個實例:
當我們進行獲取Bean(即通過applicationContext.getBean等方法獲取以及裝配Bean(即通過Autowired注入)這都是一個對象;
場景:通常無狀態的Bean的使用該作用域,無狀態表示Bean對象的屬性不需要進行更新,不會修改Bean,通常我們的Spring默認選擇該作用域;
缺點:一個改變了,其他的就都改變了;
2.prototype:原型模式-----多例模式
描述:每次對于該作用域(每一次注入)下面的每一次Bean的請求都會創建新的實例:
1)當我們進行獲取Bean的時候(即通過applicationContext.getBean()方法來進行獲取Bean對象的時候)或者裝配Bean(即通過Autowired或者@Resource來進行注入)都會創建出新的對象實例,針對有狀態的Bean作用該作用域
2)這幾種方法獲取的都是新的對象實例,每一個類中引入的對象都是自己的;
場景:通常有狀態的Bean使用該作用域
3.Request
描述:針對每一次HTTP請求都會創建新的Bean實例,就類似于prototype,不管是一次會話還是兩次會話,每進行訪問一次,都會重新給一個新的對象,就是一次HTTP請求和響應的共享Bean
場景:一次http請求和響應的共享Bean
備注:只限于SpringMVC中使用,在咱們的普通項目是不能進行使用的
4.session
描述:在一個HttpSession中,定義一個Bean實例,一個會話共享一個Bean
場景:用戶會話的共享Bean,比如說記錄一個用戶的登錄信息,是針對一個人來進行操作的,只要是這個人操作的,就會對應到這個實例,比如說張三進行登錄了,那么在張三進行登錄的過程中,使用的都是同一個對象;
備注:只是限于SpringMVC中進行使用
5.application
描述:在一個http servlet context中對應一個Bean實例
場景:Application 的作用范圍在服務器一開始執行服務,到服務器關閉為止。 Application 相比于Session、request和page的范圍最大、停留的時間也最久。
存入application的信息在Web應用程序運行期間,所有的頁面都可以訪問這個信息。
備注:只限于SpringMVC進行使用
singletion是作用于整個Spring(IOC容器)容器當中,application是在一個Servlet容器當中(處理WEB請求)
6.WebSocket------網頁聊天
描述:在一個Http WebSocket的生命周期中,定義一個Bean實例
場景:WebSocket的每一次對話
備注:限定在Spring WebSocket中使用,WebSocket的每一次對話里面,保存了一個Map結構的頭信息,將用來包裹對象頭,第一次初始化之后,直到這一次WebSocket結束之后用到的都是同一個Bean;
單例作用域和全局作用域
singletion是Spring Core的作用域,application是Spring Web的作用域(只有在Servlet里面,在SpringMVC里面才有效果的)
singletion是作用域IOC的容器,而application是作用于Servlet的容器
我們如何進行設置Bean的作用域呢?保證多例的作用域
1)直接使用@Scope他是可以即應用于類注解上面,又能應用于方法注解上面
2)Scope翻譯成中文是作用域的意思,雖然說@Scope是可以進行應用到類注解和方法注解,但是如果應用到類注解,就說明進行設置當前這個類所生效;
3)我們一定要注意,我們如果想要方法的返回值是單例的或者是多例的,我們就可以經這個注解修飾方法,如果我們要使用的是@Bean注解·+@Scope,@Scope一定要放在方法上進行注解,不能放在類上;
4)我們可以直接設置作用域的具體的值通過@Scope("propotype")
5)我們還可以根據ConfigurableBeanFactory和WebApplicationContext提供的Scope_XXX變量來進行設置,我們可以把這個變量放在@Scope里面
@Component public class GetBean {@Bean(name ="u1")//將當前User對象存儲到Spring里面@Scope("prototype")public User GetUser1(){User user=new User();user.setId(1);user.setName("李佳偉");return user;}2.Bean的大的執行流程-----重要----Spring生命周期
1)啟動Spring容器-----執行main方法(執行帶有ApplicationContext的main方法,并指定了配置文件)
2)加載Spring配置文件(配置一個組件的掃描路徑,通常在resource,web.xml里面或者是使用<Beans>標簽)
3)將Bean對象注冊到Spring容器里面:加載配置文件中的bean或者根據配置文件中的bean組件的根掃描路徑,進行對Bean對象的掃描(會進行掃描五大類注解,那么就會把這五大注解修飾過的類或者是當前加了五大注解的類里面加了@Bean注解的方法返回的類存儲到Spring容器里面)
出現了屬性注入:(如果說我們在A類里面注入了B類,那么先會把B類給注入到Spring容器里面,在進行A類注冊到Spring里面)-------先去裝配Bean的屬性,再去裝配Bean
4)將加載的對象存入到Spring容器里面,進行加載
5)其他需要使用Bean對象的地方就可以直接進行獲取并使用了
6)執行完之后所有業務之后,執行銷毀操作
Bean的執行流程(Spring的執行流程)-----啟動Spring容器-----實例化Bean(分配內存空間,從無到有)-----將Bean進行注冊到Spring里面(存儲操作)-----我們最后再將Bean裝配到需要的類中,取操作;
Bean的生命周期-----重要:是指Bean在整個IOC容器中從創建到銷毀的整個過程
所謂的Bean的生命周期是指Bean在整個Spring容器里面,也就是在IOC容器里面從創建到銷毀的整個過程
因為SpringBoot是基于Spring來進行創建的,所以Bean在整個Spring和SpringBoot的行為都是一樣的
1)實例化Bean,為Bean對象整體分配內存空間-----把二進制的字節碼轉化成一個類對象
2)進行設置它的屬性(進行Bean的注入和裝配)
我們一定是要先進行加載屬性的,如果先進行初始化方法,很有可能就會在方法里面用到這個類屬性(如果這個屬性被@Resource或者Autowired所修飾,那么我們就需要對使用的Bean進行初始化注入),一個類是有屬性和方法的
3)(Bean初始化,一系列準備工作的統稱),執行各種通知方法,比如說在飛機上進行檢查工作,檢查按鈕;
3.1)實現了各種Aware通知的方法,創建一個類,實現了BeanNameAware,BeanFactoryAware,還有ApplicationContext接口的方法
3.2)執行實現BeanPostProcessor接口初始化前置方法
3.3)執行帶注解的@PostConstruct修飾的初始化方法,依賴注入操作之后執行
3.4)執行自己所指定的init-method方法,如果有指定的話(最早使用XML的方式,在沒有注解之前)---也是初始化方法
3.5)執行實現了BeanPostProcess接口初始化后置方法
4)使用Bean
5)進行銷毀Bean
5.1首先會執行@PreDestory這是銷毀前置方法,比如說像記錄一下時間,日志
5.2如果說實現了DisposableBean接口方法
5.3destory-method:銷毀前的執行方法,在XML里面進行設置
初始化前置方法和初始化后置方法是給所有Bean進行服務的,這些方法不能寫在某一個Bean中,否則不會執行
如果有的話,就執行(前提是你得重寫了前置方法他才會執行)
下面我們寫了一些代碼來進行演示:
@Controller public class BeanStart implements BeanNameAware {@Overridepublic void setBeanName(String s) {System.out.println("執行通知方法"+s);}@PostConstruct//出生于注解時代public void start(){System.out.println("執行被注解@PostConstruct修飾的方法");}public void init()//直接這么寫,是無法進行執行的,我們必須要在XML里面進行相應的配置,這里面的方法名字是可以隨便取的,只要和XML里面的名字相匹配就可以了{System.out.println("執行init方法");}public void destory(){System.out.println("執行destory方法");}@PreDestroypublic void predestory(){System.out.println("執行被注解修飾的");} } class HelloServlet{public static void main(String[] args) {ApplicationContext context=new ClassPathXmlApplicationContext("web.xml");UserController userController=context.getBean("beanStart",BeanStart.class);userController.destory();} } web.xml配置文件: <beans><bean id="userController" class="APP.Controller.UserController" init-method="init(方法名)" destroy-method="destory"></bean> </beans> 打印結果:執行通知方法userController 執行被注解@PostConstruct修飾的方法 執行通知方法userinit 執行被注解@PostConstruct修飾的方法 執行init方法 執行destory方法可不可以先執行初始化方法,在進行設置屬性?
假設現在@Controller里面進行屬性注入了UserService,先進行初始化操作,就會出現空指針異常,所以要先進行屬性注入,在進行初始化
咱們的初始化前置方法和后置方法是為所有的Bean來進行服務的,而不是給某一個Bean來進行服務的,這一系列的方法不可以寫在某一個具體的Bean里面,否則不會執行
總結
以上是生活随笔為你收集整理的Bean的作用域和生命周期-----Spring的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 360wifi在linux系统如何使用,
- 下一篇: 从程序员代码“呼救”大破传销组织_聊掌握