詳解Spring?Bean的配置方式與實例化
一、 Spring Bean 配置方式
由 Spring IoC 容器管理的對象稱為 Bean,Bean 配置方式有兩種:配置文件開發(fā)和注解開發(fā)
配置文件開發(fā)
Spring 配置文件支持兩種格式:xml和properties,此教程以xml配置文件講解。
XML 配置文件的根元素是 <beans>,該元素包含了多個子元素 <bean>。每一個 <bean> 元素都定義了一個 Bean
XML 配置文件常用元素表
屬性名稱 | 描述 |
---|---|
id | Bean 的唯一標(biāo)識符,Spring IoC 容器對 Bean 的配置和管理都通過該屬性完成。 |
name | Bean 的別名,可以通過 name 屬性為同一個 Bean 同時指定多個名稱,每個名稱之間用逗號或分號隔開。 |
class | 指定了Bean 的具體實現(xiàn)類,它必須是一個類的全限定名。 |
scope | Bean 的作用域,屬性值可以為 singleton(單例)、prototype(原型)、request、session 和 global Session。默認值是 singleton。 |
注解開發(fā)
先插個眼在這,過幾天會發(fā)一篇文章詳細介紹
二、Spring Bean實例化
通過控制反轉(zhuǎn),對象的創(chuàng)建權(quán)就交給了IoC容器,但是容器是如何來創(chuàng)建對象的呢?
bean本質(zhì)上就是對象,對象在new的時候會使用構(gòu)造方法,創(chuàng)建bean其實也是使用構(gòu)造方法完成的。
實例化bean的三種方式:構(gòu)造方法,靜態(tài)工廠和實例工廠
環(huán)境準(zhǔn)備
1.準(zhǔn)備一個UserDao
接口和一個UserDaoImpl
實現(xiàn)類
//UserDao接口 public interface UserDao { public void say(); } //UserDaoImpl實現(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.編寫運行程序
public class App { public static void main(String[] args) { //獲取IoC容器 ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); //從容器中獲取對象 UserDaoImpl userDao = context.getBean("userDao", UserDaoImpl.class); userDao.say(); } }
構(gòu)造方法實例化Bean
第一種實例化bean的方法:構(gòu)造方法實例化,這也是最常用的方法,因為類都會提供默認的構(gòu)造方法。下面來測試下
1.在UserDaoImpl類中添加一個無參構(gòu)造方法,并打印一句話,方便觀察結(jié)果。
public class UserDaoImpl implements UserDao { //添加一個無參構(gòu)造方法 public UserDaoImpl() { System.out.println("這是UserDaoImpl的無參構(gòu)造方法"); } @Override public void say() { System.out.println("Hello,I am BigHorn!"); } }
可以在控制臺看到輸出結(jié)果,說明Spring IoC 容器創(chuàng)建對象時用的也是構(gòu)造方法
2.將構(gòu)造方法改成private測試
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)還可以運行成功,這說明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!"); } }
程序會報java.lang.NoSuchMethodException
錯,說明Spring底層使用的是類的無參構(gòu)造方法。
4.畫個圖總結(jié)下:Spring 配置文件中 bean 標(biāo)簽的 id 和類的全限定名一一對應(yīng),所以 Spring IoC容器的 getBean 方法其實就是先根據(jù) bean 的 id 獲取該類的全限定名,然后再利用反射根據(jù)類的全限定名創(chuàng)建對象并返回。
靜態(tài)工廠實例化Bean
第二種實例化Bean的方法:靜態(tài)工廠實例化
了解即可,一般是用來兼容早期的一些老系統(tǒng)。
1.創(chuàng)建一個UserDaoFactory工廠類并提供一個靜態(tài)方法
//UserDao接口 public interface UserDao { public void say(); } //UserDaoImpl實現(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)建對象 public static UserDao getUserDao(){ System.out.println("這是靜態(tài)工廠實例化Bean"); return new UserDaoImpl(); } }
2.編寫spring配置文件
<!-- class:工廠類全類名 factory-method:工廠創(chuàng)建對象的方法名 --> <bean id="userDao" class="com.bighorn.factory.UserDaoFactory" factory-method="getUserDao"/>
3.編寫運行程序
public class App { public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException { //獲取IoC容器 ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); //從容器中獲取對象 UserDaoImpl userDao = context.getBean("userDao", UserDaoImpl.class); userDao.say(); } }
看見運行結(jié)果,輸出以下語句
實例工廠實例化Bean
第二種實例化Bean的方法:實例工廠實例化
了解即可,其實和靜態(tài)工廠差不多。只不過靜態(tài)工廠可以直接通過靜態(tài)方法創(chuàng)建bean,實例工廠要先new一個實例工廠對象,然后再通過這個實例工廠對象創(chuàng)建bean
1.創(chuàng)建一個UserDaoFactory
工廠類,和靜態(tài)工廠不一樣的是,實力工廠提供的是一個普通方法
//UserDaoFactory工廠類 public class UserDaoFactory { //實例工廠創(chuàng)建對象 public UserDao getUserDao(){ System.out.println("這是實例工廠實例化Bean"); return new UserDaoImpl(); } }
2.編寫spring配置文件
<!-- userFactory:工廠的實例對象 factory-bean:指向工廠的實例對象 factory-method:工廠對象中創(chuàng)建對象的方法名 --> <bean id="userFactory" class="com.bighorn.factory.UserDaoFactory"/> <bean id="userDao" factory-bean="userFactory" factory-method="getUserDao"/>
3.運行程序和靜態(tài)工廠一樣,查看運行結(jié)果
FactoryBean
實例工廠的方法聽麻煩的,其實spring框架為我們一種實例工廠的方式:FactoryBean
,比較實用,用來整合其他框架
我們只需要實現(xiàn)FactoryBean接口即可簡化開發(fā),下面來介紹下它的具體使用方法
1.創(chuàng)建UserDaoFactoryBean類,實現(xiàn)FactoryBean接口中的三個方法:
boolean isSingleton()
:設(shè)置bean作用域,默認true表示單例,false表示非單例T getObject() throws Exception
:返回的是bean實例對象Class<?> getObjectType()
:返回的是被創(chuàng)建類的Class對象
public class UserDaoFactoryBean implements FactoryBean<UserDao> { //bean作用域:默認true表示單例 public boolean isSingleton() { return true; } //代替實例工廠中創(chuàng)建對象的方法 public UserDao getObject() throws Exception { System.out.println("這是FactoryBean實例化bean"); return new UserDaoImpl(); } //返回所創(chuàng)建類的Class對象 public Class<?> getObjectType() { return UserDao.class; } }
2.編寫spring配置文件
<bean id="userDao" class="com.bighorn.factory.UserDaoFactoryBean"/>
3.編寫運行程序
public class App { public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException { //獲取IoC容器 ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); //從容器中獲取對象 UserDaoImpl userDao1 = context.getBean("userDao", UserDaoImpl.class); UserDaoImpl userDao2 = context.getBean("userDao", UserDaoImpl.class); System.out.println(userDao1); System.out.println(userDao2); } }
以上就是詳解Spring Bean的配置方式與實例化的詳細內(nèi)容,更多關(guān)于Spring Bean配置方式 實例化的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Java lambda list轉(zhuǎn)換map時,把多個參數(shù)拼接作為key操作
這篇文章主要介紹了Java lambda list轉(zhuǎn)換map時,把多個參數(shù)拼接作為key操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-08-08Jenkins+Docker+Gitee+SpringBoot自動化部署
本文主要介紹了Jenkins+Docker+Gitee+SpringBoot自動化部署,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-03-03springboot運行到dokcer中 dockerfile的場景分析
這篇文章主要介紹了springboot運行到dokcer中 dockerfile,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-03-03tomcat報錯:Wrapper cannot find servlet class ...問題解決
這篇文章主要介紹了tomcat報錯:Wrapper cannot find servlet class ...問題解決的相關(guān)資料,需要的朋友可以參考下2016-11-11Spring學(xué)習(xí)JdbcTemplate數(shù)據(jù)庫事務(wù)參數(shù)
這篇文章主要為大家介紹了Spring學(xué)習(xí)JdbcTemplate數(shù)據(jù)庫事務(wù)參數(shù)使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-05-05