spring 裝配bean的三種方式

来源:https://www.cnblogs.com/maxshare/archive/2019/03/10/10467761.html
-Advertisement-
Play Games

這段時間在學習Spring,依賴註入DI和麵向切麵編程AOP是Spring框架最核心的部分。這次主要是總結依賴註入的bean的裝配方式。 什麼是依賴註入呢?也可以稱為控制反轉,簡單的來說,一般完成稍微複雜的業務邏輯,可能需要多個類,會出現有些類要引用其他類的實例,也可以稱為依賴其他類。傳統的方法就是 ...


這段時間在學習Spring,依賴註入DI和麵向切麵編程AOP是Spring框架最核心的部分。這次主要是總結依賴註入的bean的裝配方式。

什麼是依賴註入呢?也可以稱為控制反轉,簡單的來說,一般完成稍微複雜的業務邏輯,可能需要多個類,會出現有些類要引用其他類的實例,也可以稱為依賴其他類。傳統的方法就是直接引用那個類對象作為自己的一個屬性,但如果我們每次創建這個類的對象時,都會創建依賴的類的對象,還有如果那個類將來可能不用了,還需要到這個類去刪除這個對象,那破壞了代碼的復用性和導致高度耦合

依賴註入的出現可以很好地解決這個問題,依賴註入就是由系統負責協調類的依賴對象的創建,我們無需自己去顯示的創建依賴對象,而是由系統給我們註入這個對象,系統控制了這個對象的創建,也稱為控制反轉。


 

Spring給我們註入對象有三種方式:

  • 隱式的bean掃描發現機制和自動裝配
  • 在java中進行顯示配置
  • 在XML中進行顯示配置

第一種:

spring從兩個角度實現自動化裝配:組件掃描和自動裝配。

當對一個類標註@Component註解時,表明該類會作為組件類,spring將為這個類創建bean。當在應用文中引用這個bean,spring會自動掃描事先指定的包查找這個 bean。但spring預設是不啟用組件掃描的,可以在XML中配置加上<context:component-scan base-package="xx"/>。還有一種方法:在新建一個配置類,類中可以什麼不用寫,在配置類上加上@ComponentScan註解,spring會自動掃描改配置類所在的包,一般應該傾向xml配置。下麵是一個bbs論壇系統用戶發帖的功能小例子:

 1 package bbs.dao;
 2 @Component
 3 public interface Postdao {
 4     /*
 5      *用戶發帖 ,post表添加帖子信息
 6      */
 7     public int addpost(@Param("title") String title,@Param("content") String content,@Param("userid") int userid);
 8 }
 9 
10 package bbs.dao;
11 @Component
12 public interface Userdao {
13     /*
14      * 用戶發帖後,user表將用戶發帖數加一
15      */
16     public int addpost(int userid);
17 }

再在bbs.service包中創建一個postservice介面及其實現類,依賴Postdao和Userdao。

 1 package bbs.service;
 2 public interface PostService {
 3     /*
 4     用戶發帖後,先添加帖子信息再更新用戶發帖數量
 5     */
 6     public void addpost(String title,String content,int userid);
 7 }
 8 
 9 package bbs.service;
10 @Component
11 public class PostserviceImpl implements PostService {
12 
13     private Postdao postdao;
14     private Userdao userdao;
15 
16 //    @Autowired
17 //    public void setPostdao(Postdao postdao)
18 //    {
19 //        this.postdao=postdao;
20 //    }
21 //
22 //    @Autowired
23 //    public void setUserdao(Userdao userdao)
24 //    {
25 //        this.userdao=userdao;
26 //    }
27 
28     @Autowired
29     public PostserviceImpl(Postdao postdao,Userdao userdao)
30     {
31         this.userdao=userdao;
32         this.postdao=postdao;
33     }
34 
35     public void addpost(String title, String content, int userid) {
36         int i=postdao.addpost(title, content, userid);
37         int j=userdao.addpost(userid);
38         if(i==1&j==1)
39             System.out.println("發帖成功");
40         else
41             System.out.println("發帖失敗");
42     }
43 }

@Component在介面實現上註解就可以,但發現在userdao、postdao介面也加上了,其實可以去掉,因為我採用mybatis在xml中配置資料庫的操作,動態實現dao介面。等下會提到。上面代碼出現的@Autowired註解實現bean自動裝配,會在spring應用上下文中的組件類尋找需求的bean。一般有兩種裝配方式:構造器和Setter方法(其他方法名也行,只要能夠使註入的bean成為這個類的屬性就行)

也可能出現spring沒有查找到匹配的bean會拋出異常,在@Autowired加上required=false,如果沒有匹配的bean時,spring會使這個bean處於未裝配的狀態,沒有裝配成功。還有可能會出現相同名字的bean有很多個,會產生歧義,一般在組件類上添加註解@Qualifier()括弧寫這個bean的id,在註入時也加上@Qualifier(),寫上bean的id。像下麵:

 1 @Component
 2 @Qualifier("postdao")
 3 public interface Postdao{
 4 . . . .     
 5 }
 6  
 7 @Component
 8 @Qualifier("userdao")
 9 public interface Userdao{
10 . . . . 
11 }
12 
13 @Autowired
14 @Qualifier("usedao")
15 public void setUserdao(Userdao userdao)
16 {. . . 
17 }
18  
19 @Autowired
20 @Qualifier("postdao")
21 public void setUserdao(Postdao postdao)
22 {. . . 
23 }

由於java不允許在同一個條目上重覆出現相同類型的多個註解,所有註入採用set方式。但是其實可以創建自定義的限定符註解。這裡就不介紹啦。

 

第二種:

通過java代碼裝配bean

一般通過組件掃描和自動裝配方式就比較方便了,但如果由於需求我們要使用第三方的庫的類,在這種情況沒有辦法到第三方庫中去給類加註解,就不能使用第一種方法了。這時得採用顯示裝配,可以採用java代碼或xml顯示裝配bean。使用java代碼,先新建一個配置類JavaConfig,裡面都是配置所需的bean,不應該有業務邏輯代碼,所以單獨建一個類。

@Configuration
@ContextConfiguration(
locations = {"classpath:spring/spring-dao.xml","classpath:scan.xml"})
public class bbsConfig{
  private Postdao postdao;
  private Userdao userdao;
  @Bean(name="postservice")
public PostService getPost()
  {
  return new PostserviceImpl(postdao,userdao);
  }

在對PostService的bean註入時,同時又依賴了兩個bean,postdao和userdao。直接引用beanID就可以,spring會自動地從容器中獲取這些bean,只要他們的配置是正確的就行。這個例子中userdao、postdao是Mybatis配置自動掃描將dao介面生成代理註入到spring的,其實也算是xml裝配bean。可參考這篇文章,寫的挺清楚的。 https://bijian1013.iteye.com/blog/2318860

這裡如果再聲明一個bean,返回的仍是postserviceImpl對象,和之前的那個bean完全一樣,是同一個實例。一般spring@bean如果是同一個beanID,預設返回的是一個單例bean,註入的是同一個實例。如果修改其中一個會都改變的。

不過在這裡要註意進行測試時,由於spring的單元測試和springIoc容器是完全獨立的,postdao和userdao註入檢測時是使用locations載入xml文件,而postservice使用classes載入config類的,但是兩個不能同時混用在@ContextConfiguration中。所以非要都測試的話,就分開測試吧。

 

第三種:

在XML中裝配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
            http://www.springframework.org/schema/context">
    <import resource="spring/spring-dao.xml"/>

    <bean id="postservice" class="com.bbs.service.impl.PostserviceImpl">
          <constructor-arg ref="postdao"/>
            <constructor-arg ref="userdao"/>
    </bean>
</beans>

配置postservice的bean時需要引入兩個bean,postdao和userdao,放到constructor-arg的標簽中,ref指的是依賴的bean的ID。如果是在javaConfig中配置的,就寫@Bean的內容。如果是@Component就寫@Qualifier的內容。這裡是引入的是動態實現的dao介面的bean,是在spring-dao.xml中配置的,引入這個配置文件就可以自動獲得beanID。


 混合使用三種裝配:

1.在類上可以使用@ import(bbsConfig.class)組合其他java註解

2.在類上使用@ imortResource("classpath:spring-dao.xml")組合其他xml註解

3.在類上可以使用@ContenxtConfiguration包含class或者xml

4.在xml中可以用<import resource="spring-dao.xml">引入xml註解,也可以使用<bean class="com.bbs.dao.Userdao">引入java註解

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 在學習 的時候,發現有很多使用 開發的ui組件。本著學習的目的,自己也仿照 "Element" 寫一些組件。 使用 "VuePress" 編寫組件文檔。 單元測試: +`mocha chai sinon`。 文檔預覽地址: "預覽鏈接" 使用 編輯文檔的代碼訪問: "組件文檔" 關於 使用方法: " ...
  • 背景 "對現有開源項目的代碼進行翻譯(文件名/命名/註釋) · Issue 107 · program in chinese/overview" 簡單地說, 通過翻譯源碼, 提高項目代碼可讀性(對於母語為中文的開發者). 併在此過程中小結源碼翻譯輔助工具的需求. 源碼庫分支: "program in ...
  • 2019-03-10/21:12:31 參考博客:MiroKlose AOP術語 1.通知: 通知定義了切麵要完成的工作內容和何時完成工作,就是什麼時候去做輔助功能,功能具體是什麼代碼 五種類型 Before——在方法調用之前調用通知 After——在方法完成之後調用通知,無論方法執行成功與否 Af ...
  • MVC、MVP和MVVM這些開發模式為了分離視圖(View)和模型(Model)而提出來的,直白說就是為了前後端分離。 1. MVC(Model View Controller)模式 MVC是比較直觀的架構模式,即用戶操作 → View(負責接收用戶的輸入操作)→ Controller(業務邏輯處理 ...
  • 微服務架構的概述 應用架構的發展 應用是可以獨立運行的程式代碼,提供相對完善的業務功能. 目前的軟體架構有三種架構類型: 業務架構 應用架構 技術架構 他們之間的甚是: 業務架構決定應用架構,技術架構支撐著應用架構. 應用架構的發展歷程: 單體架構: 最古老的單體應用,沒有任何應用拆分,整體就是一個 ...
  • 由於拷貝後文檔格式有變, 僅摘幾段如下. 完整而且代碼帶語法高亮的源版在: "program in chinese/Programming_in_Scala_study_notes_zh" 前言: 本書已有中文版, 此筆記並不是對原教程的翻譯, 而是圍繞示例進行選摘, 並順便將所有示例改成中文命名( ...
  • 註: 本文僅對個人嘗試作一小結, 專欄中其他作者的嘗試還望各自總結 對自研中文編程語言的嘗試也許始於 "2015年" 對CoffeeScript的部分關鍵詞漢化和 "Java實現的彙編語言編譯器" 的開發. "2017年10月那場請求C 提供漢化版的討論" 也給了更多的動力. 之後對 "開源非英文關 ...
  • 報這個錯誤是因為我的 application_context.service.xml 文件里的的dubbo聲明暴露口時的ref屬性寫錯了。 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...