91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Java中bean如何使用

發布時間:2021-07-27 13:51:02 來源:億速云 閱讀:687 作者:Leah 欄目:開發技術

今天就跟大家聊聊有關Java中bean如何使用,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結了以下內容,希望大家根據這篇文章可以有所收獲。

bean 的生命周期

Java中bean如何使用

對象創建

  1. 實例化Bean對象,默認選擇無參構造方法,如果只有一個有參構造那么調用有參構造,如果只有多個有參構造那么報錯,除非其中一個有參構造添加了@AutoWired注解;

  2. 設置Bean的屬性;

  3. 依賴注入以及判斷是否實現了Aware相關接口(BeanNameAware, BeanFactoryAware, ApplicationContextAware)

  4. 如果這個 Bean 關聯了 BeanPostProcessor 接口,將會調用BeanPostProcessor.postProcessorBeforeInitialization()

  5. 判斷是否實現了InitalizingBean接口,實現了就執行 InitalizingBean.afterPropertiesSet() 方法

  6. 如果Bean在配置文件中的定義包含init-method屬性(或者添加了@PostConstruct注解),執行指定的方法;

  7. 執行方法BeanPostProcessor.postProcessorAfterInitialization():例如判斷有沒有實現AOP

  8. 創建對象完畢;

對象銷毀

  1. 當要銷毀Bean的時候,如果Bean實現了DisposableBean接口,執行destroy()方法。

  2. 當要銷毀Bean的時候,如果Bean在配置文件中的定義包含destroy-method屬性(或者添加了@PreDestroy注解),執行指定的方法

  3. 銷毀對象完畢

Bean 的作用域

spring 支持 5 種作用域,如下:

request:每一次HTTP請求都會產生一個新的bean,該bean僅在當前HTTP request內有效。

  • singleton::單例模式,Spring IoC 容器中只會存在一個共享的 Bean 實例,無論有多少個Bean 引用它,始終指向同一對象。該模式在多線程下是不安全的。Singleton 作用域是Spring 中的默認作用域

  • prototype:每次通過 Spring 容器獲取 prototype 定義的 bean 時,容器都將創建一個新的 Bean 實例,每個 Bean 實例都有自己的屬性和狀態,而 singleton 全局只有一個對象。根據經驗,對有狀態的bean使用prototype作用域,而對無狀態的bean使用singleton作用域。

    • 用于與數據庫交互的存儲數據的bean等,均是有狀態的bean。

    • 而僅僅用于操作其他資源的bean,如service controller,就是無狀態的bean。

    • 當然,由于spring使用了ThreadLocal進行多線程處理,絕大多數bean都可以聲明為singleton作用域。這是后話。

  • session:在一次 Http Session 中,容器會返回該 Bean 的同一實例。而對不同的 Session 請求則會創建新的實例,該 bean 實例僅在當前 Session 內有效。同 Http 請求相同,每一次session 請求創建新的實例,而不同的實例之間不共享屬性,且實例僅在自己的 session 請求內有效,請求結束,則實例將被銷毀。如用戶購物車

  • global-session:全局session作用域,僅僅在基于Portlet的Web應用中才有意義,Spring5中已經沒有了。Portlet是能夠生成語義代碼(例如HTML)片段的小型Java Web插件。它們基于Portlet容器,可以像Servlet一樣處理HTTP請求。但是與Servlet不同,每個Portlet都有不同的會話。

bean的循環依賴

什么是循環依賴

一個AService里面引用了BService的一個對象,BService里面又引用了AService的一個對象。

那么在構造AService的bean的時候,會填充屬性以及注入依賴,那么就需要注入BService的bean,spring發現BService的bean還沒有創建,又會去構造BService的bean。同理BService的bean又需要AService的bean,這時候因為AService的bean還沒有構建好,所以他也會去創建AService的bean。一直循環

Java中bean如何使用

怎么解決:使用二級緩存

  • singletonObjects:第一級緩存,里面放置的是實例化好的單例對象;這個是一直存在的

  • earlySingletonObjects:第二級緩存,里面存放的是提前曝光的單例對象;就是下面圖中的那個緩存

Java中bean如何使用

有什么問題

如果上述的bean不存在AOP,那么是沒有什么問題的,但是如果存在AOP的話,那么構造出來的bean對象就不是原始對象了,而是AOP生成的代理對象。如果還是使用二級緩存的話,那么B從緩存取的是A的原始對象而不是構造好的A的bean對象

怎么解決

添加一層緩存,singletonFactories:第三級緩存,里面存放的是要被實例化的對象的對象工廠。

主要代碼如下:

protected Object getSingleton(String beanName, boolean allowEarlyReference) {
    Object singletonObject = this.singletonObjects.get(beanName);
    if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
        synchronized (this.singletonObjects) {
            singletonObject = this.earlySingletonObjects.get(beanName);
            if (singletonObject == null && allowEarlyReference) {
                ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
                if (singletonFactory != null) {
                    singletonObject = singletonFactory.getObject();
                    this.earlySingletonObjects.put(beanName, singletonObject);
                    this.singletonFactories.remove(beanName);
                }
            }
        }
    }
    return (singletonObject != NULL_OBJECT ? singletonObject : null);
}

分析getSingleton()的整個過程,Spring首先從一級緩存singletonObjects中獲取。如果獲取不到,并且對象正在創建中,就再從二級緩存earlySingletonObjects中獲取。如果還是獲取不到且允許singletonFactories通過getObject()獲取,就從三級緩存singletonFactory.getObject()(三級緩存)獲取,如果獲取到了則從singletonFactories中移除,并放入earlySingletonObjects中。其實也就是從三級緩存移動到了二級緩存。

總結一下流程:

  • A在第一步實例化對象之后將自己提前曝光到singletonFactories中

  • 在填充屬性時發現自己依賴對象B,此時就嘗試去get(B),發現B還沒有被create,所以走create流程

  • B在填充屬性的時候發現自己依賴了對象A,于是嘗試get(A),嘗試一級緩存singletonObjects(肯定沒有,因為A的bean還沒有構造完),嘗試二級緩存earlySingletonObjects(也沒有),嘗試三級緩存singletonFactories,由于A通過ObjectFactory將自己提前曝光了,所以B能夠通過ObjectFactory.getObject拿到A對象

  • 通過提前引用,直接創建出A的動態代理對象也就是實例化好的A的bean放到第二個緩存中,這樣B的bean就直接實例化完成進入一級緩存。

  • 此時回調到A中,A填充屬性這一步完成了繼續往下執行,因為bean是單例的,所以A不會又去調用動態代理再創建一個bean,而是直接從第二個緩存里拿出實例化好的那個bean出來直接用放進一級緩存中。

看完上述內容,你們對Java中bean如何使用有進一步的了解嗎?如果還想了解更多知識或者相關內容,請關注億速云行業資訊頻道,感謝大家的支持。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

景宁| 潼关县| 兰考县| 西乌| 江华| 安溪县| 康马县| 郓城县| 桦南县| 西安市| 东海县| 黔江区| 九龙城区| 新化县| 菏泽市| 安宁市| 石景山区| 巴彦淖尔市| 尼木县| 宁陕县| 贵港市| 上林县| 淮阳县| 额济纳旗| 长宁区| 利辛县| 高邑县| 宝鸡市| 阳新县| 呼玛县| 阜平县| 泸溪县| 拜泉县| 鄂州市| 鸡东县| 永吉县| 夏河县| 泰和县| 贵州省| 无极县| 北安市|