學(xué)習(xí)目標(biāo)
上一篇文章我們介紹了什么是Spring,以及Spring的一些核心概念,并且快速快發(fā)一個(gè)Spring項(xiàng)目,實(shí)現(xiàn)IOC和DI,今天具體來講解IOC
能夠說出IOC的基礎(chǔ)配置和Bean作用域
了解Bean的生命周期
能夠說出Bean的實(shí)例化方式
一、Bean的基礎(chǔ)配置
問題導(dǎo)入
問題1:在<bean>
標(biāo)簽上如何配置別名?
問題2:Bean的默認(rèn)作用范圍是什么?如何修改?
1 Bean基礎(chǔ)配置【重點(diǎn)】
配置說明
2 Bean別名配置
配置說明
注意事項(xiàng):
獲取bean無論是通過id還是name獲取,如果無法獲取到,將拋出異常NoSuchBeanDefinitionException
NoSuchBeanDefinitionException:?No?bean?named?'studentDaoImpl'?available
代碼演示
【第0步】創(chuàng)建項(xiàng)目名稱為10_2_IOC_Bean
的maven項(xiàng)目
【第一步】導(dǎo)入Spring坐標(biāo)
??<dependencies>
??????<!--導(dǎo)入spring的坐標(biāo)spring-context,對應(yīng)版本是5.2.10.RELEASE-->
??????<dependency>
??????????<groupId>org.springframework</groupId>
??????????<artifactId>spring-context</artifactId>
??????????<version>5.3.15</version>
??????</dependency>
??????<!--?導(dǎo)入junit的測試包?-->
??????<dependency>
??????????<groupId>org.junit.jupiter</groupId>
??????????<artifactId>junit-jupiter</artifactId>
??????????<version>5.8.2</version>
??????????<scope>test</scope>
??????</dependency>
??????<dependency>
??????????<groupId>org.projectlombok</groupId>
??????????<artifactId>lombok</artifactId>
??????????<version>1.18.28</version>
??????</dependency>
??</dependencies>
【第二步】導(dǎo)入Student實(shí)體類
@Data
@ToString
@AllArgsConstructor
public?class?Student?{
????private?String?name;
????private?String?address;
????private?Integer?age;
????private?Integer?status;
}
【第三步】定義Spring管理的類(接口)
-
StudentDao接口和StudentDaoImpl實(shí)現(xiàn)類
package?com.zbbmeta.dao;
public?interface?StudentDao?{
????/**
?????*?添加學(xué)生
?????*/
????void?save();
}
package?com.zbbmeta.dao.impl;
import?com.zbbmeta.dao.StudentDao;
public?class?StudentDaoImpl?implements?StudentDao?{
????@Override
????public?void?save()?{
????????System.out.println("DAO:?添加學(xué)生信息到數(shù)據(jù)庫...");
????}
}
-
StudentService接口和StudentServiceImpl實(shí)現(xiàn)類
package?com.zbbmeta.service;
public?interface?StudentService?{
????/**
?????*?添加學(xué)生
?????*/
????void?save();
}
package?com.zbbmeta.service.impl;
import?com.zbbmeta.dao.StudentDao;
import?com.zbbmeta.dao.impl.StudentDaoImpl;
import?com.zbbmeta.service.StudentService;
public?class?StudentServiceImpl?implements?StudentService?{
????//創(chuàng)建成員對象
????private?StudentDao?studentDao?=?new?StudentDaoImpl();
????@Override
????public?void?save()?{
????}
}
【第四步】創(chuàng)建Spring配置文件在resources目錄下,配置對應(yīng)類作為Spring管理的bean對象
-
定義application.xml配置文件并配置StudentDaoImpl
<?xml?version="1.0"?encoding="UTF-8"?>
<beans?xmlns="http://www.springframework.org/schema/beans"
???????xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
???????xsi:schemaLocation="http://www.springframework.org/schema/beans?http://www.springframework.org/schema/beans/spring-beans.xsd">
????<!--
????目標(biāo):熟悉bean標(biāo)簽詳細(xì)的屬性應(yīng)用
????-->
????<!--
????name屬性:可以設(shè)置多個(gè)別名,別名之間使用逗號,空格,分號等分隔
????-->
????<bean?name="studentDao2,abc?studentDao3"?class="com.zbbmeta.dao.impl.StudentDaoImpl"?id="studentDao"></bean>
</beans>
注意事項(xiàng):bean定義時(shí)id屬性和name中名稱不能有重復(fù)的在同一個(gè)上下文中(IOC容器中)不能重復(fù)
【第四步】根據(jù)容器別名獲取Bean對象
package?com.zbbmeta;
import?com.zbbmeta.dao.StudentDao;
import?org.springframework.context.support.ClassPathXmlApplicationContext;
public?class?NameApplication?{
????public?static?void?main(String[]?args)?{
????????/**
?????????*?從IOC容器里面根據(jù)別名獲取對象執(zhí)行
?????????*/
????????//1.根據(jù)配置文件application.xml創(chuàng)建IOC容器
????????ClassPathXmlApplicationContext?ac?=?new?ClassPathXmlApplicationContext("application.xml");
????????//2.從IOC容器里面獲取id="abc"對象
????????StudentDao?studentDao?=?(StudentDao)?ac.getBean("abc");
????????//3.執(zhí)行對象方法
????????studentDao.save();
????????//4.關(guān)閉容器
????????ac.close();
????}
}
打印結(jié)果
3 Bean作用范圍配置【重點(diǎn)】
配置說明
擴(kuò)展: scope的取值不僅僅只有singleton和prototype,還有request、session、application、 websocket ,表示創(chuàng)建出的對象放置在web容器(tomcat)對應(yīng)的位置。比如:request表示保存到request域中。
代碼演示
在application.xml中配置prototype格式
-
定義application.xml配置文件并配置StudentDaoImpl
<?xml?version="1.0"?encoding="UTF-8"?>
<beans?xmlns="http://www.springframework.org/schema/beans"
???????xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
???????xsi:schemaLocation="http://www.springframework.org/schema/beans?http://www.springframework.org/schema/beans/spring-beans.xsd">
????<!--
????目標(biāo):熟悉bean標(biāo)簽詳細(xì)的屬性應(yīng)用
????-->
????<!--
????scope屬性:定義bean的作用范圍,一共有5個(gè)
?????????singleton:?設(shè)置單例創(chuàng)建對象(推薦,也是默認(rèn)值),好處:節(jié)省資源
?????????prototype:?設(shè)置多例創(chuàng)建對象,每次從IOC容器獲取的時(shí)候都會創(chuàng)建對象,獲取多次創(chuàng)建多次。
?????????request:?在web開發(fā)環(huán)境中,IOC容器會將對象放到request請求域中,對象存活的范圍在一次請求內(nèi)。
??????????????????請求開始創(chuàng)建對象,請求結(jié)束銷毀對象
?????????session:?在web開發(fā)環(huán)境中,IOC容器會將對象放到session會話域中,對象存活的范圍在一次會話內(nèi)。
??????????????????會話開始開始創(chuàng)建對象,會話銷毀對象銷毀。
?????????global-session:?是多臺服務(wù)器共享同一個(gè)會話存儲的數(shù)據(jù)。
????-->
????<bean?class="com.zbbmeta.dao.impl.StudentDaoImpl"?id="studentDao4"?scope="prototype"></bean>
</beans>
根據(jù)容器別名獲取Bean對象
package?com.zbbmeta;
import?com.zbbmeta.dao.StudentDao;
import?org.springframework.context.support.ClassPathXmlApplicationContext;
public?class?ScopeApplication?{
????public?static?void?main(String[]?args)?{
????????/**
?????????*?Bean的作用域范圍演示
?????????*/
????????//1.根據(jù)配置文件application.xml創(chuàng)建IOC容器
????????ClassPathXmlApplicationContext?ac?=?new?ClassPathXmlApplicationContext("application.xml");
????????//2.從IOC容器里面獲取id="studentService"對象
????????System.out.println("=========singleton(單例)模式=========");
????????StudentDao?studentDao?=?(StudentDao)?ac.getBean("studentDao");
????????StudentDao?studentDao1?=?(StudentDao)?ac.getBean("studentDao");
????????System.out.println("studentDao?=?"?+?studentDao);
????????System.out.println("studentDao1?=?"?+?studentDao1);
????????System.out.println("=========prototype模式=========");
????????StudentDao?studentDao2?=?(StudentDao)?ac.getBean("studentDao4");
????????StudentDao?studentDao3?=?(StudentDao)?ac.getBean("studentDao4");
????????System.out.println("studentDao2?=?"?+?studentDao2);
????????System.out.println("studentDao3?=?"?+?studentDao3);
????????//4.關(guān)閉容器
????????ac.close();
????}
}
打印結(jié)果
注意:在我們的實(shí)際開發(fā)當(dāng)中,絕大部分的Bean是單例的,也就是說絕大部分Bean不需要配置scope屬性。
二、Bean的實(shí)例化
思考:Bean的實(shí)例化方式有幾種?
2 實(shí)例化Bean的三種方式
2.1 構(gòu)造方法方式【重點(diǎn)】
-
BookDaoImpl實(shí)現(xiàn)類
public?class?StudentDaoImpl?implements?StudentDao?{
????public?StudentDaoImpl()?{
????????System.out.println("Student?dao?constructor?is?running?....");
????}
????@Override
????public?void?save()?{
????????System.out.println("DAO:?添加學(xué)生信息到數(shù)據(jù)庫...");
????}
}
-
application.xml配置
????<!--
????目標(biāo):講解bean創(chuàng)建方式
????-->
????<!--創(chuàng)建StudentDaoImpl對象方式1:默認(rèn)調(diào)用類的無參構(gòu)造函數(shù)創(chuàng)建-->
????<bean?id="studentDao"?class="com.zbbmeta.dao.impl.StudentDaoImpl"/>
-
AppForInstanceBook測試類
public?class?OneApplication?{
????public?static?void?main(String[]?args)?{
????????/**
?????????*?無參構(gòu)造方式創(chuàng)建Bean
?????????*/
????????//1.根據(jù)配置文件application.xml創(chuàng)建IOC容器
????????ClassPathXmlApplicationContext?ac?=?new?ClassPathXmlApplicationContext("application.xml");
????????//2.從IOC容器里面獲取id="studentService"對象
????????StudentDao?studentDao?=?(StudentDao)?ac.getBean("studentDao");
????????//3.執(zhí)行對象方法
????????studentDao.save();
????????//4.關(guān)閉容器
????????ac.close();
????}
}
-
運(yùn)行結(jié)果
注意:無參構(gòu)造方法如果不存在,將拋出異常BeanCreationException
2.2 靜態(tài)工廠方式
-
StudentDaoFactory工廠類
package?com.zbbmeta.factory;
import?com.zbbmeta.dao.StudentDao;
import?com.zbbmeta.dao.impl.StudentDaoImpl;
public?class?StudentDaoFactory?{
//????靜態(tài)工廠創(chuàng)建對象
????public?static?StudentDao?getStudentDao(){
????????System.out.println("Student?static?factory?setup....");
????????return?new?StudentDaoImpl();
????}
}
-
applicationContext.xml配置
<?xml?version="1.0"?encoding="UTF-8"?>
<beans?xmlns="http://www.springframework.org/schema/beans"
???????xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
???????xsi:schemaLocation="http://www.springframework.org/schema/beans?http://www.springframework.org/schema/beans/spring-beans.xsd">
????<!--
????目標(biāo):講解bean創(chuàng)建方式
????-->
????<!--創(chuàng)建StudentDaoImpl對象方式1:默認(rèn)調(diào)用類的無參構(gòu)造函數(shù)創(chuàng)建-->
<!--????<bean?id="studentDao"?class="com.zbbmeta.dao.impl.StudentDaoImpl"/>-->
????<!--創(chuàng)建StudentDaoImpl對象方式2:調(diào)用靜態(tài)工廠方法創(chuàng)建對象加入IOC容器
????class="com.zbbmeta.factory.StudentDaoFactory"?設(shè)置工廠類全名
????factory-method="getStudentDao"?調(diào)用工廠的靜態(tài)方法
-->
????<bean?class="com.zbbmeta.factory.StudentDaoFactory"?factory-method="getStudentDao"?id="studentDao2"></bean>
</beans>
注意:測試前最好把之前使用Bean標(biāo)簽創(chuàng)建的對象進(jìn)行注釋
-
TwoApplication測試類
public?class?TwoApplication?{
????public?static?void?main(String[]?args)?{
????????/**
?????????*?無參構(gòu)造方式創(chuàng)建Bean
?????????*/
????????//1.根據(jù)配置文件application.xml創(chuàng)建IOC容器
????????ClassPathXmlApplicationContext?ac?=?new?ClassPathXmlApplicationContext("application.xml");
????????//2.從IOC容器里面獲取id="studentService"對象
????????StudentDao?studentDao?=?(StudentDao)?ac.getBean("studentDao2");
????????//3.執(zhí)行對象方法
????????studentDao.save();
????????//4.關(guān)閉容器
????????ac.close();
????}
}
-
運(yùn)行結(jié)果
2.3 實(shí)例工廠方式
-
UserDao接口和UserDaoImpl實(shí)現(xiàn)類
????//利用實(shí)例方法創(chuàng)建StudentDao對象
????public?StudentDao?getStudentDao2(){
????????System.out.println("調(diào)用了實(shí)例工廠方法");
????????return?new?StudentDaoImpl();
????}
-
StudentDaoFactory工廠類添加方法
//實(shí)例工廠創(chuàng)建對象
public?class?UserDaoFactory?{
????public?UserDao?getUserDao(){
????????return?new?UserDaoImpl();
????}
}
-
applicationContext.xml配置
<?xml?version="1.0"?encoding="UTF-8"?>
<beans?xmlns="http://www.springframework.org/schema/beans"
???????xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
???????xsi:schemaLocation="http://www.springframework.org/schema/beans?http://www.springframework.org/schema/beans/spring-beans.xsd">
????<!--
????目標(biāo):講解bean創(chuàng)建方式
????-->
????<!--創(chuàng)建StudentDaoImpl對象方式1:默認(rèn)調(diào)用類的無參構(gòu)造函數(shù)創(chuàng)建-->
<!--????<bean?id="studentDao"?class="com.zbbmeta.dao.impl.StudentDaoImpl"/>-->
????<!--創(chuàng)建StudentDaoImpl對象方式2:調(diào)用靜態(tài)工廠方法創(chuàng)建對象加入IOC容器
????class="com.zbbmeta.factory.StudentDaoFactory"?設(shè)置工廠類全名
????factory-method="getStudentDao"?調(diào)用工廠的靜態(tài)方法
-->
<!--????<bean?class="com.zbbmeta.factory.StudentDaoFactory"?factory-method="getStudentDao"?id="studentDao2"></bean>-->
????<!--創(chuàng)建BookDaoImpl對象方式3:調(diào)用實(shí)例工廠方法創(chuàng)建對象加入IOC容器
????class="com.itheima.factory.BookDaoFactory"?設(shè)置工廠類全名
????factory-method="getBookDao"?調(diào)用工廠的靜態(tài)方法
-->
????<!--第一步:創(chuàng)建工廠StudentDaoFactory對象-->
????<bean?class="com.zbbmeta.factory.StudentDaoFactory"?id="studentDaoFactory"></bean>
????<!--第一步:調(diào)用工廠對象的getStudentDao2()實(shí)例方法創(chuàng)建StudentDaoImpl對象加入IOC容器
????????factory-bean="studentDaoFactory"?獲取IOC容器中指定id值的對象
????????factory-method="getStudentDao2"?如果配置了factory-bean,那么這里設(shè)置的就是實(shí)例方法名
????-->
????<bean?factory-bean="studentDaoFactory"?factory-method="getStudentDao2"?id="studentDao3"></bean>
</beans>
-
ThreeApplication測試類
package?com.zbbmeta;
import?com.zbbmeta.dao.StudentDao;
import?org.springframework.context.support.ClassPathXmlApplicationContext;
public?class?ThreeApplication?{
????public?static?void?main(String[]?args)?{
????????/**
?????????*?無參構(gòu)造方式創(chuàng)建Bean
?????????*/
????????//1.根據(jù)配置文件application.xml創(chuàng)建IOC容器
????????ClassPathXmlApplicationContext?ac?=?new?ClassPathXmlApplicationContext("application.xml");
????????//2.從IOC容器里面獲取id="studentService"對象
????????StudentDao?studentDao?=?(StudentDao)?ac.getBean("studentDao3");
????????//3.執(zhí)行對象方法
????????studentDao.save();
????????//4.關(guān)閉容器
????????ac.close();
????}
}
-
運(yùn)行結(jié)果
三、Bean的生命周期【了解】
問題導(dǎo)入
問題1:多例的Bean能夠配置并執(zhí)行銷毀的方法?
問題2:如何做才執(zhí)行Bean銷毀的方法?
1 生命周期相關(guān)概念介紹
-
生命周期:從創(chuàng)建到消亡的完整過程
-
bean生命周期:bean從創(chuàng)建到銷毀的整體過程
-
bean生命周期控制:在bean創(chuàng)建后到銷毀前做一些事情
1.1生命周期過程
- 初始化容器
-
創(chuàng)建對象(內(nèi)存分配)
-
執(zhí)行構(gòu)造方法
-
執(zhí)行屬性注入(set操作)
-
執(zhí)行bean初始化方法
-
- 使用bean
-
執(zhí)行業(yè)務(wù)操作
-
- 關(guān)閉/銷毀容器
-
執(zhí)行bean銷毀方法
-
2 代碼演示
2.1 Bean生命周期控制
【第0步】創(chuàng)建項(xiàng)目名稱為10_4_IOC_BeanLifeCycle
的maven項(xiàng)目
【第一步】導(dǎo)入Spring坐標(biāo)
??<dependencies>
??????<!--導(dǎo)入spring的坐標(biāo)spring-context,對應(yīng)版本是5.2.10.RELEASE-->
??????<dependency>
??????????<groupId>org.springframework</groupId>
??????????<artifactId>spring-context</artifactId>
??????????<version>5.3.15</version>
??????</dependency>
??????<!--?導(dǎo)入junit的測試包?-->
??????<dependency>
??????????<groupId>org.junit.jupiter</groupId>
??????????<artifactId>junit-jupiter</artifactId>
??????????<version>5.8.2</version>
??????????<scope>test</scope>
??????</dependency>
??????<dependency>
??????????<groupId>org.projectlombok</groupId>
??????????<artifactId>lombok</artifactId>
??????????<version>1.18.28</version>
??????</dependency>
??</dependencies>
【第二步】導(dǎo)入Student實(shí)體類
@Data
@ToString
@AllArgsConstructor
public?class?Student?{
????private?String?name;
????private?String?address;
????private?Integer?age;
????private?Integer?status;
}
【第三步】定義Spring管理的類(接口)
-
StudentDao接口和StudentDaoImpl實(shí)現(xiàn)類
package?com.zbbmeta.dao;
public?interface?StudentDao?{
????/**
?????*?添加學(xué)生
?????*/
????void?save();
}
package?com.zbbmeta.dao.impl;
import?com.zbbmeta.dao.StudentDao;
public?class?StudentDaoImpl?implements?StudentDao?{
????public?StudentDaoImpl(){
????????System.out.println("Student?Dao?的無參構(gòu)造");
????}
????@Override
????public?void?save()?{
????????System.out.println("DAO:?添加學(xué)生信息到數(shù)據(jù)庫...");
????}
????public?void?init(){
????????System.out.println("Student?Dao?的初始化方法");
????}
????public?void?destroy(){
????????System.out.println("Student?Dao?的銷毀方法");
????}
}
【第四步】創(chuàng)建Spring配置文件在resources目錄下,配置對應(yīng)類作為Spring管理的bean對象
-
定義application.xml配置文件并配置StudentDaoImpl
<?xml?version="1.0"?encoding="UTF-8"?>
<beans?xmlns="http://www.springframework.org/schema/beans"
???????xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
???????xsi:schemaLocation="http://www.springframework.org/schema/beans?http://www.springframework.org/schema/beans/spring-beans.xsd">
????<!--目標(biāo):創(chuàng)建StudentDaoImpl對象:設(shè)置生命周期方法
????????init-method="init"?在對象創(chuàng)建后立即調(diào)用初始化方法
????????destroy-method="destroy":在容器執(zhí)行銷毀前立即調(diào)用銷毀的方法
????????注意:只有單例對象才會運(yùn)行銷毀生命周期方法
-->
????<bean?class="com.zbbmeta.dao.impl.StudentDaoImpl"?id="studentDao"?init-method="init"?destroy-method="destroy"></bean>
</beans>
【第四步】根據(jù)容器別名獲取Bean對象
package?com.zbbmeta;
import?com.zbbmeta.dao.StudentDao;
import?org.springframework.context.support.ClassPathXmlApplicationContext;
public?class?LifeCycleApplication?{
????public?static?void?main(String[]?args)?{
????????????//1.根據(jù)配置文件application.xml創(chuàng)建IOC容器
????????????ClassPathXmlApplicationContext?ac?=?new?ClassPathXmlApplicationContext("application.xml");
????????????//2.從IOC容器里面獲取id="studentService"對象
????????????StudentDao?studentDao?=?(StudentDao)?ac.getBean("studentDao");
????????????//3.執(zhí)行對象方法
????????????studentDao.save();
????????????//4.關(guān)閉容器
????????????ac.close();
????????
????}
}
打印結(jié)果
3 Bean銷毀時(shí)機(jī)
-
容器關(guān)閉前觸發(fā)bean的銷毀
- 關(guān)閉容器方式:
-
手工關(guān)閉容器 調(diào)用容器的
close()
操作文章來源:http://www.zghlxwxcb.cn/news/detail-635980.html -
注冊關(guān)閉鉤子(類似于注冊一個(gè)事件),在虛擬機(jī)退出前先關(guān)閉容器再退出虛擬機(jī) 調(diào)用容器的
registerShutdownHook()
操作文章來源地址http://www.zghlxwxcb.cn/news/detail-635980.html
-
public?class?LifeCycleApplication?{
????public?static?void?main(String[]?args)?{
????????????//1.根據(jù)配置文件application.xml創(chuàng)建IOC容器
????????????ClassPathXmlApplicationContext?ac?=?new?ClassPathXmlApplicationContext("application.xml");
????????????//2.從IOC容器里面獲取id="studentService"對象
????????????StudentDao?studentDao?=?(StudentDao)?ac.getBean("studentDao");
????????????//3.執(zhí)行對象方法
????????????studentDao.save();
????????????//4.關(guān)閉容器
//????????????ac.close();
????????//注冊關(guān)閉鉤子函數(shù),在虛擬機(jī)退出之前回調(diào)此函數(shù),關(guān)閉容器
????????ac.registerShutdownHook();
????}
}
到了這里,關(guān)于Spring-1-透徹理解Spring XML的Bean創(chuàng)建--IOC的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!