javascript
SpringIOC配置文件「bean」标签的属性id class name scope init-method destroy-method factory-bean factory-method
spring
引入Spring
在沒有使用spring的時候寫代碼的三層架構的時候,dao層與service緊密聯系,service與controller緊密聯系,在service中new的dao接口的實現類,在controller中new的是service的實現類,這種聯系很緊密,高耦合
圖解spring是如何降低耦合度的
原始模式
在最初的代碼是要使用的話,就new這個接口的實現對象,假如我們換實現類后,還需要更改源代碼,這樣耦合度高,加入我們項目上線后,我們要更改某個實現,需要更改源代碼,需要從新編譯部署運行,十分麻煩
工廠模式降低解耦
使用工廠模式,讓new實現類的工作交給工廠來創建,這樣雖然具體的業務和實現類是斷開了耦合,但是工廠與實現類還是高耦合,我們想修改實現類,還得修改工廠中的方法,導致還是需要從新編譯打包部署運行
spring的IOC
使用spring來管理我們的實體對象,只需要將配置文件中的實現更改,無需更改源代碼,當我們需要跟換實現的時候,只需要將配置文件中的class更改就行了,無需重新編譯,十分方便,從而使得代碼與代碼之間的耦合度降低,讓類與配置文件有緊密聯系
耦合與內聚
IOC
IoC
? IoC(Inversion Of Control)控制反轉,Spring反向控制應用程序所需要使用的外部資源
? Spring控制的資源全部放置在Spring容器中,該容器稱為IoC容器
通俗來將就是原本我們使用一個類需要將這個類new出來,是我們主動去創建這個類
而把這個類交給spring的ioc管理后,spring會把這個類放在他的ioc容器中,然后我們要使用就去容器中獲取就是,被動獲取
spring的applicationContext.xml關于IOC的配置
記錄spring的applicationContext.xml配置文件中的bean標簽的使用
bean
? 名稱:bean
? 類型:標簽
? 歸屬:beans標簽
? 作用:定義spring中的資源,受此標簽定義的資源將受到spring控制
? 格式:
< beans>
< bean />
< /beans>
基本屬性id屬性和class屬性< bean id=“dog” class=“com.fs.iocdemo.Dog”/>
< bean id=“dog” class=“com.fs.iocdemo.Dog”/>
◆ id:bean的名稱,通過id值獲取bean
◆ class:bean的類型
類的準備
創建一個Dog類,提供一個方法來輸出語句便于觀察
package com.fs.iocdemo;public class Dog {public void testBean(){System.out.println("Dog對象被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/beanshttps://www.springframework.org/schema/beans/spring-beans.xsd"><!-- 把Dog對象交給spring的ioc容器管理,默認通過無參構造方法創建--><bean id="dog" class="com.fs.iocdemo.Dog"/> </beans>測試方法
//測試bean是否被ioc管理@Testpublic void testBean() {//創建spring的ioc容器對象,傳遞的參數為配置文件的名,類路徑下的配置文件ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");//通過配置文件中的id從spring的ioc容器中獲取Dog對象Dog dog = (Dog) applicationContext.getBean("dog");//調用方法dog.testBean();}輸出結果與解釋
說明我們的Dog已經從spring的IOC容器中獲取到了
基本屬性name < bean id=“cat” name=“cat1,cat2” class=“com.fs.iocdemo.Cat”/>
◆ name:bean的名稱,可以通過name值獲取bean,用于多人配合時給bean起別名
類的準備
創建一個Cat類,來演示一個配置文件中可以將多個類交給spring的Ioc管理,和演示name屬性
package com.fs.iocdemo;public class Cat {public void testName(){System.out.println("cat被spring的ioc管理了");}}配置文件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/beanshttps://www.springframework.org/schema/beans/spring-beans.xsd"><!-- 把Dog對象交給spring的ioc容器管理,默認通過無參構造方法創建--><bean id="dog" class="com.fs.iocdemo.Dog"/><!--把Cat對象交給spring的ioc容器管理,并且給多個name(起別名),通過getBean可以給別名從ioc中的到對象--><bean id="cat" name="cat1,cat2" class="com.fs.iocdemo.Cat"/></beans>測試方法
//測試給bean起別名后,通過別名從ioc中獲取對象@Testpublic void testName() {//創建spring的ioc容器對象,傳遞的參數為配置文件的名,類路徑下的配置文件ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");//通過配置文件中的id從spring的ioc容器中獲取Dog對象 // Cat cat = (Cat) applicationContext.getBean("cat");//使用別名也可以從spring的ioc獲取出Cat對象 // Cat cat = (Cat) applicationContext.getBean("cat1");Cat cat = (Cat) applicationContext.getBean("cat2");//調用方法cat.testName();}輸出結果與解釋
由上面代碼可得,getBean(這里可以傳遞id,也可以傳遞name),別名起多個,也可以從springIOC中獲取
基本屬性scope < bean id=“cat3” scope=“singleton” class=“com.fs.iocdemo.Cat”/>
bean屬性scope
? 名稱:scope
? 類型:屬性
? 歸屬:bean標簽
? 作用:定義bean的作用范圍
? 格式:< bean scope=“singleton”>
? 取值:
◆ singleton:設定創建出的對象保存在spring容器中,是一個單例的對象
◆ prototype:設定創建出的對象保存在spring容器中,是一個非單例的對象
◆ request、session、application、 websocket :設定創建出的對象放置在web容器對應的位置
類依然使用Cat類
配置文件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/beanshttps://www.springframework.org/schema/beans/spring-beans.xsd"><!-- 把Dog對象交給spring的ioc容器管理,默認通過無參構造方法創建--><bean id="dog" class="com.fs.iocdemo.Dog"/><!--把Cat對象交給spring的ioc容器管理,并且給多個name(起別名),通過getBean可以給別名從ioc中的到對象--><bean id="cat" name="cat1,cat2" class="com.fs.iocdemo.Cat"/><!--bean中的scope屬性默認是單例的(singleton)而且是俄漢式,就是類一加載就創建(不寫scope就是單例)scope屬性的prototype是多列的,但是是懶漢式,需要的后才創建--> <!-- <bean id="cat3" scope="singleton" class="com.fs.iocdemo.Cat"/>--><bean id="cat3" scope="prototype" class="com.fs.iocdemo.Cat"/></beans>測試方法
//測試bean標簽的scope屬性單例和多列模式@Testpublic void testScope() {//創建spring的ioc容器對象,傳遞的參數為配置文件的名,類路徑下的配置文件ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");/*<bean id="cat2" scope="singleton" class="com.fs.iocdemo.Cat"/>//單列模式獲取多個對象,看地址是否一樣,一樣說明確實是單例Cat cat = (Cat) applicationContext.getBean("cat3");Cat cat1 = (Cat) applicationContext.getBean("cat3");Cat cat2 = (Cat) applicationContext.getBean("cat3");//輸出看下地址值System.out.println(cat);//com.fs.iocdemo.Cat@7a765367System.out.println(cat1);//com.fs.iocdemo.Cat@7a765367System.out.println(cat2);//com.fs.iocdemo.Cat@7a765367*///多列模式下輸出的地址值不一樣,所明確實是的//多列模式spring是不會吧對象放在ioc中的,只是幫我們new的一下//<bean id="cat3" scope="prototype" class="com.fs.iocdemo.Cat"/>Cat cat = (Cat) applicationContext.getBean("cat3");Cat cat1 = (Cat) applicationContext.getBean("cat3");Cat cat2 = (Cat) applicationContext.getBean("cat3");//輸出看下地址值System.out.println(cat);//com.fs.iocdemo.Cat@7a765367System.out.println(cat1);//com.fs.iocdemo.Cat@76b0bfabSystem.out.println(cat2);//com.fs.iocdemo.Cat@17d677df}運行結果
在測試代碼的輸出語句中有顯示,可以得到當單例的時候,得到的對象都是同一個,而且是從IOC中獲取的對象,而多列的時候,獲取的對象是多個,而且不是從SpringIOC中獲取的,因為是多列,每獲取spring只幫new出來,而不會存儲在IOC中
Bean的生命周期 < bean id=“cat4” scope=“prototype” init-method=“init” destroy-method=“destroy” class=“com.fs.iocdemo.Cat”/>
bean生命周期
? 名稱:init-method,destroy-method
? 類型:屬性
? 歸屬:bean標簽
? 作用:定義bean對象在初始化或銷毀時完成的工作
? 格式:<bean init-method=“init” destroy-method="destroy>
? 取值:bean對應的類中對應的具體方法名
? 注意事項:
◆ 當scope=“singleton”時,spring容器中有且僅有一個對象,init方法在創建容器時僅執行一次
◆ 當scope=“prototype”時,spring容器要創建同一類型的多個對象,init方法在每個對象創建
時均執行一次
◆ 當scope=“singleton”時,關閉容器會導致bean實例的銷毀,調用destroy方法一次
◆ 當scope=“prototype”時,對象的銷毀由垃圾回收機制gc()控制,destroy方法將不會被執行
類的準備
在類中創建一個構造方法,兩個隨意的方法,名字也隨意,打印輸出一下,方便查看效果
package com.fs.iocdemo;public class Cat {public Cat() {System.out.println("構造方法執行了");}public void testName(){System.out.println("cat被spring的ioc管理了");}public void init(){System.out.println("init方法執行了");}public void destroy(){System.out.println("destroy方法執行了");} }配置文件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/beanshttps://www.springframework.org/schema/beans/spring-beans.xsd"><!-- 把Dog對象交給spring的ioc容器管理,默認通過無參構造方法創建--><bean id="dog" class="com.fs.iocdemo.Dog"/><!--把Cat對象交給spring的ioc容器管理,并且給多個name(起別名),通過getBean可以給別名從ioc中的到對象--><bean id="cat" name="cat1,cat2" class="com.fs.iocdemo.Cat"/><!--bean中的scope屬性默認是單例的(singleton)而且是俄漢式,就是類一加載就創建(不寫scope就是單例)scope屬性的prototype是多列的,但是是懶漢式,需要的后才創建--> <!-- <bean id="cat3" scope="singleton" class="com.fs.iocdemo.Cat"/>--><bean id="cat3" scope="prototype" class="com.fs.iocdemo.Cat"/><!-- init-method:給的類中的一個方法 在對象創建后執行 destroy-method:給類中的一個方法 在ioc容器正常關閉的時候運行,需要使用ClassPathXmlApplicationContext中的close()關閉才會執行 --><bean id="cat4" scope="prototype" init-method="init" destroy-method="destroy" class="com.fs.iocdemo.Cat"/></beans>測試方法
//測試bean的生命周期@Testpublic void testInitDestroy() {//創建spring的ioc容器對象,傳遞的參數為配置文件的名,類路徑下的配置文件ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");//不需要從ioc中獲得對象,因為spring一讀取配置文件就創建對象存在ioc中,所以默認無參構造方法就執行了// <bean id="cat4" scope="singleton" init-method="init" destroy-method="destroy" class="com.fs.iocdemo.Cat"/>/*單例模式(單列模式創建的對象會交給springIOC管理)構造方法執行了構造方法執行了init方法執行了destroy方法執行了*/// <bean id="cat4" scope="prototype" init-method="init" destroy-method="destroy" class="com.fs.iocdemo.Cat"/>//多列測試Cat cat = (Cat) applicationContext.getBean("cat4");Cat cat2 = (Cat) applicationContext.getBean("cat4");Cat cat3 = (Cat) applicationContext.getBean("cat4");/*多列模式下不會執行destroy方法(多列創建的對象不會交個spring的IOC管理,創建后就沒有被真正的關閉,而是被jvm垃圾回收,所以不會立馬執行destroy)構造方法執行了構造方法執行了init方法執行了構造方法執行了init方法執行了構造方法執行了init方法執行了*///ClassPathXmlApplicationContext 的close()關閉spring讓destroy執行applicationContext.close();}運行結果
代碼中有注釋運行結果,也有解釋.
bean對象的創建方式
使用靜態工廠和實例工廠創建bean
使用靜態工廠方式
bean對象創建方式(了解)
? 名稱:factory-bean
? 類型:屬性
? 歸屬:bean標簽
? 作用:定義bean對象創建方式,使用靜態工廠的形式創建bean,兼容早期遺留系統的升級工作
? 格式:
? 取值:工廠bean中用于獲取對象的靜態方法名
? 注意事項:
◆ class屬性必須配置成靜態工廠的類名
靜態工廠類
靜態工廠獲取Dog只需要FactoryStatic.Dog就能得到Dog對象
package com.fs.factory;import com.fs.iocdemo.Dog;public class FactoryStatic {//這個靜態工廠,用于生產dogpublic static Dog getDog(){return new Dog();} }實例工廠類
實例工廠獲取Dog,首先需要 new FactoryBean().getDog() 才能獲得Dog對象
package com.fs.factory;import com.fs.iocdemo.Dog;public class FactoryBean {//這是個實體類工廠,用于生產Dogpublic Dog getDog(){return new Dog();} }配置文件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/beanshttps://www.springframework.org/schema/beans/spring-beans.xsd"><!-- 把Dog對象交給spring的ioc容器管理,默認通過無參構造方法創建--><bean id="dog" class="com.fs.iocdemo.Dog"/><!--把Cat對象交給spring的ioc容器管理,并且給多個name(起別名),通過getBean可以給別名從ioc中的到對象--><bean id="cat" name="cat1,cat2" class="com.fs.iocdemo.Cat"/><!--bean中的scope屬性默認是單例的(singleton)而且是俄漢式,就是類一加載就創建(不寫scope就是單例)scope屬性的prototype是多列的,但是是懶漢式,需要的后才創建--> <!-- <bean id="cat3" scope="singleton" class="com.fs.iocdemo.Cat"/>--><bean id="cat3" scope="prototype" class="com.fs.iocdemo.Cat"/><!-- init-method:給的類中的一個方法 在對象創建后執行 destroy-method:給類中的一個方法 在ioc容器正常關閉的時候運行,需要使用ClassPathXmlApplicationContext中的close()關閉才會執行 --><bean id="cat4" scope="prototype" init-method="init" destroy-method="destroy" class="com.fs.iocdemo.Cat"/><!-- 配置靜態工廠交給spring管理因為獲取Dog的方法是靜態的,當我們從ioc獲取出靜態工廠就直接調用getDog方法就能拿到Dog//實際是將getDog的返回值存儲在ioc容器中 --><bean id="factoryStatic" class="com.fs.factory.FactoryStatic" factory-method="getDog"/><!-- 配置實體工廠--><bean id="factoryBean" class="com.fs.factory.FactoryBean"/> <!-- 然后在實體工廠中獲取Dogfactory-bean="factoryBean" : 關聯上面的實體工廠factory-method="getDog" : 調用實體工廠的方法//實際是將Dog存到ioc容器中 --><bean id="factoryBeanDog" factory-bean="factoryBean" factory-method="getDog"/></beans>測試方法
//測試工廠獲取對象@Testpublic void testFactory() {//創建spring的ioc容器對象,傳遞的參數為配置文件的名,類路徑下的配置文件ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");//<bean id="factoryStatic" class="com.fs.factory.FactoryStatic"/>Dog factoryStaticDog = (Dog) applicationContext.getBean("factoryStatic");factoryStaticDog.testBean();/*<bean id="factoryBean" class="com.fs.factory.FactoryBean"/> <!-- 然后在實體工廠中獲取Dogfactory-bean="factoryBean" : 關聯上面的實體工廠factory-method="getDog" : 調用實體工廠的方法//實際是將Dog存到ioc容器中 --><bean id="factoryBeanDog" factory-bean="factoryBean" factory-method="getDog"/>*/Dog factoryBeanDog = (Dog) applicationContext.getBean("factoryBeanDog");factoryBeanDog.testBean();}總結
以上是生活随笔為你收集整理的SpringIOC配置文件「bean」标签的属性id class name scope init-method destroy-method factory-bean factory-method的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 浅谈:数据结构之单链表,java代码演示
- 下一篇: SpringIOC的依耐注入DI---s