Spring基礎——IOC九種bean聲明方式

来源:https://www.cnblogs.com/zhangyuan1024/archive/2019/12/09/12009141.html
-Advertisement-
Play Games

Spring簡介 Spring不是服務於開發web項目的功能,或業務。而是服務於項目的開發,方便各層間的解耦調用,方便對類的批量管理,是提高軟體開發效率,降低後期維護成本的框架。 Spring的核心思想是IOC(控制反轉),AOP(切麵編程)兩點。 IOC:即不再需要程式員去顯式地`new`一個對象 ...


 

Spring簡介

Spring不是服務於開發web項目的功能,或業務。而是服務於項目的開發,方便各層間的解耦調用,方便對類的批量管理,是提高軟體開發效率,降低後期維護成本的框架。
Spring的核心思想是IOC(控制反轉),AOP(切麵編程)兩點。
IOC:即不再需要程式員去顯式地`new`一個對象,而是把Spring框架把框架創建出的對象拿來用。因為是spring框架創建的對象,對象都在spring框架對象中保存,亦稱為spring容器,這樣spring就知道當前項目中都創建了哪些對象,這個對象歸屬於那一層,該如何管理。想使用spring的其他功能第一點就是要用spring的對象,也稱為將控制權交給spring管理。
AOP:對某種路徑下的所有類,或有共同特性的類或方法統一管理,在原任務執行的前後,加入新功能。做出監控,初始化,整理,銷毀等一系列統一的伴隨動作。
如果你從事Java編程有一段時間了, 那麼你或許會發現(可能你也實際使用過) 很多框架通過強迫應用繼承它們的類或實現它們的介面從而導致應用與框架綁死。這種侵入式的編程方式在早期版本的Struts以及無數其他的Java規範和框架中都能看到。Spring竭力避免因自身的API而弄亂你的應用代碼。Spring不會強迫你實現Spring規範的介面或繼承Spring規範的類,相反,在基於Spring構建的應用中,它的類通常沒有任何痕跡表明你使用了Spring。 最壞的場景是, 一個類或許會使用Spring註解, 但它依舊是POJO。
任何一個有實際意義的應用(肯定比Hello World示例更複雜) 都會由兩個或者更多的類組成, 這些類相互之間進行協作來完成特定的業務邏輯。 按照傳統的做法, 每個對象負責管理與自己相互協作的對象(即它所依賴的對象) 的引用, 這將會導致高度耦合和難以測試的代碼。

IOC聲明Bean

首先創建的Maven Poject,詳細包結構如下

 其中AOP會在下一篇進行講解;

Controller_.java

/**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
        response.getWriter().append("Served at: ").append(request.getContextPath());
        ClassPathXmlApplicationContext ctx=new ClassPathXmlApplicationContext("/ApplicationContext.xml"); 
        Service_ s = (Service_) ctx.getBean("service_Impl1_new");
        System.out.println(s);
        s.show();
    }

由於Spring無法單獨演示,所以Controller_.java是創建的是一個Servlet,直接調用doPost或者doGet方法,進行Service的實現,輸出Service_對象s,執行show方法。

Service_.java

public interface Service_ {
    public void show();
}

創建一個Service介面,用來實現Spring。

1.無參構造方法聲明bean

Service_Impl1.java

public class Service_Impl1 implements Service_{

    
    public Service_Impl1() {
        // TODO Auto-generated constructor stub
        System.out.println("service1-無參構造方法");
    }
    @Override
    public void show() {
        // TODO Auto-generated method stub
        System.out.println("Service_Impl1");
    }

}

重寫Service_的show方法輸出實現了Service_Impl1,編寫無參構造方法。

ApplicationContext.xml

<!-- 預設構造方法 -->
    <bean id="service_Impl1" class="com.zy.spring.service.serviceimpl.Service_Impl1"></bean>

只需要設置id與class,class對應Service_Impl1,id則是Controller_.java調用的getBean中的參數。運行結果見自定義構造方法註入bean

2.自定義構造方法聲明bean

Service_Impl2.java

public class Service_Impl2 implements Service_{

    public Service_Impl2(int a) {
        // TODO Auto-generated constructor stub
        System.out.println("service2-自定義構造參數:"+a);
    }
    @Override
    public void show() {
        // TODO Auto-generated method stub
        System.out.println("Service_Impl2");
    }

}

ApplicationContext.xml

 <!-- 自定義構造方法 -->
     <bean id="service_Impl2" class="com.zy.spring.service.serviceimpl.Service_Impl2">
         <constructor-arg index="0" value="1024"></constructor-arg>
     </bean>

<constructor-arg index="0" value="1024"></constructor-arg>這是構造方法中參數的設置,index顧名思義就是索引的意思,其中a參數是第0個,value是參數的值。

3.單實例 懶載入聲明bean

Service_Impl3.java

public class Service_Impl3 implements Service_{
    public Service_Impl3() {
        // TODO Auto-generated constructor stub
        System.out.println("service3-懶載入 單實例");
    }
    @Override
    public void show() {
        // TODO Auto-generated method stub
        System.out.println("Service_Impl3");
    }

}

ApplicationContext.xml

 <!--  單實例 懶載入 -->
    <bean id="service_Impl3" class="com.zy.spring.service.serviceimpl.Service_Impl3" lazy-init="true" scope="singleton"></bean>

lazy-init="true" 設置懶載入,也就是調用的時候才會載入bean,不會自動載入;scope="singleton" 作用域標簽,單實例也就是只創建一個實例。

4.參數引用聲明bean

Service_Impl4.java

public class Service_Impl4 implements Service_{
    
    Service_ s3;
    
    
    public Service_ getS3() {
        return s3;
    }
    public void setS3(Service_ s3) {
        this.s3 = s3;
    }
    public Service_Impl4() {
        // TODO Auto-generated constructor stub
        System.out.println("service4-參數引用bean");
    }
    @Override
    public void show() {
        // TODO Auto-generated method stub
        System.out.println("Service_Impl4");
    }

}

ApplicationContext.xml

<!-- 參數引用bean -->
    <bean id="service_Impl4" class="com.zy.spring.service.serviceimpl.Service_Impl4">
       <property name="s3" ref="service_Impl3"></property>
    </bean>

<property name="s3" ref="service_Impl3"></property> 參數標簽,name是Service_Impl4中的參數s3,ref鏈接要引用的bean。

5.初始化屬性聲明bean

Service_Impl5.java

public class Service_Impl5 implements Service_{
    String name;
    ArrayList<String> list;
    HashMap<String, String> map;
    HashSet<Integer> set;
    
    
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((list == null) ? 0 : list.hashCode());
        result = prime * result + ((map == null) ? 0 : map.hashCode());
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        result = prime * result + ((set == null) ? 0 : set.hashCode());
        return result;
    }
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Service_Impl5 other = (Service_Impl5) obj;
        if (list == null) {
            if (other.list != null)
                return false;
        } else if (!list.equals(other.list))
            return false;
        if (map == null) {
            if (other.map != null)
                return false;
        } else if (!map.equals(other.map))
            return false;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        if (set == null) {
            if (other.set != null)
                return false;
        } else if (!set.equals(other.set))
            return false;
        return true;
    }
    @Override
    public String toString() {
        return "Service_Impl5 [name=" + name + ", list=" + list + ", map=" + map + ", set=" + set + "]";
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public ArrayList<String> getList() {
        return list;
    }
    public void setList(ArrayList<String> list) {
        this.list = list;
    }
    public HashMap<String, String> getMap() {
        return map;
    }
    public void setMap(HashMap<String, String> map) {
        this.map = map;
    }
    public HashSet<Integer> getSet() {
        return set;
    }
    public void setSet(HashSet<Integer> set) {
        this.set = set;
    }
    
    
    
    public Service_Impl5() {
        // TODO Auto-generated constructor stub
        System.out.println("service5-初始化屬性");
    }
    @Override
    public void show() {
        // TODO Auto-generated method stub
        System.out.println("Service_Impl5");
    }

}

其中初始化參數有list,map,set以及普通參數,重寫了hashCode和equals方法,詳見HashMap記憶體泄漏;重寫toString方法用來輸出初始化屬性。

ApplicationContext.xml

<!--     初始化屬性  -->
     <bean id="service_Impl5" class="com.zy.spring.service.serviceimpl.Service_Impl5">
         <property name="name" value="zy"></property>
         <property name="map">
             <map>
                 <entry key="AAA" value="aaa"></entry>
                 <entry key="BBB" value="bbb"></entry>
             </map>
         </property>
         
         <property name="list">
             <list>
                 <value type="java.lang.String">QQQ</value>
                 <value type="java.lang.String">WWW</value>
             </list>
         </property>
         
         <property name="set">
             <set>
                 <value type="java.lang.Integer">111</value>
                 <value type="java.lang.Integer">222</value>
             </set>
         </property>
     </bean>

其中map標簽內使用<entry key="AAA" value="aaa"></entry>進行賦值。其他的正常使用property和value進行賦值。

6.初始化屬性引用方法返回值聲明bean

Service_Impl6.java

public class Service_Impl6 implements Service_{
    String s5_toString;
    
    
    
    public String getS5_toString() {
        return s5_toString;
    }
    public void setS5_toString(String s5_toString) {
        this.s5_toString = s5_toString;
    }
    
    public Service_Impl6() {
        // TODO Auto-generated constructor stub
        System.out.println("service6-調用方法返回值");
    }
    @Override
    public void show() {
        // TODO Auto-generated method stub
        System.out.println("Service_Impl6 返回值"+s5_toString);
    }

}

其中調用了Service_Impl5的toString方法並且進行了輸出。

ApplicationContext.xml

<!--     調用方法返回值 -->
      <bean id="service_Impl6" class="com.zy.spring.service.serviceimpl.Service_Impl6">
            <property name="s5_toString">
                <bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
                    <property name="targetObject" ref="service_Impl5"></property>
                    <property name="targetMethod" value="toString"></property>
                </bean>
            </property>
      </bean>

<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">固定用來聲明調用方法返回值。

targetObject——目標的bean

targetMethod——目標的方法

7.靜態工廠——聲明工廠bean

Service_Impl7.java

public class Service_Impl7 implements Service_{
    
    public static Service_ StaticFactory(int num) {
        switch (num) {
        case 1:
            return new Service_Impl1();
        case 2:
            return new Service_Impl2(100);
        case 3:
            return new Service_Impl3();
        case 4:
            return new Service_Impl4();
        case 5:
            return new Service_Impl5();
        default:
            return new Service_Impl6();
        }
    }
    
    public Service_Impl7() {
        // TODO Auto-generated constructor stub
        System.out.println("service7-靜態工廠");
    }
    @Override
    public void show() {
        // TODO Auto-generated method stub
        System.out.println("Service_Impl7");
    }

}

工廠在實現類中使用了switch語句進行模擬,靜態工廠在方法前加上static關鍵字,分別調用上面的其他實現類方法。

ApplicationContext.xml

<!--   靜態工廠 -->
       <bean id="service_Impl7" class="com.zy.spring.service.serviceimpl.Service_Impl7" factory-method="StaticFactory" >
               <constructor-arg name="num" value="2"></constructor-arg>
       </bean>

使用構造方法註入的方法來賦值<constructor-arg name="num" value="2"></constructor-arg> ;factory-method="StaticFactory" ( factory-method工廠的方法名)

8.實例工廠——聲明工廠bean

Service_Impl8.java

public class Service_Impl8 implements Service_{
    
    public  Service_ factory1(int num) {
        switch (num) {
        case 1:
            return new Service_Impl1();
        case 2:
            return new Service_Impl2(100);
        case 3:
            return new Service_Impl3();
        case 4:
            return new Service_Impl4();
        case 5:
            return new Service_Impl5();
        default:
            return new Service_Impl6();
        }
    }
    
    public Service_Impl8() {
        // TODO Auto-generated constructor stub
        System.out.println("service8-實例工廠");
    }
    @Override
    public void show() {
        // TODO Auto-generated method stub
        System.out.println("Service_Impl8");
    }

}

ApplicationContext.xml

  <!-- 實例工廠 -->
      <bean id="service_Impl8" class="com.zy.spring.service.serviceimpl.Service_Impl8"  >
       </bean>
    <bean id="service_Impl8_new"  factory-bean="service_Impl8" factory-method="factory1">
        <constructor-arg name="num" value="2"></constructor-arg>
    </bean>

創建實例工廠bean,首先創建一個實例工廠的bean,然後再創建一個工廠方法的bean去調用工廠的bean。

調用的時候要調用工廠方法的bean,這裡就要調用service_Impl8_new

9.註解聲明bean

@Service:用於標註業務層組件
@Controller:用於標註控制層組件(如struts中的action)
@Repository:用於標註數據訪問組件,即DAO組件
@Component(value="*"):泛指組件,當組件不好歸類的時候,我們可以使用這個註解進行標註

Service_Impl9.java

@Service
public class Service_Impl9 implements Service_{

    
    public Service_Impl9() {
        // TODO Auto-generated constructor stub
        System.out.println("service9-註解註入bean");
    }
    @Override
    public void show() {
        // TODO Auto-generated method stub
        System.out.println("Service_Impl9");
    }

}

@Service進行bean的聲明(註解只能聲明無參構造方法),使用註解預設聲明的bean是類名的首字母小寫,這裡聲明的bean的id應該是service_Impl9。

ApplicationContext.xml

 <!-- 註解掃描IOC根目錄 -->
        <context:component-scan base-package="com.zy.spring"> 
     <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/><!-- 掃描不包括controller -->
    </context:component-scan>

使用註解需要加上註解掃描,其中base-package是掃描的目錄,一般使用的是項目的根目錄,以後使用SpringMVC的話,就不用掃描Controller。

 註解寫入bean

@Resource(name="*" type="*")bean寫入
@Autowired/@Qualifier
@inject/@named

 

 


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

-Advertisement-
Play Games
更多相關文章
  • 如何獲取頁面元素 根據ID獲取 使用getElementById()方法可以獲取帶ID的元素對象 因為文檔頁面從上往下載入,所以先得有標簽,script寫在標簽的下麵 get 獲取 element 元素 by 通過 駝峰命名法 參數 id 是大小寫敏感的字元串 返回一個元素對象 console.di ...
  • 關於github page 創建子功能變數名稱以及https 認證 ...
  • 今天聽課聽到了Math對象中的隨機數方法random(),然後就想用它設計一個簡單的隨機點名系統。我記得之前高中的時候語文老師用過一個,是類似於名字滾動的那種,現在太菜就先不考慮這個了,後續有機會再研究吧。 先展示一下最終的效果圖。 下麵是html代碼部分 1 <!DOCTYPE html> 2 < ...
  • 下麵是常見的命名參考規範: ❤ 主體 頭部:header 內容:content/container 尾部:footer 導航:nav 側欄:sidebar 欄目:column 整體佈局:wrapper 左右中:left / right / center 登錄條:loginbar 標誌:logo 廣告 ...
  • Vue的組件是可復用的 Vue 實例,且帶有一個名字 。我們可以在一個通過 new Vue 創建的 Vue 根實例中,把這個組件作為自定義元素來使用。因為組件是可復用的 Vue 實例,所以它們與 new Vue 接收相同的選項,例如 data、computed、watch、methods 以及生命周... ...
  • CSS的基本使用 直接寫在標簽內 寫在 style 標簽內 使用外部 .css 文件 @import (不建議使用此方式) link CSS選擇器 優先順序:id選擇器 class 選擇器 標簽選擇器 標簽選擇器:標簽名{} class選擇器(“.”符號):.class名{} id選擇器(“ ”符號, ...
  • react-starter-projects These are repositories that you copy and modify to create your own React app. Pick a starter project with all the features you ...
  • 本文在 "個人主頁" 同步更新~ 背就完事了 介紹:一些知識點相關的面試題和答案 使用姿勢: 看答案前先嘗試回答,看完後把答案收起來檢驗成果~ 面試官:如何理解JS的作用域和作用域鏈 答:在ES5中,只有全局作用域和局部作用域。ES6因為let,const的引入而有了塊作用域。js在瀏覽器中的頂級作 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...