javascript
Spring第三篇【Core模块之对象依赖】
tags: Spring
前言
在Spring的第二篇中主要講解了Spring Core模塊的使用IOC容器創(chuàng)建對(duì)象的問(wèn)題,Spring Core模塊主要是解決對(duì)象的創(chuàng)建和對(duì)象之間的依賴關(guān)系,因此本博文主要講解如何使用IOC容器來(lái)解決對(duì)象之間的依賴關(guān)系!
回顧以前對(duì)象依賴
我們來(lái)看一下我們以前關(guān)于對(duì)象依賴,是怎么的歷程
直接new對(duì)象
- 在最開(kāi)始,我們是直接new對(duì)象給serice的userDao屬性賦值...
寫(xiě)DaoFactory,用字符串來(lái)維護(hù)依賴關(guān)系
-
后來(lái),我們發(fā)現(xiàn)service層緊緊耦合了dao層。我們就寫(xiě)了DaoFactory,在service層只要通過(guò)字符串就能夠創(chuàng)建對(duì)應(yīng)的dao層的對(duì)象了。
-
DaoFactory
- serivce
DaoFactory讀取配置文件
-
再后來(lái),我們發(fā)現(xiàn)要修改Dao的實(shí)現(xiàn)類(lèi),還是得修改service層的源代碼呀..于是我們就在DaoFactory中讀取關(guān)于daoImpl的配置文件,根據(jù)配置文件來(lái)創(chuàng)建對(duì)象,這樣一來(lái),創(chuàng)建的是哪個(gè)daoImpl對(duì)service層就是透明的
-
DaoFactory
- service
Spring依賴注入
通過(guò)上面的歷程,我們可以清晰地發(fā)現(xiàn):對(duì)象之間的依賴關(guān)系,其實(shí)就是給對(duì)象上的屬性賦值!因?yàn)閷?duì)象上有其他對(duì)象的變量,因此存在了依賴...
Spring提供了好幾種的方式來(lái)給屬性賦值
- 1) 通過(guò)構(gòu)造函數(shù)
- 2) 通過(guò)set方法給屬性注入值
- p名稱(chēng)空間
- 4)自動(dòng)裝配(了解)
- 5) 注解
搭建測(cè)試環(huán)境
-
UserService中使用userDao變量來(lái)維護(hù)與Dao層之間的依賴關(guān)系
-
UserAction中使用userService變量來(lái)維護(hù)與Service層之間的依賴關(guān)系
-
userDao
- userService
- userAnction
構(gòu)造函數(shù)給屬性賦值
其實(shí)我們?cè)谥v解創(chuàng)建帶參數(shù)的構(gòu)造函數(shù)的時(shí)候已經(jīng)講過(guò)了...我們還是來(lái)回顧一下唄..
我們測(cè)試service和dao的依賴關(guān)系就好了....在serice中加入一個(gè)構(gòu)造函數(shù),參數(shù)就是userDao
public UserService(UserDao userDao) {this.userDao = userDao;//看看有沒(méi)有拿到userDaoSystem.out.println(userDao);}復(fù)制代碼applicationContext.xml配置文件
<!--創(chuàng)建userDao對(duì)象--><bean id="userDao" class="UserDao"/><!--創(chuàng)建userService對(duì)象--><bean id="userService" class="UserService"><!--要想在userService層中能夠引用到userDao,就必須先創(chuàng)建userDao對(duì)象--><constructor-arg index="0" name="userDao" type="UserDao" ref="userDao"></constructor-arg></bean>復(fù)制代碼- 測(cè)試:可以成功獲取到userDao對(duì)象
通過(guò)set方法給屬性注入值
我們這里也是測(cè)試service和dao層的依賴關(guān)系就好了...在service層通過(guò)set方法來(lái)把userDao注入到UserService中
- 為UserService添加set方法
applicationContext.xml配置文件:通過(guò)property節(jié)點(diǎn)來(lái)給屬性賦值
- 引用類(lèi)型使用ref屬性
- 基本類(lèi)型使用value屬性
- 測(cè)試:
內(nèi)部Bean
我們剛才是先創(chuàng)建userDao對(duì)象,再由userService對(duì)userDao對(duì)象進(jìn)行引用...我們還有另一種思維:先創(chuàng)建userService,發(fā)現(xiàn)userService需要userDao的屬性,再創(chuàng)建userDao...我們來(lái)看看這種思維方式是怎么配置的:
applicationContext.xml配置文件:property節(jié)點(diǎn)內(nèi)置bean節(jié)點(diǎn)
<!--1.創(chuàng)建userService,看到有userDao這個(gè)屬性2.而userDao這個(gè)屬性又是一個(gè)對(duì)象3.在property屬性下又內(nèi)置了一個(gè)bean4.創(chuàng)建userDao--><bean id="userService" class="UserService"><property name="userDao"><bean id="userDao" class="UserDao"/></property></bean>復(fù)制代碼- 測(cè)試
我們發(fā)現(xiàn)這種思維方式和服務(wù)器訪問(wèn)的執(zhí)行順序是一樣的,但是如果userDao要多次被其他service使用的話,就要多次配置了...
p 名稱(chēng)空間注入屬性值
p名稱(chēng)控件這種方式其實(shí)就是set方法的一種優(yōu)化,優(yōu)化了配置而已...p名稱(chēng)空間這個(gè)內(nèi)容需要在Spring3版本以上才能使用...我們來(lái)看看:
applicationContext.xml配置文件:使用p名稱(chēng)空間
<bean id="userDao" class="UserDao"/><!--不用寫(xiě)property節(jié)點(diǎn)了,直接使用p名稱(chēng)空間--><bean id="userService" class="UserService" p:userDao-ref="userDao"/>復(fù)制代碼- 測(cè)試
自動(dòng)裝配
Spring還提供了自動(dòng)裝配的功能,能夠非常簡(jiǎn)化我們的配置
自動(dòng)裝載默認(rèn)是不打開(kāi)的,自動(dòng)裝配常用的可分為兩種:
- 根據(jù)名字來(lái)裝配
- 根據(jù)類(lèi)型類(lèi)裝配
XML配置根據(jù)名字
applicationContext.xml配置文件:使用自動(dòng)裝配,根據(jù)名字
<bean id="userDao" class="UserDao"/><!--1.通過(guò)名字來(lái)自動(dòng)裝配2.發(fā)現(xiàn)userService中有個(gè)叫userDao的屬性3.看看IOC容器中沒(méi)有叫userDao的對(duì)象4.如果有,就裝配進(jìn)去--><bean id="userService" class="UserService" autowire="byName"/>復(fù)制代碼- 測(cè)試
XML配置根據(jù)類(lèi)型
applicationContext.xml配置文件:使用自動(dòng)裝配,根據(jù)類(lèi)型
值得注意的是:如果使用了根據(jù)類(lèi)型來(lái)自動(dòng)裝配,那么在IOC容器中只能有一個(gè)這樣的類(lèi)型,否則就會(huì)報(bào)錯(cuò)!
<bean id="userDao" class="UserDao"/><!--1.通過(guò)名字來(lái)自動(dòng)裝配2.發(fā)現(xiàn)userService中有個(gè)叫userDao的屬性3.看看IOC容器UserDao類(lèi)型的對(duì)象4.如果有,就裝配進(jìn)去--><bean id="userService" class="UserService" autowire="byType"/>復(fù)制代碼- 測(cè)試:
我們這只是測(cè)試兩個(gè)對(duì)象之間的依賴關(guān)系,如果我們有很多對(duì)象,我們也可以使用默認(rèn)自動(dòng)分配
###使用注解來(lái)實(shí)現(xiàn)自動(dòng)裝配###
@Autowired注解來(lái)實(shí)現(xiàn)自動(dòng)裝配:
- 可以在構(gòu)造器上修飾
- 也可以在setter方法上修飾
- 來(lái)自java的@Inject的和@AutoWired有相同的功能
如果沒(méi)有匹配到bean,又為了避免異常的出現(xiàn),我們可以使用required屬性上設(shè)置為false。【謹(jǐn)慎對(duì)待】
- 測(cè)試代碼
順利拿到userDao的引用
注解
自從jdk5有了注解這個(gè)新特性,我們可以看到Struts2框架、Hibernate框架都支持使用注解來(lái)配置信息...
通過(guò)注解來(lái)配置信息就是為了簡(jiǎn)化IOC容器的配置,注解可以把對(duì)象添加到IOC容器中、處理對(duì)象依賴關(guān)系,我們來(lái)看看怎么用吧:
使用注解步驟:
- 1)先引入context名稱(chēng)空間
- xmlns:context="http://www.springframework.org/schema/context" 復(fù)制代碼
- 2)開(kāi)啟注解掃描器
- `<context:component-scan base-package=""></context:component-scan>` 復(fù)制代碼
- 第二種方法:也可以通過(guò)自定義掃描類(lèi)以@CompoentScan修飾來(lái)掃描IOC容器的bean對(duì)象。。如下代碼:
在使用@ComponentScan()這個(gè)注解的時(shí)候,在測(cè)試類(lèi)上需要@ContextConfiguration這個(gè)注解來(lái)加載配置類(lèi)...
- @ContextConfiguration這個(gè)注解又在Spring的test包下..
創(chuàng)建對(duì)象以及處理對(duì)象依賴關(guān)系,相關(guān)的注解:
- @ComponentScan掃描器
- @Configuration表明該類(lèi)是配置類(lèi)
- @Component 指定把一個(gè)對(duì)象加入IOC容器--->@Name也可以實(shí)現(xiàn)相同的效果【一般少用】
- @Repository 作用同@Component; 在持久層使用
- @Service 作用同@Component; 在業(yè)務(wù)邏輯層使用
- @Controller 作用同@Component; 在控制層使用
- @Resource 依賴關(guān)系
- 如果@Resource不指定值,那么就根據(jù)類(lèi)型來(lái)找,相同的類(lèi)型在IOC容器中不能有兩個(gè)
- 如果@Resource指定了值,那么就根據(jù)名字來(lái)找
測(cè)試代碼
- UserDao
- userService
- userAction
- 測(cè)試
注解和XML配置是可以混合使用的...
如果您覺(jué)得這篇文章幫助到了您,可以給作者一點(diǎn)鼓勵(lì)
總結(jié)
以上是生活随笔為你收集整理的Spring第三篇【Core模块之对象依赖】的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 一次前端笔试总结
- 下一篇: 前端路由的两种实现原理