SpringIOC基礎(chǔ)知識(shí)總結(jié)
點(diǎn)擊上方藍(lán)色字體,選擇“標(biāo)星公眾號(hào)”
優(yōu)質(zhì)文章,第一時(shí)間送達(dá)
? 作者?|??鄧曉暉
來(lái)源 |??urlify.cn/VNv67n
1.BeanFactory和ApplicationContext的區(qū)別:
BeanFactory是Spring框架中IOC容器的頂層接口,它只是用來(lái)定義一些基礎(chǔ)功能,定義一些基礎(chǔ)規(guī)范,而ApplicationContext是它的一個(gè)子接口,所以ApplicationContext是具備BeanFactory提供的全部功能。
通常我們稱BeanFactory為SpringIOC的基礎(chǔ)容器,ApplicationContext是容器的高級(jí)接口,比如BeanFactory擁有更多的功能,比如說(shuō)國(guó)際化支持和資源訪問(wèn)(xml、java配置類)等等。
2.實(shí)例化bean的三種方式:
?式?:使??參構(gòu)造函數(shù)
在默認(rèn)情況下,它會(huì)通過(guò)反射調(diào)??參構(gòu)造函數(shù)來(lái)創(chuàng)建對(duì)象。如果類中沒(méi)有?參構(gòu)造函數(shù),將創(chuàng)建失敗。
"connectionUtils"?class="com.lagou.edu.utils.ConnectionUtils">
?式?:使?靜態(tài)?法創(chuàng)建
在實(shí)際開發(fā)中,我們使?的對(duì)象有些時(shí)候并不是直接通過(guò)構(gòu)造函數(shù)就可以創(chuàng)建出來(lái)的,它可能在創(chuàng)建的過(guò)程中會(huì)做很多額外的操作。此時(shí)會(huì)提供?個(gè)創(chuàng)建對(duì)象的?法,恰好這個(gè)?法是static修飾的?法,即是此種情況。
例如,我們?cè)谧鯦dbc操作時(shí),會(huì)?到java.sql.Connection接?的實(shí)現(xiàn)類,如果是mysql數(shù)據(jù)庫(kù),那么?的就是JDBC4Connection,但是我們不會(huì)去寫?JDBC4Connection connection = newJDBC4Connection()?,因?yàn)槲覀円?cè)驅(qū)動(dòng),還要提供URL和憑證信息,??DriverManager.getConnection??法來(lái)獲取連接。
那么在實(shí)際開發(fā)中,尤其早期的項(xiàng)?沒(méi)有使?Spring框架來(lái)管理對(duì)象的創(chuàng)建,但是在設(shè)計(jì)時(shí)使?了??模式解耦,那么當(dāng)接?spring之后,??類創(chuàng)建對(duì)象就具有和上述例?相同特征,即可采?此種?式配置。
"userService"?class="com.lagou.factory.BeanFactory"
factory-method="getTransferService">
?式三:使?實(shí)例化?法創(chuàng)建
此種?式和上?靜態(tài)?法創(chuàng)建其實(shí)類似,區(qū)別是?于獲取對(duì)象的?法不再是static修飾的了,?是類中的? 個(gè)普通?法。此種?式?靜態(tài)?法創(chuàng)建的使??率要??些。
在早期開發(fā)的項(xiàng)?中,??類中的?法有可能是靜態(tài)的,也有可能是?靜態(tài)?法,當(dāng)是?靜態(tài)?法時(shí),即可采?下?的配置?式:
"beanFactory"
class="com.lagou.factory.instancemethod.BeanFactory"> ?"transferService"?factory-bean="beanFactory"?factory-method="getTransferService">
3.Bean的作用范圍和生命周期
3.1作用范圍——scope

經(jīng)常使用的有singleton和prototype:
????
???"accountDao"?class="com.lagou.edu.dao.impl.JdbcAccountDaoImpl"?>
???????"ConnectionUtils"?ref="connectionUtils">
???
測(cè)試:
???"accountDao"?class="com.lagou.edu.dao.impl.JdbcAccountDaoImpl"?>
???????"ConnectionUtils"?ref="connectionUtils">
???
???????//===
[email protected]
????public?void?test(){
????????ApplicationContext?applicationContext?=?new?ClassPathXmlApplicationContext("applicationContext.xml");
????????AccountDao?accountDao?=?(AccountDao)?applicationContext.getBean("accountDao");
????????System.out.println("accountDao:"+accountDao);
????????AccountDao?accountDao1?=?(AccountDao)?applicationContext.getBean("accountDao");
????????System.out.println("accountDao1:"+accountDao1);
????}
//得出結(jié)果為:
accountDao:com.lagou.edu.dao.impl.JdbcAccountDaoImpl@58cbafc2
accountDao1:com.lagou.edu.dao.impl.JdbcAccountDaoImpl@58cbafc2 ??
//同一個(gè)對(duì)象
???"accountDao"?class="com.lagou.edu.dao.impl.JdbcAccountDaoImpl"?scope="prototype">
???????"ConnectionUtils"?ref="connectionUtils">
???
???????//===
[email protected]
????public?void?test(){
????????ApplicationContext?applicationContext?=?new?ClassPathXmlApplicationContext("applicationContext.xml");
????????AccountDao?accountDao?=?(AccountDao)?applicationContext.getBean("accountDao");
????????System.out.println("accountDao:"+accountDao);
????????AccountDao?accountDao1?=?(AccountDao)?applicationContext.getBean("accountDao");
????????System.out.println("accountDao1:"+accountDao1);
????}
//得出結(jié)果為:
accountDao:com.lagou.edu.dao.impl.JdbcAccountDaoImpl@75d3a5e0
accountDao1:com.lagou.edu.dao.impl.JdbcAccountDaoImpl@74d1dc36 ?
//不是同一個(gè)對(duì)象
3.2生命周期
singleton(默認(rèn))單例:IOC容器只有一個(gè)該類對(duì)象
一句話總結(jié):?jiǎn)卫J降腷ean對(duì)象生命周期與容器相同
對(duì)象出生:當(dāng)容器創(chuàng)建時(shí),對(duì)象就被創(chuàng)建了
對(duì)象活著:只要容器在,對(duì)象就一直活著
對(duì)象死亡:當(dāng)容器銷毀時(shí),對(duì)象就被銷毀了
prototype (多例)原型:每次使用該類的對(duì)象(getBean),都返回一個(gè)新的對(duì)象
一句話總結(jié):多例模式的bean對(duì)象,spring框架只負(fù)責(zé)創(chuàng)建,不負(fù)責(zé)銷毀
對(duì)象出生:當(dāng)使用對(duì)象時(shí)創(chuàng)建新的對(duì)象實(shí)例
對(duì)象活著:只要對(duì)象在使用中,就一直活著
對(duì)象死亡:當(dāng)對(duì)象長(zhǎng)時(shí)間不用時(shí),被java的垃圾回收器回收了
init-method屬性:?于指定bean對(duì)象的初始化?法,此?法會(huì)在bean對(duì)象裝配后調(diào)?。必須是?個(gè)?參?法。
destory-method屬性:?于指定bean對(duì)象的銷毀?法,此?法會(huì)在bean對(duì)象銷毀前執(zhí)?。它只能為scope是singleton時(shí)起作?。

4.DI依賴注入的xml配置
4.1 set方法注入
set注入使用property標(biāo)簽,如果注入的是另外一個(gè)bean使用ref屬性,如果注入的是普通值使用value屬性
???"accountDao"?class="com.lagou.edu.dao.impl.JdbcAccountDaoImpl"?scope="prototype"?>
???????"name"?value="zhangsan">
???????"age"?value="1">
???
4.2 構(gòu)造函數(shù)注入
根據(jù)有參構(gòu)造函數(shù)參數(shù)索引:
???"accountDao"?class="com.lagou.edu.dao.impl.JdbcAccountDaoImpl"?scope="prototype"?>
???????"0"?ref="connectionUtils">
???????"1"?value="zhangsan">
???????"2"?value="1">
???根據(jù)有參構(gòu)造函數(shù)參數(shù)名稱:
???"accountDao"?class="com.lagou.edu.dao.impl.JdbcAccountDaoImpl"?scope="prototype"?>
???????"connectionUtils"?ref="connectionUtils">
???????"name"?value="zhangsan">
????????"age"?value="1">
???
4.3 復(fù)雜類型
???"accountDao"?class="com.lagou.edu.dao.impl.JdbcAccountDaoImpl"?scope="prototype"?>
???????"ConnectionUtils"?ref="connectionUtils">
????????
???????"myArray">
???????????
???????????????
???????????????array1
???????????????array2
???????????
???????
???????"myMap">
???????????
???????
???????"mySet">
???????????<set>
???????????????set1
???????????????set2
???????????set>
???????
???????"myProperties">
???????????
???????????????"prop1">value1
???????????????"prop2">value2
???????????
???????
???
5.DI依賴注入的注解和xml相結(jié)合實(shí)現(xiàn)方式
哪些bean定義在xml中,哪些bean的定義使用注解?
第三方j(luò)ar中的bean定義在xml
自己開發(fā)的bean使用注解
我是用Druid連接池,那么它屬于第三方j(luò)ar,所以我就在配置文件中配置
????
????"dataSource"?class="com.alibaba.druid.pool.DruidDataSource">
????????"driverClassName"?value="com.mysql.jdbc.Driver">
????????"url"?value="xxxx">
????????"username"?value="xxxx">
????????"password"?value="xxxx">
????
然后在使用它的地方使用注解:
5.1 @Autowired——按照類型注入
按照類型注入:如下帶代碼,它會(huì)在容器中找到一個(gè)類型為AccoutDao的對(duì)象注入進(jìn)來(lái)
@Service("transferService")//不指定也可以,變成了類名的首字母小寫
public?class?TransferServiceImpl?implements?TransferService?{
????//@Autowired?按照類型注入
????@Autowired
????private?AccountDao?accountDao;
????//可以加在屬性和set方法上,如果加在屬性上,set方法就不需要了
//????public?void?setAccountDao(AccountDao?accountDao)?{
//????????this.accountDao?=?accountDao;
//????}
如果AccountDao有多個(gè)實(shí)現(xiàn)類 ,且多個(gè)實(shí)現(xiàn)類都配置在了IOC容器中,怎么辦?
5.2 @Qualifier("具體id")——指定具體的id
@Service("transferService")
public?class?TransferServiceImpl?implements?TransferService?{
????//@Autowired?按照類型注入,如果按照類型無(wú)法唯一鎖定對(duì)象,可以結(jié)合@Qualifier("具體的id")
????@Autowired
????@Qualifier("accountDao")
????private?AccountDao?accountDao;
5.3 @Resource
@Resource 注解由J2EE 提供,需要導(dǎo)?包?javax.annotation.Resource。(JDK11默認(rèn)移除,jdk8可以直接使用)
@Resource 默認(rèn)按照 ByName ?動(dòng)注?。
public?class?TransferService?{
?@Resource?
?private?AccountDao?accountDao;
?@Resource(name="studentDao")?
?private?StudentDao?studentDao;
?@Resource(type="TeacherDao")?
?private?TeacherDao?teacherDao;
?@Resource(name="manDao",type="ManDao")?
?private?ManDao?manDao;
}
如果同時(shí)指定了?name?和?type,則從Spring上下?中找到唯?匹配的bean進(jìn)?裝配,找不到則拋出異常。
如果指定了?name,則從上下?中查找名稱(id)匹配的bean進(jìn)?裝配,找不到則拋出異常。
如果指定了?type,則從上下?中找到類似匹配的唯?bean進(jìn)?裝配,找不到或是找到多個(gè),都會(huì)拋出異常。
如果既沒(méi)有指定name,?沒(méi)有指定type,則?動(dòng)按照byName?式進(jìn)?裝配;
注意:
@Resource 在 Jdk 11中已經(jīng)移除,如果要使?,需要單獨(dú)引?jar包
?????javax.annotation
?????javax.annotation-api
?????1.3.2
5.4 注解掃描
5.4.1 引入命名空間——context
"1.0"?encoding="UTF-8"?>
"http://www.springframework.org/schema/beans"
???????xmlns:context="http://www.springframework.org/schema/context"
???????xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
???????xsi:schemaLocation="
????????????http://www.springframework.org/schema/beans
????????????https://www.springframework.org/schema/beans/spring-beans.xsd
????????????http://www.springframework.org/schema/context
????????????https://www.springframework.org/schema/context/spring-context.xsd
">
5.4.2 開啟注解掃描
"com.lagou.edu">
6.其他
引入外部資源文件:
"classpath:jdbc.properties"?/>
最終的配置文件只留下了一個(gè)第三方j(luò)ar
"1.0"?encoding="UTF-8"?>
"http://www.springframework.org/schema/beans"
???????xmlns:context="http://www.springframework.org/schema/context"
???????xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
???????xsi:schemaLocation="
????????????http://www.springframework.org/schema/beans
????????????https://www.springframework.org/schema/beans/spring-beans.xsd
????????????http://www.springframework.org/schema/context
????????????https://www.springframework.org/schema/context/spring-context.xsd
">
????
????"com.lagou.edu">
????
????"classpath:jdbc.properties"?/>
????
????"dataSource"?class="com.alibaba.druid.pool.DruidDataSource">
????????"driverClassName"?value="${jdbc.driver}">
????????"url"?value="${jdbc.url}">
????????"username"?value="${jdbc.username}">
????????"password"?value="${jdbc.password}">
????
6.DI依賴注入,純注解模式
不要xml配置文件,從java配置類啟動(dòng)
新建SpringCofig類
使用注解@Configuration?標(biāo)識(shí)當(dāng)前類是一個(gè)配置類
使用注解@ComponentScan({"com.lagou.edu"})?代替
進(jìn)行注解掃描使用注解@PropertySource({"classpath:jdbc.properties"})?代替
引入外部資源文件使用@Bean?將?法返回對(duì)象加?SpringIOC 容器
@Value?對(duì)變量賦值,可以直接賦值,也可以使? ${} 讀取資源配置?件中的信息
還可以使用@Import?引?其他配置類
//@Configuration?標(biāo)識(shí)當(dāng)前類是一個(gè)配置類
@Configuration
@ComponentScan({"com.lagou.edu"})
@PropertySource({"classpath:jdbc.properties"})
public?class?SpringConfig?{
????@Value("${jdbc.driver}")
????private?String?driverClassName;
????@Value("${jdbc.url}")
????private?String?url;
????@Value("${jdbc.username}")
????private?String?username;
????@Value("${jdbc.password}")
????private?String?password;
????@Bean("dataSource")
????public?DataSource?creatDataSource(){
????????DruidDataSource?druidDataSource?=?new?DruidDataSource();
????????druidDataSource.setDriverClassName(driverClassName);
????????druidDataSource.setUrl(url);
????????druidDataSource.setUsername(username);
????????druidDataSource.setPassword(password);
????????return?druidDataSource;
????}
}
6.1啟動(dòng)
6.1.1 JavaSE:
[email protected]
????public?void?test(){
????????ApplicationContext?applicationContext?=?new?AnnotationConfigApplicationContext(SpringConfig.class);
????????AccountDao?accountDao?=?(AccountDao)?applicationContext.getBean("accountDao");
????????System.out.println(accountDao);
????}
6.1.2 JavaWeb:
配置web.xml文件
?"-//Sun?Microsystems,?Inc.//DTD?Web?Application?2.3//EN"
?"http://java.sun.com/dtd/web-app_2_3.dtd"?>
??Archetype?Created?Web?Application
??
??
????contextClass
????org.springframework.web.context.support.AnnotationConfigWebApplicationContext
??
??
??
????contextConfigLocation
????com.lagou.edu.SpringConfig
??
??
??
??
????org.springframework.web.context.ContextLoaderListener
??
粉絲福利:實(shí)戰(zhàn)springboot+CAS單點(diǎn)登錄系統(tǒng)視頻教程免費(fèi)領(lǐng)取
???

?長(zhǎng)按上方微信二維碼?2 秒 即可獲取資料
感謝點(diǎn)贊支持下哈?
