Spring IoC 容器和 bean 物件
程式的耦合性:
耦合性(Coupling),又叫耦合度,是對模組間關聯程度的度量。耦合的強弱取決於模組間介面的複雜性、呼叫模組的方式以及通過介面傳送資料的多少。模組間的耦合度是指模組之間的依賴關係,包括控制關係、呼叫關 系、資料傳遞關係。模組間聯絡越多,其耦合性越強,同時表明其獨立性越差( 降低耦合性,可以提高其獨立 性)。
I o C容器
IoC
是Inversion of Control
的縮寫,即控制反轉的意思,是解決程式耦合性的一種思想。通常建立物件的時候使用new關鍵字,控制權由程式設計師控制,而"控制反轉"是指new例項工作不由程式設計師來做而是交給Spring容器來做。解決程式耦合性的辦法有很多,而依賴注入(DI)這一功能就是IOC思想的一種具體實現Spring pom.xml配置:
<dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.2.0.RELEASE</version> </dependency> </dependencies>
Spring 專案結構依賴:
Spring bean.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"> //id 是自己定義的一個名字,相當於取一個別名 ,class是需要訪問實現類的全限定類名 <bean id="daoService" class="com.Test.Dao.DaoServiceImpl"></bean> <bean id="userService" class="com.Test.Service.UserServiceImpl"></bean> </beans>
入門案例:
import com.Test.Dao.DaoService; import com.Test.Service.UserService; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class MyTest { public static void main(String[] args){ ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml"); //daoService,userService就是之前bean.xml檔案裡的id DaoService dao = (DaoService)context.getBean("daoService"); UserService user = (UserService)context.getBean("userService"); System.out.println(dao); System.out.println(user); } }
Application Context 是 spring 中較高階的容器,它採用立即載入的策略。而
BeanFactory
是採用延遲載入的策略,但是也可以載入配置檔案中定義的 bean,將所有的 bean 集中在一起,當有請求的時候分配 bean。ApplicationContext
包含BeanFactory
所有的功能,一般情況下,相對於BeanFactory
,ApplicationContext
會更加優秀。ApplicationContext的三個實現類:
1.ClassXmlPathApplicationContext:載入類路徑下的配置檔案,不需要提供 XML 檔案 的完整路徑,只需正確配置 CLASSPATH 環境變數即可,因為,容器會從CLASSPATH 中搜索 bean 配置檔案。
2.FileSystemXmlApplicationContext:載入磁碟任意路徑下的配置檔案。
3.AnnotationConfingApplictionContext:用於讀取註解建立容器。
建立bean的三種方式:
1.使用預設建構函式建立:
<bean id="daoService" class="com.Test.Dao.DaoServiceImpl"></bean>
2.(使用別人建立好的類時)使用普通工廠中的方法建立物件(或使用某個類中的方法建立物件):
import com.Test.Service.UserService; import com.Test.Service.UserServiceImpl; public class InstanceFactory { public UserService getUserService(){ return new UserServiceImpl(); } }
bean配置:
<bean id="userService" factory-bean="instanceFactory" factory-method="getUserService">
3.使用工廠中的靜態方法建立bean物件:
import com.Test.Service.UserService; import com.Test.Service.UserServiceImpl; public class InstanceFactory { public static UserService getUserService(){ return new UserServiceImpl(); } }
<bean id="userService" class="com.Test.Factory.StaticInstanceFactory" factory-method="getUserService"></bean>
bean的作用域:
當在 Spring 中定義一個 bean 時,你必須宣告該 bean 的作用域的選項。例如,為了強制 Spring 在每次需要時都產生一個新的 bean 例項,你應該宣告 bean 的作用域的屬性為 prototype。同理,如果你想讓 Spring 在每次需要時都返回同一個bean例項,你應該宣告 bean 的作用域的屬性為 singleton。
Spring 框架支援以下五個作用域,分別為singleton、prototype、request、session和global session,5種作用域說明如下所示,
注意,如果你使用 web-aware ApplicationContext 時,其中三個是可用的。
作用域 | 描述 |
---|---|
singleton | 在spring IoC容器僅存在一個Bean例項,Bean以單例方式存在,預設值 |
prototype | 每次從容器中呼叫Bean時,都返回一個新的例項,即每次呼叫getBean()時,相當於執行newXxxBean() |
request | 每次HTTP請求都會建立一個新的Bean,該作用域僅適用於WebApplicationContext環境 |
session | 同一個HTTP Session共享一個Bean,不同Session使用不同的Bean,僅適用於WebApplicationContext環境 |
global-session | 一般用於Portlet應用環境,該運用域僅適用於WebApplicationContext環境 |
singleton 作用域:
singleton 是預設的作用域,也就是說,當定義 Bean 時,如果沒有指定作用域配置項,則 Bean 的作用域被預設為 singleton。
當一個bean的作用域為Singleton,那麼Spring IoC容器中只會存在一個共享的bean例項,並且所有對bean的請求,只要id與該bean定義相匹配,則只會返回bean的同一例項。
也就是說,當將一個bean定義設定為singleton作用域的時候,Spring IoC容器只會建立該bean定義的唯一例項。
Singleton是單例型別,就是在建立起容器時就同時自動建立了一個bean的物件,不管你是否使用,他都存在了,每次獲取到的物件都是同一個物件。注意,Singleton作用域是Spring中的預設作用域。你可以在 bean 的配置檔案中設定作用域的屬性為 singleton,如下所示:
<!-- A bean definition with singleton scope -->
<bean id="..." class="..." scope="singleton">
<!-- collaborators and configuration for this bean go here -->
</bean>
prototype 作用域
當一個bean的作用域為Prototype,表示一個bean定義對應多個物件例項。Prototype作用域的bean會導致在每次對該bean請求(將其注入到另一個bean中,或者以程式的方式呼叫容器的getBean()方法)時都會建立一個新的bean例項。Prototype是原型型別,它在我們建立容器的時候並沒有例項化,而是當我們獲取bean的時候才會去建立一個物件,而且我們每次獲取到的物件都不是同一個物件。根據經驗,對有狀態的bean應該使用prototype作用域,而對無狀態的bean則應該使用singleton作用域。
為了定義 prototype 作用域,你可以在 bean 的配置檔案中設定作用域的屬性為 prototype,如下所示:
<!-- A bean definition with singleton scope -->
<bean id="..." class="..." scope="prototype">
<!-- collaborators and configuration for this bean go here -->
</bean>
----相關參考見w3cschool文