<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
準備開發環境
最終專案的結構如下:
在上述的環境下,我們來研究下Spring中的第一種bean的建立方式構造方法範例化:
步驟1:準備需要被建立的類
準備一個BookDao和BookDaoImpl類
public interface BookDao { public void save(); } public class BookDaoImpl implements BookDao { public void save() { System.out.println("book dao save ..."); } }
步驟2:將類設定到Spring容器
<?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 id="bookDao" class="com.itheima.dao.impl.BookDaoImpl"/> </beans>
步驟3:編寫執行程式
public class AppForInstanceBook { public static void main(String[] args) { ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml"); BookDao bookDao = (BookDao) ctx.getBean("bookDao"); bookDao.save(); } }
步驟4:類中提供建構函式測試
在BookDaoImpl類中新增一個無參建構函式,並列印一句話,方便觀察結果。
public class BookDaoImpl implements BookDao { public BookDaoImpl() { System.out.println("book dao constructor is running ...."); } public void save() { System.out.println("book dao save ..."); } }
執行程式,如果控制檯有列印建構函式中的輸出,說明Spring容器在建立物件的時候也走的是建構函式
步驟5:將建構函式改成private測試
public class BookDaoImpl implements BookDao { private BookDaoImpl() { System.out.println("book dao constructor is running ...."); } public void save() { System.out.println("book dao save ..."); } }
執行程式,能執行成功,說明內部走的依然是建構函式,能存取到類中的私有構造方法,顯而易見Spring底層用的是反射
步驟6:建構函式中新增一個引數測試
public class BookDaoImpl implements BookDao { private BookDaoImpl(int i) { System.out.println("book dao constructor is running ...."); } public void save() { System.out.println("book dao save ..."); } }
執行程式,程式會報錯,說明Spring底層使用的是類的無參構造方法。
接下來,我們主要研究下Spring的報錯資訊
錯誤資訊從下往上依次檢視,因為上面的錯誤大都是對下面錯誤的一個包裝,最核心錯誤是在最下面
Caused by: java.lang.NoSuchMethodException: com.itheima.dao.impl.BookDaoImpl.
<init>
()
<init>
():哪個類的哪個方法沒有被找到導致的異常,<init>
()指定是類的構造方法,即該類的無參構造方法如果最後一行錯誤獲取不到錯誤資訊,接下來檢視第二層:
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.itheima.dao.impl.BookDaoImpl]: No default constructor found; nested exception is java.lang.NoSuchMethodException: com.itheima.dao.impl.BookDaoImpl.
<init>
()
nested:巢狀的意思,後面的異常內容和最底層的異常是一致的
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.itheima.dao.impl.BookDaoImpl]: No default constructor found;
看到這其實錯誤已經比較明顯,給大家個練習,把倒數第三層的錯誤分析下吧:
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'bookDao' defined in class path resource [applicationContext.xml]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.itheima.dao.impl.BookDaoImpl]: No default constructor found; nested exception is java.lang.NoSuchMethodException: com.itheima.dao.impl.BookDaoImpl.
<init>
()。
建立bean異常,錯誤建立bean:範例化bean失敗
因為每一個類預設都會提供一個無參建構函式,所以其實真正在使用這種方式的時候,我們什麼也不需要做。這也是我們以後比較常用的一種方式。
接下來研究Spring中的第二種bean的建立方式靜態工廠範例化
:
在講這種方式之前,我們需要先回顧一個知識點是使用工廠來建立物件的方式:
(1)準備一個OrderDao和OrderDaoImpl類
public interface OrderDao { public void save(); } public class OrderDaoImpl implements OrderDao { public void save() { System.out.println("order dao save ..."); } }
(2)建立一個工廠類OrderDaoFactory並提供一個==靜態方法==
//靜態工廠建立物件 public class OrderDaoFactory { public static OrderDao getOrderDao(){ return new OrderDaoImpl(); } }
(3)編寫AppForInstanceOrder執行類,在類中通過工廠獲取物件
public class AppForInstanceOrder { public static void main(String[] args) { //通過靜態工廠建立物件 OrderDao orderDao = OrderDaoFactory.getOrderDao(); orderDao.save(); } }
(4)執行後,可以檢視到結果
如果程式碼中物件是通過上面的這種方式來建立的,如何將其交給Spring來管理呢?
這就要用到Spring中的靜態工廠範例化的知識了,具體實現步驟為:
(1)在spring的組態檔application.properties中新增以下內容:
<bean id="orderDao" class="com.itheima.factory.OrderDaoFactory" factory-method="getOrderDao"/>
class:工廠類的類全名
factory-mehod:具體工廠類中建立物件的方法名
對應關係如下圖:
(2)在AppForInstanceOrder執行類,使用從IOC容器中獲取bean的方法進行執行測試
public class AppForInstanceOrder { public static void main(String[] args) { ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml"); OrderDao orderDao = (OrderDao) ctx.getBean("orderDao"); orderDao.save(); } }
(3)執行後,可以檢視到結果
看到這,可能有人會問了,你這種方式在工廠類中不也是直接new物件的,和我自己直接new沒什麼太大的區別,而且靜態工廠的方式反而更復雜,這種方式的意義是什麼?
主要的原因是:
在工廠的靜態方法中,我們除了new物件還可以做其他的一些業務操作,這些操作必不可少,如:
public class OrderDaoFactory { public static OrderDao getOrderDao(){ System.out.println("factory setup....");//模擬必要的業務操作 return new OrderDaoImpl(); } }
之前new物件的方式就無法新增其他的業務內容,重新執行,檢視結果:
介紹完靜態工廠範例化後,這種方式一般是用來相容早期的一些老系統,所以瞭解為主。
接下來繼續來研究Spring的第三種bean的建立方式範例工廠範例化:
(1)準備一個UserDao和UserDaoImpl類
public interface UserDao { public void save(); } public class UserDaoImpl implements UserDao { public void save() { System.out.println("user dao save ..."); } }
(2)建立一個工廠類OrderDaoFactory並提供一個普通方法,注意此處和靜態工廠的工廠類不一樣的地方是方法不是靜態方法
public class UserDaoFactory { public UserDao getUserDao(){ return new UserDaoImpl(); } }
(3)編寫AppForInstanceUser執行類,在類中通過工廠獲取物件
public class AppForInstanceUser { public static void main(String[] args) { //建立範例工廠物件 UserDaoFactory userDaoFactory = new UserDaoFactory(); //通過範例工廠物件建立物件 UserDao userDao = userDaoFactory.getUserDao(); userDao.save(); }
(4)執行後,可以檢視到結果
對於上面這種範例工廠的方式如何交給Spring管理呢?
具體實現步驟為:
(1)在spring的組態檔中新增以下內容:
<bean id="userFactory" class="com.itheima.factory.UserDaoFactory"/> <bean id="userDao" factory-method="getUserDao" factory-bean="userFactory"/>
範例化工廠執行的順序是:
建立範例化工廠物件,對應的是第一行設定
呼叫物件中的方法來建立bean,對應的是第二行設定
factory-mehod:具體工廠類中建立物件的方法名
(2)在AppForInstanceUser執行類,使用從IOC容器中獲取bean的方法進行執行測試
public class AppForInstanceUser { public static void main(String[] args) { ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml"); UserDao userDao = (UserDao) ctx.getBean("userDao"); userDao.save(); } }
(3)執行後,可以檢視到結果
範例工廠範例化的方式就已經介紹完了,設定的過程還是比較複雜,所以Spring為了簡化這種設定方式就提供了一種叫FactoryBean
的方式來簡化開發。
具體的使用步驟為:
(1)建立一個UserDaoFactoryBean的類,實現FactoryBean介面,重寫介面的方法
public class UserDaoFactoryBean implements FactoryBean<UserDao> { //代替原始範例工廠中建立物件的方法 public UserDao getObject() throws Exception { return new UserDaoImpl(); } //返回所建立類的Class物件 public Class<?> getObjectType() { return UserDao.class; } }
(2)在Spring的組態檔中進行設定
<bean id="userDao" class="com.itheima.factory.UserDaoFactoryBean"/>
(3)AppForInstanceUser執行類不用做任何修改,直接執行
這種方式在Spring去整合其他框架的時候會被用到。
檢視原始碼會發現,FactoryBean介面其實會有三個方法,分別是:
T getObject() throws Exception; Class<?> getObjectType(); default boolean isSingleton() { return true; }
方法一:getObject(),被重寫後,在方法中進行物件的建立並返回
方法二:getObjectType(),被重寫後,主要返回的是被建立類的Class物件
方法三:沒有被重寫,因為它已經給了預設值,從方法名中可以看出其作用是設定物件是否為單例,預設true,從意思上來看,我們猜想預設應該是單例,如何來驗證呢?
思路很簡單,就是從容器中獲取該物件的多個值,列印到控制檯,檢視是否為同一個物件。
public class AppForInstanceUser { public static void main(String[] args) { ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml"); UserDao userDao1 = (UserDao) ctx.getBean("userDao"); UserDao userDao2 = (UserDao) ctx.getBean("userDao"); System.out.println(userDao1); System.out.println(userDao2); } }
列印結果,如下:
通過驗證,會發現預設是單例,那如果想改成單例具體如何實現?
只需要將isSingleton()方法進行重寫,修改返回為false,即可
//FactoryBean建立物件 public class UserDaoFactoryBean implements FactoryBean<UserDao> { //代替原始範例工廠中建立物件的方法 public UserDao getObject() throws Exception { return new UserDaoImpl(); } public Class<?> getObjectType() { return UserDao.class; } public boolean isSingleton() { return false; } }
重新執行AppForInstanceUser,檢視結果
從結果中可以看出現在已經是非單例了,但是一般情況下我們都會採用單例,也就是採用預設即可。所以isSingleton()方法一般不需要進行重寫。
(1)bean是如何建立的呢
構造方法
(2)Spring的IOC範例化物件的三種方式分別是:
構造方法(常用)
靜態工廠(瞭解)
範例工廠(瞭解)
FactoryBean(實用)
這些方式中,重點掌握構造方法和FactoryBean即可。
需要注意的一點是,構造方法在類中預設會提供,但是如果重寫了構造方法,預設的就會消失,在使用的過程中需要注意,如果需要重寫構造方法,最好把預設的構造方法也重寫下。
以上就是Spring中Bean的三種範例化方式詳解的詳細內容,更多關於Spring Bean範例化的資料請關注it145.com其它相關文章!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45