詳解Spring?Bean的配置方式與實(shí)例化
一、 Spring Bean 配置方式
由 Spring IoC 容器管理的對(duì)象稱為 Bean,Bean 配置方式有兩種:配置文件開發(fā)和注解開發(fā)
配置文件開發(fā)
Spring 配置文件支持兩種格式:xml和properties,此教程以xml配置文件講解。
XML 配置文件的根元素是 <beans>,該元素包含了多個(gè)子元素 <bean>。每一個(gè) <bean> 元素都定義了一個(gè) Bean

XML 配置文件常用元素表
| 屬性名稱 | 描述 |
|---|---|
| id | Bean 的唯一標(biāo)識(shí)符,Spring IoC 容器對(duì) Bean 的配置和管理都通過該屬性完成。 |
| name | Bean 的別名,可以通過 name 屬性為同一個(gè) Bean 同時(shí)指定多個(gè)名稱,每個(gè)名稱之間用逗號(hào)或分號(hào)隔開。 |
| class | 指定了Bean 的具體實(shí)現(xiàn)類,它必須是一個(gè)類的全限定名。 |
| scope | Bean 的作用域,屬性值可以為 singleton(單例)、prototype(原型)、request、session 和 global Session。默認(rèn)值是 singleton。 |
注解開發(fā)
先插個(gè)眼在這,過幾天會(huì)發(fā)一篇文章詳細(xì)介紹
二、Spring Bean實(shí)例化
通過控制反轉(zhuǎn),對(duì)象的創(chuàng)建權(quán)就交給了IoC容器,但是容器是如何來創(chuàng)建對(duì)象的呢?
bean本質(zhì)上就是對(duì)象,對(duì)象在new的時(shí)候會(huì)使用構(gòu)造方法,創(chuàng)建bean其實(shí)也是使用構(gòu)造方法完成的。
實(shí)例化bean的三種方式:構(gòu)造方法,靜態(tài)工廠和實(shí)例工廠
環(huán)境準(zhǔn)備
1.準(zhǔn)備一個(gè)UserDao接口和一個(gè)UserDaoImpl實(shí)現(xiàn)類
//UserDao接口
public interface UserDao {
public void say();
}
//UserDaoImpl實(shí)現(xiàn)類
public class UserDaoImpl implements UserDao {
@Override
public void say() {
System.out.println("Hello,I am BigHorn!");
}
}
2.編寫spring配置文件
<bean id="userDao" class="com.bighorn.dao.impl.UserDaoImpl"/>
3.編寫運(yùn)行程序
public class App {
public static void main(String[] args) {
//獲取IoC容器
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
//從容器中獲取對(duì)象
UserDaoImpl userDao = context.getBean("userDao", UserDaoImpl.class);
userDao.say();
}
}
構(gòu)造方法實(shí)例化Bean
第一種實(shí)例化bean的方法:構(gòu)造方法實(shí)例化,這也是最常用的方法,因?yàn)轭惗紩?huì)提供默認(rèn)的構(gòu)造方法。下面來測(cè)試下
1.在UserDaoImpl類中添加一個(gè)無參構(gòu)造方法,并打印一句話,方便觀察結(jié)果。
public class UserDaoImpl implements UserDao {
//添加一個(gè)無參構(gòu)造方法
public UserDaoImpl() {
System.out.println("這是UserDaoImpl的無參構(gòu)造方法");
}
@Override
public void say() {
System.out.println("Hello,I am BigHorn!");
}
}
可以在控制臺(tái)看到輸出結(jié)果,說明Spring IoC 容器創(chuàng)建對(duì)象時(shí)用的也是構(gòu)造方法

2.將構(gòu)造方法改成private測(cè)試
public class UserDaoImpl implements UserDao {
//將構(gòu)造方法改成private
private UserDaoImpl() {
System.out.println("這是UserDaoImpl的無參構(gòu)造方法");
}
@Override
public void say() {
System.out.println("Hello,I am BigHorn!");
}
}
發(fā)現(xiàn)還可以運(yùn)行成功,這說明Spring底層用的是反射,訪問到類中的私有構(gòu)造方法。

3.將無參構(gòu)造方法換成有參構(gòu)造方法
public class UserDaoImpl implements UserDao {
//將無參構(gòu)造方法換成有參構(gòu)造方法
private UserDaoImpl(int i) {
System.out.println("這是UserDaoImpl的無參構(gòu)造方法");
}
@Override
public void say() {
System.out.println("Hello,I am BigHorn!");
}
}
程序會(huì)報(bào)java.lang.NoSuchMethodException錯(cuò),說明Spring底層使用的是類的無參構(gòu)造方法。

4.畫個(gè)圖總結(jié)下:Spring 配置文件中 bean 標(biāo)簽的 id 和類的全限定名一一對(duì)應(yīng),所以 Spring IoC容器的 getBean 方法其實(shí)就是先根據(jù) bean 的 id 獲取該類的全限定名,然后再利用反射根據(jù)類的全限定名創(chuàng)建對(duì)象并返回。

靜態(tài)工廠實(shí)例化Bean
第二種實(shí)例化Bean的方法:靜態(tài)工廠實(shí)例化
了解即可,一般是用來兼容早期的一些老系統(tǒng)。
1.創(chuàng)建一個(gè)UserDaoFactory工廠類并提供一個(gè)靜態(tài)方法
//UserDao接口
public interface UserDao {
public void say();
}
//UserDaoImpl實(shí)現(xiàn)類
public class UserDaoImpl implements UserDao {
public UserDaoImpl() {
System.out.println("這是UserDaoImpl的無參構(gòu)造方法");
}
@Override
public void say() {
System.out.println("Hello,I am BigHorn!");
}
}
//UserDaoFactory工廠類
public class UserDaoFactory {
//靜態(tài)工廠創(chuàng)建對(duì)象
public static UserDao getUserDao(){
System.out.println("這是靜態(tài)工廠實(shí)例化Bean");
return new UserDaoImpl();
}
}
2.編寫spring配置文件
<!--
class:工廠類全類名
factory-method:工廠創(chuàng)建對(duì)象的方法名
-->
<bean id="userDao" class="com.bighorn.factory.UserDaoFactory" factory-method="getUserDao"/>
3.編寫運(yùn)行程序
public class App {
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
//獲取IoC容器
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
//從容器中獲取對(duì)象
UserDaoImpl userDao = context.getBean("userDao", UserDaoImpl.class);
userDao.say();
}
}
看見運(yùn)行結(jié)果,輸出以下語句

實(shí)例工廠實(shí)例化Bean
第二種實(shí)例化Bean的方法:實(shí)例工廠實(shí)例化
了解即可,其實(shí)和靜態(tài)工廠差不多。只不過靜態(tài)工廠可以直接通過靜態(tài)方法創(chuàng)建bean,實(shí)例工廠要先new一個(gè)實(shí)例工廠對(duì)象,然后再通過這個(gè)實(shí)例工廠對(duì)象創(chuàng)建bean
1.創(chuàng)建一個(gè)UserDaoFactory工廠類,和靜態(tài)工廠不一樣的是,實(shí)力工廠提供的是一個(gè)普通方法
//UserDaoFactory工廠類
public class UserDaoFactory {
//實(shí)例工廠創(chuàng)建對(duì)象
public UserDao getUserDao(){
System.out.println("這是實(shí)例工廠實(shí)例化Bean");
return new UserDaoImpl();
}
}2.編寫spring配置文件
<!--
userFactory:工廠的實(shí)例對(duì)象
factory-bean:指向工廠的實(shí)例對(duì)象
factory-method:工廠對(duì)象中創(chuàng)建對(duì)象的方法名
-->
<bean id="userFactory" class="com.bighorn.factory.UserDaoFactory"/>
<bean id="userDao" factory-bean="userFactory" factory-method="getUserDao"/>
3.運(yùn)行程序和靜態(tài)工廠一樣,查看運(yùn)行結(jié)果

FactoryBean
實(shí)例工廠的方法聽麻煩的,其實(shí)spring框架為我們一種實(shí)例工廠的方式:FactoryBean,比較實(shí)用,用來整合其他框架
我們只需要實(shí)現(xiàn)FactoryBean接口即可簡(jiǎn)化開發(fā),下面來介紹下它的具體使用方法
1.創(chuàng)建UserDaoFactoryBean類,實(shí)現(xiàn)FactoryBean接口中的三個(gè)方法:
boolean isSingleton():設(shè)置bean作用域,默認(rèn)true表示單例,false表示非單例T getObject() throws Exception:返回的是bean實(shí)例對(duì)象Class<?> getObjectType():返回的是被創(chuàng)建類的Class對(duì)象
public class UserDaoFactoryBean implements FactoryBean<UserDao> {
//bean作用域:默認(rèn)true表示單例
public boolean isSingleton() {
return true;
}
//代替實(shí)例工廠中創(chuàng)建對(duì)象的方法
public UserDao getObject() throws Exception {
System.out.println("這是FactoryBean實(shí)例化bean");
return new UserDaoImpl();
}
//返回所創(chuàng)建類的Class對(duì)象
public Class<?> getObjectType() {
return UserDao.class;
}
}
2.編寫spring配置文件
<bean id="userDao" class="com.bighorn.factory.UserDaoFactoryBean"/>
3.編寫運(yùn)行程序
public class App {
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
//獲取IoC容器
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
//從容器中獲取對(duì)象
UserDaoImpl userDao1 = context.getBean("userDao", UserDaoImpl.class);
UserDaoImpl userDao2 = context.getBean("userDao", UserDaoImpl.class);
System.out.println(userDao1);
System.out.println(userDao2);
}
}

以上就是詳解Spring Bean的配置方式與實(shí)例化的詳細(xì)內(nèi)容,更多關(guān)于Spring Bean配置方式 實(shí)例化的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Java 把json對(duì)象轉(zhuǎn)成map鍵值對(duì)的方法
這篇文章主要介紹了java 把json對(duì)象中轉(zhuǎn)成map鍵值對(duì)的方法,本文的目的是把json串轉(zhuǎn)成map鍵值對(duì)存儲(chǔ),而且只存儲(chǔ)葉節(jié)點(diǎn)的數(shù)據(jù) 。需要的朋友可以參考下2018-04-04
Feign遠(yuǎn)程調(diào)用Multipartfile參數(shù)處理
這篇文章主要介紹了Feign遠(yuǎn)程調(diào)用Multipartfile參數(shù)處理,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-03-03
Java中綴表達(dá)式轉(zhuǎn)后綴表達(dá)式實(shí)現(xiàn)方法詳解
這篇文章主要介紹了Java中綴表達(dá)式轉(zhuǎn)后綴表達(dá)式實(shí)現(xiàn)方法,結(jié)合實(shí)例形式分析了Java中綴表達(dá)式轉(zhuǎn)換成后綴表達(dá)式的相關(guān)算法原理與具體實(shí)現(xiàn)技巧,需要的朋友可以參考下2019-03-03
SpringCloud動(dòng)態(tài)配置注解@RefreshScope與@Component的深度解析
在現(xiàn)代微服務(wù)架構(gòu)中,動(dòng)態(tài)配置管理是一個(gè)關(guān)鍵需求,本文將為大家介紹Spring Cloud中相關(guān)的注解@RefreshScope與@Component的使用,需要的小伙伴可以參考下2025-04-04

