Spring bean三種創建方式

  spring共提供了三種實例化bean的方式:構造器實例化(全類名,反射)、工廠方法(靜態工廠實例化 ? 動態工廠實例化)和FactoryBean ,下面一一詳解:

?

1、構造器實例化

City.java

 1 package com.proc.bean;
 2 
 3 public class City {
 4 
 5     private String name;
 6     private String code;
 7     
 8     public City() {
 9     }
10 
11     public City(String name, String code) {
12         this.name = name;
13         this.code = code;
14     }
15 
16     public String getName() {
17         return name;
18     }
19 
20     public void setName(String name) {
21         this.name = name;
22     }
23 
24     public String getCode() {
25         return code;
26     }
27 
28     public void setCode(String code) {
29         this.code = code;
30     }
31 
32     @Override
33     public String toString() {
34         return "City [name=" + name + ", code=" + code + "]";
35     }
36 }

?

通過構造方式配置Bean

1 <bean id="city" class="com.proc.bean.City">
2     <constructor-arg value="北京"/>
3     <constructor-arg value="BJ"/>
4 </bean>

?

測試代碼

1 ApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext.xml");
2 City city=ctx.getBean("city", City.class);
3 System.out.println(city);

輸出結果

City [name=北京, code=BJ]

?

2、靜態工廠實例化

  先創建一個靜態工廠StaticCityFactory

 1 package com.proc.bean;
 2 
 3 import java.util.HashMap;
 4 import java.util.Map;
 5 
 6 public class StaticCityFactory {
 7     
 8     private static Map<String, City> cities;
 9     
10     static{
11         cities=new HashMap<String, City>();
12         cities.put("BJ", new City("北京", "BJ"));
13         cities.put("SH", new City("上海", "SH"));
14         cities.put("CD", new City("成都", "CD"));
15         cities.put("SZ", new City("深圳", "SZ"));
16     }
17 
18     public static City getCity(String code){
19         return cities.get(code);
20     }
21 }

?

  配置bean

1 <!-- 通過靜態工廠實例化對象
2     class:靜態工廠類型
3     factory-method:靜態工廠靜態方法名稱
4     constructor-arg:為靜態工廠方法指定參數
5  -->
6 <bean id="city" class="com.proc.bean.StaticCityFactory" factory-method="getCity">
7     <constructor-arg value="BJ"/>
8 </bean>

?

3、動態工廠實例化

  先創建一個實例化工廠

 1 package com.proc.bean;
 2 
 3 import java.util.HashMap;
 4 import java.util.Map;
 5 
 6 public class InstanceCityFactory {
 7     
 8     private Map<String, City> cities;
 9     {
10         cities=new HashMap<String, City>();
11         cities.put("BJ", new City("北京", "BJ"));
12         cities.put("SH", new City("上海", "SH"));
13         cities.put("CD", new City("成都", "CD"));
14         cities.put("SZ", new City("深圳", "SZ"));
15     }
16     
17     public City getCity(String code){
18         return cities.get(code);
19     }
20 }

  配置

1 <!-- 配置實例化工廠 -->
2 <bean id="cityFacotry" class="com.proc.bean.InstanceCityFactory"/>
3  
4  <!-- 通過實例化工廠獲取對象 -->
5 <bean id="city" factory-bean="cityFacotry" factory-method="getCity">
6     <constructor-arg value="SH"/> <!-- 配置參數 -->
7 </bean>

?

4、FactoryBean

  

? ?一般情況下,Spring 通過反射機制利用 <bean> 的 class 屬性指定實現類實例化 Bean ,在某些情況下,實例化 Bean 過程比較復雜,如果按照傳統的方式,則需要在 <bean> 中提供大量的配置信息。配置方式的靈活性是受限的,這時采用編碼的方式可能會得到一個簡單的方案。 Spring 為此提供了一個org.springframework.bean.factory.FactoryBean 的工廠類接口,用戶可以通過實現該接口定制實例化 Bean 的邏輯。

  FactoryBean接口對于 Spring 框架來說占用重要的地位, Spring 自身就提供了 70 多個 FactoryBean 的實現。它們隱藏了實例化一些復雜 Bean 的細節,給上層應用帶來了便利。從 Spring 3.0 開始, FactoryBean 開始支持泛型,即接口聲明改為 FactoryBean<T> 的形式:

1 public interface FactoryBean<T> {  
2     T getObject() throws Exception;  
3     Class<?> getObjectType();  
4     boolean isSingleton();  
5 }

  在該接口中還定義了以下3 個方法:

    T getObject():返回由 FactoryBean 創建的 Bean 實例,如果 isSingleton() 返回 true ,則該實例會放到Spring 容器中單實例緩存池中;

    boolean isSingleton():返回由 FactoryBean 創建的 Bean 實例的作用域是 singleton 還是 prototype ;

    Class<T> getObjectType():返回 FactoryBean 創建的 Bean 類型。

  當配置文件中<bean> 的 class 屬性配置的實現類是 FactoryBean 時,通過 getBean() 方法返回的不是FactoryBean 本身,而是 FactoryBean#getObject() 方法所返回的對象,相當于 FactoryBean#getObject() 代理了getBean() 方法。

?

  例:如果使用傳統方式配置下面Car 的 <bean> 時, Car 的每個屬性分別對應一個 <property> 元素標簽。

 1 public class Car {
 2     private int maxSpeed;
 3     private String brand;
 4     private double price;
 5     public int getMaxSpeed() {
 6         return this.maxSpeed;
 7     }
 8     public void setMaxSpeed(int maxSpeed) {
 9         this.maxSpeed = maxSpeed;
10     }
11     public String getBrand() {
12         return this.brand;
13     }
14     public void setBrand(String brand) {
15         this.brand = brand;
16     }
17     public double getPrice() {
18         return this.price;
19     }
20     public void setPrice(double price) {
21         this.price = price;
22     }
23 }

  如果用FactoryBean 的方式實現就靈活點,下例通過逗號分割符的方式一次性的為 Car 的所有屬性指定配置值:

public class CarFactoryBean implements FactoryBean<Car> {private String carInfo;public Car getObject() throws Exception {Car car = new Car();String[] infos = carInfo.split(",");car.setBrand(infos[0]);car.setMaxSpeed(Integer.valueOf(infos[1]));car.setPrice(Double.valueOf(infos[2]));return car;}public Class<Car> getObjectType() {return Car.class;}public boolean isSingleton() {return false;}public String getCarInfo() {return this.carInfo;}// 接受逗號分割符設置屬性信息public void setCarInfo(String carInfo) {this.carInfo = carInfo;}
}

  有了這個CarFactoryBean 后,就可以在配置文件中使用下面這種自定義的配置方式配置 Car Bean 了:

1 <bean id="car" class="com.baobaotao.factorybean.CarFactoryBean">
2     <property name="carInfo" value="法拉利 ,400,2000000"/>
3 </bean>

  當調用getBean("car") 時, Spring 通過反射機制發現 CarFactoryBean 實現了 FactoryBean 的接口,這時Spring 容器就調用接口方法 CarFactoryBean#getObject() 方法返回。如果希望獲取 CarFactoryBean 的實例,則需要在使用 getBean(beanName) 方法時在 beanName 前顯示的加上 "&" 前綴:如 getBean("&car");

轉載于:https://www.cnblogs.com/caoyc/p/5624697.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/256908.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/256908.shtml
英文地址,請注明出處:http://en.pswp.cn/news/256908.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Excel使用控件創建動態地圖圖表

[本文軟件Excel 2010] 效果圖&#xff1a; 首先我們看一下數據源 數據源中第二列是對應圖形的名稱。首先創建圖形&#xff0c;我們可能在網絡中找到各個地圖的矢量圖形。不過不是每個地圖圖形都適合我們&#xff0c;或許企業劃分非按照行政區劃分。因此可以嘗試自己繪制&#x…

Windows 10 常用的快捷鍵及常用指令

系統快捷鍵 快捷鍵功能說明備注CtrlShiftEsc打開任務管理器macbook: fnshiftF11普通鍵盤: PrintScreen截屏幕圖macbook: fnshiftoptionF11普通鍵盤: altPrintScreen截取當前窗口圖片macbook: WinfnEsc普通鍵盤: WinPause/Break打開系統屬性WinctrlD新建虛擬桌面Windows 10Winct…

學習筆記(35續):Python網絡編程并發編程-基于gevent及線程池實現的并發套接字通訊

1.基于線程池實現并發套接字通訊&#xff1a;因為套接字涉及地是I/O密集模型&#xff0c;因此使用多線程會有高效率 服務器 #基于線程池完成并發的套接字通訊 from socket import * from threading import Thread from concurrent.futures import ThreadPoolExecutordef commun…

使用Configuration Manager部署及管理軟件更新(2)

承接上一篇文章&#xff1a;http://ericxuting.blog.51cto.com/8995534/1543835 一、 確定軟件更新符合性 1. 打開Configuration Manager管理控制臺&#xff0c;點擊軟件庫&#xff0c;展開軟件更新&#xff0c;點擊所有軟件更新 2. 點擊主頁中的運行摘要&#xff0c;等待對話框…

NULL、nil、Nil、NSNull的區別

標志值含義NULL&#xff08;void *&#xff09;0C指針的字面零值nil&#xff08;id&#xff09;0Objecve-C對象的字面零值Nil&#xff08;Class&#xff09;0Objecve-C類的字面零值NSNull[NSNull null]用來表示零值的單獨的對象轉載于:https://www.cnblogs.com/wlsxmhz/p/56250…

Fiddler 域名過濾

原來一直沒意識到Fiddler過濾&#xff0c;導致每次抓包都要自己判斷、搜索好多東西&#xff0c;真是呵呵&#xff01; 過濾設置很簡單&#xff0c;看懂一張圖就解決問題了。 箭頭 那兩處設置下&#xff0c;圓圈處保存再進行抓包即可 轉載于:https://www.cnblogs.com/eejron/p/4…

windows中VS卸載opencv配置,重新安裝其他版本

1、找到工程的屬性管理器&#xff0c;電機Debug64和Release64下面的 包含目錄和庫目錄&#xff0c;刪掉其原由配置的oepncv路徑&#xff1b; 找到鏈接器中的附加依賴項&#xff0c;刪掉原有的配置&#xff1b;

學習筆記(36):Python網絡編程并發編程-IO模型介紹

立即學習:https://edu.csdn.net/course/play/24458/296460?utm_sourceblogtoedu I/O模型介紹&#xff1a;I/O模型表示處于等待狀態的模型&#xff0c;如套接字通訊的accept和recv函數一樣 1.同步I/O 2.異步I/O 3.阻塞I/O 4.非阻塞I/O

AD9 如何畫4層pcb板

新建的PCB文件默認的是2層板&#xff0c;教你怎么設置4層甚至更多層板。在工具欄點擊Design-->Layer Stack Manager.進入之后顯示的是兩層板&#xff0c;添加為4層板&#xff0c;一般是先點top layer, 再點Add Layer,再點Add Layer&#xff0c;這樣就成了4層板。見下圖。 有…

gulp 流處理

包含的內容&#xff1a; 穿插流流合并流隊列流篩選1. 穿插流// passthrough stream 把流傳遞給其他的// usegulp.src(glob,{passthrough:true})// function 進行流的合并處理&#xff0c;避免多余配置以及冗余代碼 2. 合并流// 使用merge2// install yarn add merge2 or …

windows上使用cmake 編譯yaml-cpp源碼,生成yam-cpp.lib

1、打開cmake-gui 2、添加CmakeList 3、建立build 4、進入工程中生成debug和release版本的lib

BZOJ 3039: 玉蟾宮( 懸線法 )

最大子矩陣...懸線法..時間復雜度O(nm)懸線法就是記錄一個H向上延伸的最大長度(懸線), L, R向左向右延伸的最大長度, 然后通過遞推來得到. ------------------------------------------------------------------#include<bits/stdc.h>using namespace std;#define ok(c) …

學習筆記(37):Python實戰編程-yield實現生成器

立即學習:https://edu.csdn.net/course/play/19711/255579?utm_sourceblogtoedu1.yield return generator yield是一個返回的是一個生成器對象&#xff0c;是通過next函數一次一次地進行函數地迭代來獲取結果的&#xff0c;而return函數則是將結果返回后&#xff0c;不再與…

ie6、7 下input的邊框問題 ?

input的border設置為none,ie8及以上border都兼容&#xff0c;ie6和7的border還繼續存在&#xff0c;將border設為0時所有瀏覽器上都不存在了&#xff0c;但是border為0時還是會繼續的渲染。 將input的border設為"0 none",ie7及以上都正常了&#xff0c;但是ie6上inpu…

Mocha BSM產品亮點——關聯事件分析

業務需求與挑戰企業經常會遇到下列場景&#xff1a;? 企業某應用&#xff0c;例如&#xff0c;WebSphere Portal Server&#xff0c;已經不可用&#xff0c;是由于應用自身已不可用&#xff1f;還是應用所連接的數據庫出了問題&#xff1f;還是應用的LDAP服務不可用&#xff1…

輕量級文本編輯器,Notepad最佳替代品:Notepad++

目錄 正文之前1. 目的2. 原帖3. 為何推薦Notepad3.1. Notepad的一些基本特點3.2. notepad&#xff0c;notepad2&#xff0c;notepad&#xff0c;ultraEdit比較4. 使用Notepad前要了解的知識4.1. Notepad的名稱和縮寫4.2. Notepad修改設置后&#xff0c;立即生效4.3. Notepad的版…

學習筆記(38):Python實戰編程-窗體顯示

立即學習:https://edu.csdn.net/course/play/19711/343100?utm_sourceblogtoedu GUI&#xff1a;圖形用戶接口——GUI組件&#xff0c;組件定義&#xff0c;組件布局管理 主體窗口的設置&#xff1a; import tkinter#導入創建窗體的相關模塊class Mainwindow():#創建窗口類de…

Tomcat 配置和spring-framework MVC配置簡介

Tomcat啟動時&#xff0c;先找系統變量CATALINA_BASE&#xff0c;如果沒有&#xff0c;則找CATALINA_HOME。然后找這個變量所指的目錄下的conf文件夾&#xff0c;從中讀取配置文件。最重要的配置文件&#xff1a;server.xml 。要配置tomcat&#xff0c;基本上了解server.xml&am…

SDL 庫 無法解析的外部符號 __imp__fprintf

VS2015 在鏈接器-》命令行 里加入legacy_stdio_definitions.lib 另外一個常見錯誤關于stderr的用 extern "C" { FILE __iob_func[3] { *stdin,*stdout,*stderr }; }轉載于:https://www.cnblogs.com/zhaogaojian/p/5646885.html

ultra edit ftp帳號管理導入導出方法

在更換電腦或ultra edit新安裝時往往需要將原來使用的ftp帳號導入過來&#xff0c;可以在高級-備份/恢復用戶定制-選中其他保存備份&#xff0c;拷貝出來然后再導入。 也可以在配置-ftp/sftp中保存&#xff0c;拷貝出來然后在安裝好后配置。 步驟1. 導出ftp帳號信息&#xff1a…