概念
Spring容器里裝的是需要管理的對象榕茧,裝在一個HashMap集合中覆旱。我們用容器來實例化對象饭玲,管理對象之間的依賴
只要實現(xiàn)了BeanFactory和ApplicationContext接口的類醉冤,那么這兩個接口的類都可以作為Spring容器
BeanFactory
是最頂層最基本的接口卫袒,它描述了容器需要實現(xiàn)的最基本的功能
ApplicationContext
繼承了BeanFactory接口宵呛,它描述的內(nèi)容更加廣泛。它是把beans.xml文件里的內(nèi)容先存放到HashMap容器里夕凝,需要用的時候從里面取烤蜕,用得最多
實例化Bean的三種方式
在 Spring 中,構(gòu)成應(yīng)用程序主干并由 Spring IoC 容器管理的對象稱為 bean迹冤。bean 是由Spring IoC 容器實例化讽营、組裝和管理的對象
1)使用默認(rèn)無參構(gòu)造函數(shù)
在默認(rèn)情況下,它會根據(jù)默認(rèn)無參構(gòu)造函數(shù)來創(chuàng)建類對象泡徙,如果bean中沒有默認(rèn)無參構(gòu)造函數(shù)橱鹏,將會創(chuàng)建失敗
beans.xml文件中
<bean id="accountDao" class="xn.xh.dao.impl.AccountDaoImpl"/>
AccountDaoImpl.java文件中
public class AccountDaoImpl implements IAccountDao {
//無參構(gòu)造函數(shù)。如果一個類沒有定義任何的構(gòu)造函數(shù),那么會自動生成一個無參構(gòu)造函數(shù)
public AccountDaoImpl() {
System.out.println("創(chuàng)建了對象!");
}
===========================================================
//如果上面這個代碼改成下面這樣莉兰,執(zhí)行client時就會報錯
public AccountDaoImpl(String name) {
System.out.println("創(chuàng)建了對象!");
}
===========================================================
@Override
public void saveAccount() {
System.out.println("jdbc保存賬戶!");
}
}
client.java文件中
public class client {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
IAccountDao accountDao = (IAccountDao)context.getBean("accountDao");
accountDao.saveAccount();
//運行結(jié)果為在控制臺打印出:創(chuàng)建了對象! Jdbc保存賬戶!
}
}
2)spring管理靜態(tài)工廠挑围,使用靜態(tài)工廠的方法創(chuàng)建對象
模擬一個靜態(tài)工廠,創(chuàng)建數(shù)據(jù)層實現(xiàn)類
beans.xml文件中
<bean id="accountDao" class="xn.xh.factory.StaticFactory" factory-method="createAccountDao" />
AccountDaoImpl.java文件中
public class AccountDaoImpl implements IAccountDao {
public AccountDaoImpl() {
System.out.println("創(chuàng)建了對象!");
}
@Override
public void saveAccount() {
System.out.println("jdbc保存賬戶!");
}
}
StaticFactory文件中
public class StaticFactory {
public static IAccountDao createAccountDao() {
return new AccountDaoImpl();
}
}
client.java文件中
public class client {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
IAccountDao accountDao = (IAccountDao)context.getBean("accountDao");
accountDao.saveAccount();
//運行結(jié)果為在控制臺打印出:創(chuàng)建了對象! Jdbc保存賬戶!
}
}
此種方法是
使用StaticFactory類中的靜態(tài)方法createAccountDao創(chuàng)建對象糖荒,并存入spring容器
id屬性:指定bean的id杉辙,用于從容器中獲取
class屬性:指定靜態(tài)工廠的全限定類名
factory-method屬性:指定生產(chǎn)對象的靜態(tài)方法
3)spring管理實例工廠-使用實例工廠的方法創(chuàng)建對象
模擬一個實例工廠,創(chuàng)建業(yè)務(wù)層實現(xiàn)類
次工廠創(chuàng)建對象捶朵,必須有工廠實例對象蜘矢,再調(diào)用方法
beans.xml文件中
<bean id="InstanceFactory" class="xn.xh.factory.InstanceFactory" />
<bean id="accountDao" factory-bean="InstanceFactory" factory-method="createAccountDao" />
AccountDaoImpl.java文件中
public class AccountDaoImpl implements IAccountDao {
public AccountDaoImpl() {
System.out.println("創(chuàng)建了對象!");
}
@Override
public void saveAccount() {
System.out.println("jdbc保存賬戶!");
}
}
InstanceFactory.java文件中
public class InstanceFactory {
public IAccountDao createAccountDao() {
return new AccountDaoImpl();
}
}
client.java文件中
public class client {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
IAccountDao accountDao = (IAccountDao)context.getBean("accountDao");
accountDao.saveAccount();
//運行結(jié)果為在控制臺打印出:創(chuàng)建了對象! Jdbc保存賬戶!
}
}
2)和3)那么麻煩,為什么不只用1)的方法進(jìn)行創(chuàng)建實例對象呢综看? 比如上面工廠(InstanceFactory類)是第三方的jar包品腹,我們無法修改里面的代碼,但又想通過它來生成實例對象時就要用到了
bean標(biāo)簽
作用
用于配置對象讓spring來創(chuàng)建的
屬性
id:給對象在容器中提供一個唯一標(biāo)識红碑,用于獲取對象
class:指定類的全限定類名舞吭,用于反射創(chuàng)建對象
scope:指定對象的作用范圍
?singleton:默認(rèn)值,單例的
?prototype:多例的
?request:web項目中Spring創(chuàng)建一個Bean的對象析珊,將對象存入到request域中
?session:web項目中Spring創(chuàng)建一個Bean的對象羡鸥,將對象存入到session域中
bean的作用范圍和生命周期
單例對象
scope=“singleton”
一個應(yīng)用只有一個對象的實例,它的作用范圍就是整個引用
在加載beans.xml文件的時候創(chuàng)建對象忠寻,放入到HashMap集合當(dāng)中惧浴,只會被創(chuàng)建一次。用getBean()方法調(diào)用的時候直接去集合里取
生命周期
?對象出生:當(dāng)應(yīng)用加載锡溯,創(chuàng)建容器時赶舆,對象就被創(chuàng)建了
?對象活著:只要容器在哑姚,對象一直活著
?對象死亡:當(dāng)應(yīng)用卸載祭饭,銷毀容器時,對象就會被銷毀
多例對象
scope="prototype"
每次訪問對象時叙量,都會重新創(chuàng)建對象實例
生命周期
?對象出生:當(dāng)使用對象時倡蝙,創(chuàng)建新的對象實例
?對象活著:只要對象在使用中,就一直活著
?對象死亡:當(dāng)對象長時間不用時绞佩,被java的垃圾回收器回收了