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