對於bean的基礎設定如下
<bean id="" class=""/>
其中,bean標籤的功能、使用方式以及id和class屬性的作用,我們通過一張圖來描述下
思考:
class屬效能不能寫介面如BookDao
的類全名呢?
答案肯定是不行,因為介面是沒辦法建立物件的。
前面提過為bean設定id時,id必須唯一,但是如果由於命名習慣而產生了分歧後,該如何解決?
在解決這個問題之前,我們需要準備下開發環境,內容如下:
環境準備好後,接下來就可以在這個環境的基礎上來學習下bean的別名設定,
首先來看下別名的設定說明:
開啟spring的組態檔applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--name:為bean指定別名,別名可以有多個,使用逗號,分號,空格進行分隔-->
<bean id="bookService" name="service service4 bookEbi" class="com.itheima.service.impl.BookServiceImpl">
<property name="bookDao" ref="bookDao"/>
</bean>
<!--scope:為bean設定作用範圍,可選值為單例singloton,非單例prototype-->
<bean id="bookDao" name="dao" class="com.itheima.dao.impl.BookDaoImpl"/>
</beans>
說明:Ebi全稱Enterprise Business Interface,翻譯為企業業務介面
public class AppForName {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
//此處根據bean標籤的id屬性和name屬性的任意一個值來獲取bean物件
BookService bookService = (BookService) ctx.getBean("service4");
bookService.save();
}
}
測試結果為:
注意事項:
bean依賴注入的ref屬性指定bean,必須在容器中存在
如果不存在,則會報錯,如下:
這個錯誤大家需要特別關注下:
獲取bean無論是通過id還是name獲取,如果無法獲取到,將丟擲異常NoSuchBeanDefinitionException
遇到這樣的問題通常檢查名稱是否寫錯
關於bean的作用範圍是bean屬性設定的一個重點內容。看到這個作用範圍,我們就得思考bean的作用範圍是來控制bean哪塊內容的?
我們先來看下bean作用範圍的設定屬性
:
同一個bean獲取兩次,將物件列印到控制檯,看列印出的地址值是否一致。
建立一個AppForScope的類,在其main方法中來驗證
public class AppForScope {
public static void main(String[] args) {
ApplicationContext ctx = new
ClassPathXmlApplicationContext("applicationContext.xml");
BookDao bookDao1 = (BookDao) ctx.getBean("bookDao");
BookDao bookDao2 = (BookDao) ctx.getBean("bookDao");
System.out.println(bookDao1);
System.out.println(bookDao2);
}
}
列印,觀察控制檯的列印結果
結論:預設情況下,Spring建立的bean物件都是單例的
獲取到結論後,問題就來了,那如果我想建立出來非單例的bean物件,該如何實現呢?
在Spring的組態檔中,修改<bean>
的scope屬性
<bean id="bookDao" name="dao" class="com.itheima.dao.impl.BookDaoImpl" scope=""/>
將scope設定為singleton
<bean id="bookDao" name="dao" class="com.itheima.dao.impl.BookDaoImpl" scope="singleton"/>
執行AppForScope,列印看結果
將scope設定為prototype
<bean id="bookDao" name="dao" class="com.itheima.dao.impl.BookDaoImpl" scope="prototype"/>
執行AppForScope,列印看結果
結論,使用bean的scope
屬性可以控制bean的建立是否為單例:
singleton
預設為單例
prototype
為非單例
介紹完scope
屬性以後,我們來思考幾個問題:
為什麼bean預設為單例?
bean為單例的意思是在Spring的IOC容器中只會有該類的一個物件
bean物件只有一個就避免了物件的頻繁建立與銷燬,達到了bean物件的複用,效能高
bean在容器中是單例的,會不會產生執行緒安全問題?
如果物件是有狀態物件,即該物件有成員變數可以用來儲存資料的,
因為所有請求執行緒共用一個bean物件,所以會存線上程安全問題。
如果物件是無狀態物件,即該物件沒有成員變數沒有進行資料儲存的,
因方法中的區域性變數在方法呼叫完成後會被銷燬,所以不會存線上程安全問題。
哪些bean物件適合交給容器進行管理?
表現層物件 serviceImpl
業務層物件 service
資料層物件 dao
工具物件 util
哪些bean物件不適合交給容器進行管理?
封裝範例的域物件,因為會引發執行緒安全問題,所以不適合。
本文來自部落格園,作者:|舊市拾荒|,轉載請註明原文連結:https://www.cnblogs.com/xiaoyh/p/16303453.html