SpringIOC基礎(chǔ)知識總結(jié)
點擊上方藍色字體,選擇“標星公眾號”
優(yōu)質(zhì)文章,第一時間送達
? 作者?|??鄧曉暉
來源 |??urlify.cn/VNv67n
1.BeanFactory和ApplicationContext的區(qū)別:
BeanFactory是Spring框架中IOC容器的頂層接口,它只是用來定義一些基礎(chǔ)功能,定義一些基礎(chǔ)規(guī)范,而ApplicationContext是它的一個子接口,所以ApplicationContext是具備BeanFactory提供的全部功能。
通常我們稱BeanFactory為SpringIOC的基礎(chǔ)容器,ApplicationContext是容器的高級接口,比如BeanFactory擁有更多的功能,比如說國際化支持和資源訪問(xml、java配置類)等等。
2.實例化bean的三種方式:
?式?:使??參構(gòu)造函數(shù)
在默認情況下,它會通過反射調(diào)??參構(gòu)造函數(shù)來創(chuàng)建對象。如果類中沒有?參構(gòu)造函數(shù),將創(chuàng)建失敗。
"connectionUtils"?class="com.lagou.edu.utils.ConnectionUtils">
?式?:使?靜態(tài)?法創(chuàng)建
在實際開發(fā)中,我們使?的對象有些時候并不是直接通過構(gòu)造函數(shù)就可以創(chuàng)建出來的,它可能在創(chuàng)建的過程中會做很多額外的操作。此時會提供?個創(chuàng)建對象的?法,恰好這個?法是static修飾的?法,即是此種情況。
例如,我們在做Jdbc操作時,會?到java.sql.Connection接?的實現(xiàn)類,如果是mysql數(shù)據(jù)庫,那么?的就是JDBC4Connection,但是我們不會去寫?JDBC4Connection connection = newJDBC4Connection()?,因為我們要注冊驅(qū)動,還要提供URL和憑證信息,??DriverManager.getConnection??法來獲取連接。
那么在實際開發(fā)中,尤其早期的項?沒有使?Spring框架來管理對象的創(chuàng)建,但是在設(shè)計時使?了??模式解耦,那么當接?spring之后,??類創(chuàng)建對象就具有和上述例?相同特征,即可采?此種?式配置。
"userService"?class="com.lagou.factory.BeanFactory"
factory-method="getTransferService">
?式三:使?實例化?法創(chuàng)建
此種?式和上?靜態(tài)?法創(chuàng)建其實類似,區(qū)別是?于獲取對象的?法不再是static修飾的了,?是類中的? 個普通?法。此種?式?靜態(tài)?法創(chuàng)建的使??率要??些。
在早期開發(fā)的項?中,??類中的?法有可能是靜態(tài)的,也有可能是?靜態(tài)?法,當是?靜態(tài)?法時,即可采?下?的配置?式:
"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">
???
測試:
???"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 ??
//同一個對象
???"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 ?
//不是同一個對象
3.2生命周期
singleton(默認)單例:IOC容器只有一個該類對象
一句話總結(jié):單例模式的bean對象生命周期與容器相同
對象出生:當容器創(chuàng)建時,對象就被創(chuàng)建了
對象活著:只要容器在,對象就一直活著
對象死亡:當容器銷毀時,對象就被銷毀了
prototype (多例)原型:每次使用該類的對象(getBean),都返回一個新的對象
一句話總結(jié):多例模式的bean對象,spring框架只負責創(chuàng)建,不負責銷毀
對象出生:當使用對象時創(chuàng)建新的對象實例
對象活著:只要對象在使用中,就一直活著
對象死亡:當對象長時間不用時,被java的垃圾回收器回收了
init-method屬性:?于指定bean對象的初始化?法,此?法會在bean對象裝配后調(diào)?。必須是?個?參?法。
destory-method屬性:?于指定bean對象的銷毀?法,此?法會在bean對象銷毀前執(zhí)?。它只能為scope是singleton時起作?。

4.DI依賴注入的xml配置
4.1 set方法注入
set注入使用property標簽,如果注入的是另外一個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é)合實現(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——按照類型注入
按照類型注入:如下帶代碼,它會在容器中找到一個類型為AccoutDao的對象注入進來
@Service("transferService")//不指定也可以,變成了類名的首字母小寫
public?class?TransferServiceImpl?implements?TransferService?{
????//@Autowired?按照類型注入
????@Autowired
????private?AccountDao?accountDao;
????//可以加在屬性和set方法上,如果加在屬性上,set方法就不需要了
//????public?void?setAccountDao(AccountDao?accountDao)?{
//????????this.accountDao?=?accountDao;
//????}
如果AccountDao有多個實現(xiàn)類 ,且多個實現(xiàn)類都配置在了IOC容器中,怎么辦?
5.2 @Qualifier("具體id")——指定具體的id
@Service("transferService")
public?class?TransferServiceImpl?implements?TransferService?{
????//@Autowired?按照類型注入,如果按照類型無法唯一鎖定對象,可以結(jié)合@Qualifier("具體的id")
????@Autowired
????@Qualifier("accountDao")
????private?AccountDao?accountDao;
5.3 @Resource
@Resource 注解由J2EE 提供,需要導(dǎo)?包?javax.annotation.Resource。(JDK11默認移除,jdk8可以直接使用)
@Resource 默認按照 ByName ?動注?。
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;
}
如果同時指定了?name?和?type,則從Spring上下?中找到唯?匹配的bean進?裝配,找不到則拋出異常。
如果指定了?name,則從上下?中查找名稱(id)匹配的bean進?裝配,找不到則拋出異常。
如果指定了?type,則從上下?中找到類似匹配的唯?bean進?裝配,找不到或是找到多個,都會拋出異常。
如果既沒有指定name,?沒有指定type,則?動按照byName?式進?裝配;
注意:
@Resource 在 Jdk 11中已經(jīng)移除,如果要使?,需要單獨引?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"?/>
最終的配置文件只留下了一個第三方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配置類啟動
新建SpringCofig類
使用注解@Configuration?標識當前類是一個配置類
使用注解@ComponentScan({"com.lagou.edu"})?代替
進行注解掃描使用注解@PropertySource({"classpath:jdbc.properties"})?代替
引入外部資源文件使用@Bean?將?法返回對象加?SpringIOC 容器
@Value?對變量賦值,可以直接賦值,也可以使? ${} 讀取資源配置?件中的信息
還可以使用@Import?引?其他配置類
//@Configuration?標識當前類是一個配置類
@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啟動
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
??
粉絲福利:實戰(zhàn)springboot+CAS單點登錄系統(tǒng)視頻教程免費領(lǐng)取
???

?長按上方微信二維碼?2 秒 即可獲取資料
感謝點贊支持下哈?
