Spring6當中獲取Bean的四種方式小結
每博一文案
比如:《殺死一只是更鳥》中提到的 對應我們:我們努力升本,考研,每天都在努力學習,但是某天突然想到萬一沒有考上的話,那現(xiàn)在的努力又有什么意義呢? 答案:在《殺死一只是更鳥》里有這樣一段話: 勇敢是,當你還未開始,你就知道自己會輸,可你依然要去做,而且無論如何都要把它堅持到底,你很少能贏,但有時也會。努力的這個過程本身就是有意義,能夠獲得理想的結果當然很好,但如果失敗了也沒關系。因為你的勇敢,從未辜負你的青春,而黎明的光亮,總有一刻,會照亮穿梭于黑暗之中的自己。 況且,你還不一定會輸呢。
Spring 為Bean 的獲取提供了多種方式,通常包括4種方式。(也就是說在Spring中為Bean對象的創(chuàng)建準備了多種方案,目的是:更加靈活)
- 第一種:通過構造方法實例化,獲取 Bean對象
- 第二種:通過簡單工廠模式實例化,獲取Bean對象
- 第三種:通過factory-bean 屬性,獲取Bean對象
- 第四種:通過對FactoryBean 接口的實例化,獲取Bean對象
1. Spring6 當中 獲取 Bean 的四種方式
1.1 第一種方式:通過構造方法獲取 Bean
簡單的說:就是通過在spring的配置文件中,進行一個配置,從而調取其中 Bean 的構成方法,獲取到 對應的Bean對象。
準備工作:通過 maven 導入 Spring6的框包
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.rainbowsea</groupId> <artifactId>spring6-005-bean-instantiation-blog</artifactId> <version>1.0-SNAPSHOT</version> <packaging>jar</packaging> <properties> <maven.compiler.source>17</maven.compiler.source> <maven.compiler.target>17</maven.compiler.target> </properties> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>6.0.11</version> </dependency> <!-- junit4 --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.13.2</version> <scope>test</scope> </dependency> </dependencies> </project>
這里我們創(chuàng)建一個User 的類,方便我們進行一個,測試。為了測試效果,更加明顯,這里這個User類就定義成一個空的類吧
配置相關的 spring.xml 配置文件信息內容,告知 Spirng 框架,幫我們進行一個管理。
<?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"> <!-- 第一種: 通過構造方法獲取 Bean --> <bean id="user" class="com.rainbowsea.Bean.User"></bean> </beans>
運行測試,看是否能夠,獲取到我們想要的這個 User 類對象。
import com.rainbowsea.Bean.User; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Test { @org.junit.Test public void test() { ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring6.xml"); User user = applicationContext.getBean("user", User.class); System.out.println(user); } }
從上述結果,我們通過構造方法,獲取到了 Bean 對象。
1.2 第二種方式:通過簡單工廠模式獲取 Bean
第一步: 定義一個Bean,還是使用 User 對象
外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳 第二步: 編寫簡單工廠模式當中的工廠類。
注意: 這里的 User 對象,本質上,還是我們程序員自己給 new 出來的,并不是 Spring 幫我們弄的。
/** * 特點:它是簡單工廠模式(靜態(tài)工廠模式),是靜態(tài)的一個方法 * */ public class UserFactory { public static User get() { // 本質上,還是我們自己程序員自己 new 出來的 return new User(); } }
第三步:在Spring配置文件中指定創(chuàng)建該Bean的方法(使用factory-method屬性指定)
通過簡單工廠模式,你需要在Spring當中配置文件種告訴 Spring框架,調用哪個類當中的哪個方法可以獲取到這個你要的 Bean; factory-method 指明方法()對應方法的小寫。
factory-method=
屬性我們這里指定的是 UserFactory 工廠類當中靜態(tài)方法,也就是告訴Spring 框架,調用方法可以獲取到你要的Bean 對象。
<?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"> <!-- 第二種: 通過簡單工廠模式,你需要在Spring當中配置文件種告訴 Spring框架,調用哪個類當中的哪個方法可以獲取到這個 你要的 Bean; factory-method 指明方法()對應方法的小寫 --> <!-- factory-method= 屬性指定的時工廠類當中靜態(tài)方法,也就是告訴Spring 框架,調用方法可以獲取到你要的 Bean--> <bean id="userFactory" class="com.rainbowsea.Bean.UserFactory" factory-method="get"></bean> </beans>
第四步: 編寫測試程序
通過: 這樣一個配置,就讓我們告知了 Spring 框架,你調用那個類當中的哪里方法,就可以獲取到我們想要的Bean 對象。
1.3 第三種方式:通過 factory-bean 屬性獲取 Bean
使用 factory-bean 屬性獲取 Bean,本質上是,使用23種設計模式當中的工廠方法模式(注意,這里沒有錯,不了解的,可能會認為是,我寫錯了,并沒有寫錯這里)。
**第一步:**定義一個 Bean 對象。這里我們還是使用 User 這里類,進行試驗。
第二步: 既然是工廠方法模式,自然是少不了,工廠了。需要注意 :這里是工廠方法模式,與靜態(tài)工廠模式不同,這個生產 Bena 對象的方法,不是靜態(tài)方法,而是實例化方法 。這也導致了,我們在接下來后續(xù)的 spring.xml 配置文件上與第二種 方式有所差異的。注意其中的差異,所使用的標簽,不要弄錯了。
package com.rainbowsea.Bean; /** * 特點:它是簡單工廠模式(靜態(tài)工廠模式),是靜態(tài)的一個方法 * */ public class UserFactory { // 工廠方法模式中的具體工廠角色中的方法是:實例方法 public User get() { // 相同點是和靜態(tài)工廠方法模式是一樣的:都是我們自己程序員 new 的。 // 然后交給 Spring框架管理 return new User(); } }
**第三步:**在Spring配置文件中指定factory-bean以及factory-method
上面我們說到,工廠方法模式與靜態(tài)方法模式,不同點,上是工廠方法模式生產Bean 對象的方法,并不是一個 static() 方法 ,所以,使用的標簽屬性就有所不同了。
這里我們需要用到以下,兩個標簽屬性,才能讓spirng 準確的調用哪個類當中的哪個對象的方法,獲取,返回給我們自己想要的 Bean 對象,這里是User 這個 bean對象。
- factory-bean 指明哪個對象
- factory-method當中的哪個方法;可以獲取到你想要的 bean
簡單的說:告訴Spring 通過哪個對象,當中的哪個方法,可以獲取到我想要的 Bean 對象 。
<?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"> <!-- 第三種:通過Spring提供的實例化方式,通過工廠方法模式,通過 factory-bean 指明哪個對象+factory-method當中的哪個方法;可以獲取到你想要的 bean--> <!-- 簡單的說:就是告訴Spring框架,調用哪個對象中的哪個方法,就可以獲取到你想要的 Bean了--> <bean id="userFactory" class="com.rainbowsea.Bean.UserFactory"> </bean> <!-- 以下的配置很關鍵: factory-bean:告訴Spring框架調用哪個對象; factory-method 告訴Spring框架 調用哪個方法,可以獲取到你要的Bean--> <bean id="userBean" factory-bean="userFactory" factory-method="get"></bean> </beans>
第四步: 測試運行結果。
import com.rainbowsea.Bean.User; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Test { @org.junit.Test public void test() { ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring6.xml"); User user = applicationContext.getBean("userBean", User.class); System.out.println(user); } }
1.4 第四種方式:通過 FactoryBean 接口 獲取 Bean
以上的第三種方式中,factory-bean的屬性值是我們自定義的,factory-method的屬性值也是我們自己定義的。
在Spring中,當你編寫的類直接實現(xiàn)FactoryBean接口之后,factory-bean不需要指定了,factory-method也不需要指定了。
factory-bean會自動指向實現(xiàn)FactoryBean接口的類,factory-method會自動指向getObject()方法。
package org.springframework.beans.factory; import org.springframework.lang.Nullable; public interface FactoryBean<T> { String OBJECT_TYPE_ATTRIBUTE = "factoryBeanObjectType"; @Nullable T getObject() throws Exception; @Nullable Class<?> getObjectType(); default boolean isSingleton() { return true; } }
第四種方式:簡單的說:就是對第三種方式的一種簡化,通過讓對應的工廠類是實現(xiàn)該接口implements FactoryBean ,Spring就知道該調用哪個對象,中的哪個方法,獲取到你要的 Bean 對象了 。從到到達了某種程度上的簡化。
第一步: 定義一個Bean
這里我們還是使用 User 這里類,進行試驗。
第二步: 編寫一個(工廠模式當中的)工廠類實現(xiàn) FactoryBean接口
下面,我們來了解一下,F(xiàn)actoryBean接口下的這個三個方法的作用是干啥的
// 返回我們所需要的 Bean 對象 T getObject() throws Exception;
例如:注意一點:這里還是需要我們自己 new() 出對應所需要的 Bean 對象,而不是 Spirng 弄出來的
@Override public User getObject() throws Exception { return new User(); // 還是需要我們程序員自己 new() 出來 }
/** * 這個方法在接口中有默認實現(xiàn) * 默認返回 true,表示單例的 * 如果想多例的化,直接講這個修改為: return false 即可。 * @return */ default boolean isSingleton() { return true; }
例如: @Override public boolean isSingleton() { return true; // 單例 }
這里我們定義了一個 UserFactory 產生 User 的對象的工廠類,同時實現(xiàn)implements FactoryBean 該接口。
package com.rainbowsea.Bean; import org.springframework.beans.factory.FactoryBean; /** * 特點:它是簡單工廠模式(靜態(tài)工廠模式),是靜態(tài)的一個方法 * */ public class UserFactory implements FactoryBean<User> { @Override public User getObject() throws Exception { // 本質上還是我們程序員自己 new ()出來的,并不是 Spring 弄出來 return new User(); } // 這個方法可以不用管它。 @Override public Class<?> getObjectType() { return null; } @Override public boolean isSingleton() { return true; // 單例 // false 多例 } }
**第三步:**在Spring配置文件中配置FactoryBean
由于我們這個public class UserFactory implements FactoryBean 生產 User 的工廠實現(xiàn)了 FactoryBean 接口,Spring 已經是知道,我們需要調用的是哪個對象當中的哪個方法,從而獲取對應的 user Bean對象了。所以對應其中的
spinrg.xml
只需要簡單的配置一下,即可。
如下:
將方式的核心就在于:通過一個特殊的Bean(工廠Bean當中的方法)<該工廠實現(xiàn)了 FactoryBean 接口 >,來返回一個普通的Bean 對象。
<?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"> <!-- Spring框架中:獲取Bean的第四種方式:通過 FactoryBean 接口來實現(xiàn)指明 --> <!-- 這種方式實際上就是第三種方式的簡化--> <!-- 由于你編寫的類實現(xiàn)了FactoryBean接口,那么這個類就是一個特殊的類,不需要你再手動指定: factory-bean; factory-method 哪個對象,哪個方法了,你實現(xiàn)了 FactoryBean 接口,Spring框架就已經知道了,不需要再特殊指明了--> <!-- 剩下指明是哪個特殊的類就可以了--> <!-- 通過一個特殊的Bean,工廠Bean,來返回一個普通的Bean person對象--> <bean id="userFactory" class="com.rainbowsea.Bean.UserFactory"></bean> </beans>
第四步: 運行程序測試。
package com.rainbowsea.test; import com.rainbowsea.Bean.User; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Test { @org.junit.Test public void test() { ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring6.xml"); User user = applicationContext.getBean("userFactory", User.class); System.out.println(user); } }
FactoryBean在Spring中是一個接口。被稱為“工廠Bean”。“工廠Bean(通過工廠上的方法返回一個 對應的 Bean 對象)”是一種特殊的Bean。所有的“工廠Bean”都是用來協(xié)助Spring框架來創(chuàng)建其他Bean對象的。
1.5 BeanFactroy 和 FactroyBean 的區(qū)別
BeanFactory
Spring IoC容器的頂級對象,BeanFactory被翻譯為“Bean工廠”,在Spring的IoC容器中,“Bean工廠”負責創(chuàng)建Bean對象。 BeanFactory是工廠。
FactoryBean
FactoryBean:它是一個Bean,是一個能夠輔助Spring實例化其它Bean對象的一個Bean。
第一類:普通Bean第二類:工廠Bean(記?。汗SBean也是一種Bean,只不過這種Bean,比較特殊工廠Bean(通過工廠上的方法返回一個 對應的 Bean 對象),從而到達輔助Spring實例化其它Bean對象的效果。)
在Spring中,Bean可以分為兩類:
2. 將Date 作為復雜類型進行注入(可以自定義 Date 時間類型的格式)
在Spring 當中 為什么要將 Date 作為復雜類型進行注入呢?
原因是,在Spring 如果將 Date 作為簡單類型進行注入的話,需要特定的時間格式,才能注入成功。
準備工作:定義一個 Bean 類,同時其中含有一個 Date 類型的屬性值。
package com.rainbowsea.Bean.myDate; import java.util.Date; public class Vip { private Date birth; public Vip(Date birth) { this.birth = birth; } public Vip() { } public Date getBirth() { return birth; } public void setBirth(Date birth) { this.birth = birth; } @Override public String toString() { return "Vip{" + "birth=" + birth + '}'; } }
演示如下:
警告: Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘vipBean’ defined in class path resource [spring2.xml]: Failed to convert property value of type ‘java.lang.String’ to required type ‘java.util.Date’ for property ‘birth’; Cannot convert value of type ‘java.lang.String’ to required type ‘java.util.Date’ for property ‘birth’: no matching editors or conversion strategy found
對應Spring當中的 Date 作為簡單類型的注入,需要用如下它美國的格式時間格式,才能被識別為 Date 類型。特殊格式如下:
Mon Apr 29 20:03:58 CST 2024
雖然轉化成功了,但是這個格式,對于我們國人來說,不太友好,而且也不好記憶。
所以為了將Date 類型轉化為我們國人友好的類型的格式,我們就需要將 Date 定義為 復雜類型
進行 ref 注入。但是怎樣將 Date 作為復雜類型注入的同時又可以轉換為我們需要的格式呢。——這就需要用到上面我們所學習的通過 FactoryBean接口 獲取 Bean 對象了。其實呢,上面第二種方式,第三種方式,第四種方式都是可以實現(xiàn)的。但是第四種方式比較簡化,我們這里就用第四種方式來解決。這個問題。
第一步: 定義一個含有 Date 類型的類,就還是使用上面哪個 Vip 類吧
第二步: 創(chuàng)建一個用于生產我們所需要的格式的 Date的工廠 同時該工廠又實現(xiàn)了 implements FactoryBean 接口。告訴Spring框架,調用其中的哪個對象當中的哪個方法,獲取到我們所需要的 Date 對象。
package com.rainbowsea.Bean.myDate; import org.springframework.beans.factory.FactoryBean; import java.text.SimpleDateFormat; import java.util.Date; /** * Date 工廠模式 * DateFactoryBean 這個工廠Bean 協(xié)助我們Spring 創(chuàng)建這個普通的Bean;Date */ public class DateFactor implements FactoryBean<Date> { // 這個 String字符串類型,作為我們Date類型,進行一個轉換 private String strDate; public DateFactor() { } public DateFactor(String strDate) { this.strDate = strDate; } public String getStrDate() { return strDate; } public void setStrDate(String strDate) { this.strDate = strDate; } @Override public Date getObject() throws Exception { // 通過 SimpleDateFormat 來自定義我們的 Date 的日期時間類型的格式 SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd"); // 通過在 spring.xml 對DateFactor類當中的 String strDate 屬性進行賦值 Date date = simpleDateFormat.parse(this.strDate); // 將字符串類型轉換為 Date 日期時間類型 return date; // 轉換后返回 Date 類型,進行一個賦值操作 } @Override public Class<?> getObjectType() { return null; } @Override public boolean isSingleton() { return true; // 單例 false 多例 } }
上述代碼的核心代碼片段講解:
// 這個 String字符串類型,作為我們Date類型,進行一個轉換 private String strDate; public Date getObject() throws Exception { // 通過 SimpleDateFormat 來自定義我們的 Date 的日期時間類型的格式 SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd"); // 通過在 spring.xml 對DateFactor類當中的 String strDate 屬性進行賦值 Date date = simpleDateFormat.parse(this.strDate); // 將字符串類型轉換為 Date 日期時間類型 return date; // 轉換后返回 Date 類型,進行一個賦值操作 }
通過定義一個Date 類型的工廠類 生產出,我們需要的格式的 Date 類型。
第三步: 為我們這個 工廠類(生產我們所需的Date日期類型格式),配置到 Spring 當中去,并讓 Spirng 框架返回一個我們需要的 Date類型的 Bean 對象,同時作為復雜類型,賦值到 Vip 這個類當中的 birth 屬性的值。
<?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"> <!-- 指明通過DateFactor 獲取到一個我們所需要的格式的 Date 類型--> <bean id="myDateBean" class="com.rainbowsea.Bean.myDate.DateFactor"> <property name="strDate" value="1980-01-01"></property> </bean> <!-- 獲取到之后,作為復雜類型,賦值給 Vip 當中的 Date birth 屬性值--> <bean id="vipBean" class="com.rainbowsea.Bean.myDate.Vip"> <property name="birth" ref="myDateBean"></property> </bean> </beans>
第四步: 運行程序測試
核心要素就是:通過一個(這里時生產我們所需格式的 Date 類型的)工廠類實現(xiàn) FactoryBean接口,被稱為“工廠Bean”。“工廠Bean(通過工廠上的方法返回一個對應的 Bean(這里時 Date ) 對象)”是一種特殊的Bean。獲取到對應 Date 后,再作為 復雜類型作為其他類上的屬性的值存在。
3. 總結
第一種通過構造方法獲取 Bean:簡單的說:就是通過在spring的配置文件中,進行一個配置,從而調取其中 Bean 的構成方法,獲取到 對應的Bean對象。
第二種方式:通過簡單工廠模式獲取 Bean;注意時工廠類中生產對應的Bean對象是靜態(tài)方法()。同時其中的 Bean 本質上還是程序員自己 new()出來的。
通過簡單工廠模式,你需要在Spring當中配置文件種告訴 Spring框架,調用哪個類當中的哪個方法可以獲取到這個你要的 Bean; factory-method 指明方法()對應方法的小寫。
factory-method=
屬性我們這里指定的是 UserFactory 工廠類當中靜態(tài)方法,也就是告訴Spring 框架,調用方法可以獲取到你要的Bean 對象。第三種方式:通過 factory-bean 屬性獲取 Bean;使用 factory-bean 屬性獲取 Bean,本質上是,使用23種設計模式當中的工廠方法模式。(注意 其中的工廠類當中的生產對應 Bean的方法是實例方法(不是靜態(tài)方法),其中的 Bean 本質上還是程序員自己 new()出來的 )
這里我們需要用到以下,兩個標簽屬性,才能讓spirng 準確的調用哪個類當中的哪個對象的方法,獲取,返回給我們自己想要的 Bean 對象,這里是User 這個 bean對象。 factory-bean 指明哪個對象factory-method當中的哪個方法;可以獲取到你想要的 bean第四種方式:通過 FactoryBean 接口 獲取 Bean;簡單的說:就是對第三種方式的一種簡化,通過讓對應的工廠類是實現(xiàn)該接口implements FactoryBean ,Spring就知道該調用哪個對象,中的哪個方法,獲取到你要的 Bean 對象了 。從到到達了某種程度上的簡化。
該方式的核心就在于:通過一個特殊的Bean(工廠Bean當中的方法)<該工廠實現(xiàn)了 FactoryBean 接口 >,來返回一個普通的Bean 對象。BeanFactroy 和 FactroyBean 的區(qū)別
將Date 作為復雜類型進行注入(可以自定義 Date 時間類型的格式);
對應Spring當中的 Date 作為簡單類型的注入,需要用如下它美國的格式時間格式,才能被識別為 Date 類型。
核心要素就是:通過一個(這里時生產我們所需格式的 Date 類型的)工廠類實現(xiàn) FactoryBean接口,被稱為“工廠Bean”。“工廠Bean(通過工廠上的方法返回一個對應的 Bean(這里時 Date ) 對象)”是一種特殊的Bean。獲取到對應 Date 后,再作為 復雜類型作為其他類上的屬性的值存在。
4. 最后:
以上就是Spring6當中獲取Bean的四種方式小結的詳細內容,更多關于Spring6獲取Bean的資料請關注腳本之家其它相關文章!
相關文章
Java Swing組件實現(xiàn)進度監(jiān)視功能示例
這篇文章主要介紹了Java Swing組件實現(xiàn)進度監(jiān)視功能,結合完整實例形式詳細分析了Java基于Swing組件實現(xiàn)進度條顯示功能的具體操作技巧與相關注意事項,需要的朋友可以參考下2018-02-02在Window系統(tǒng)下安裝Netbeans9的方法
今天小編就為大家分享一篇關于在Window系統(tǒng)下安裝Netbeans9的方法,小編覺得內容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧2018-12-12