詳談Spring對(duì)IOC的理解(推薦篇)
一、IOC控制反轉(zhuǎn)和DI依賴(lài)注入
1.控制反轉(zhuǎn),字面可以理解為:主動(dòng)權(quán)的轉(zhuǎn)移,原來(lái)一個(gè)應(yīng)用程序內(nèi)的對(duì)象是類(lèi)通過(guò)new去主動(dòng)創(chuàng)建并實(shí)例化的,對(duì)對(duì)像創(chuàng)建的主動(dòng)權(quán)在程序代碼中。程序不僅要管理業(yè)務(wù)邏輯也要管理對(duì)的象創(chuàng)建和依賴(lài)關(guān)系。這是很累的,也跟軟件工程 "低耦合高內(nèi)聚" 的概念不十分符合。
有了spring的ioc容器之后,對(duì)象的實(shí)例化和依賴(lài)關(guān)系管理都由IOC容器進(jìn)行統(tǒng)一管理,主體類(lèi)只要依賴(lài)ioc容器就夠了,需要啥,容器會(huì)給他注入進(jìn)去,也就是只要聲明對(duì)象不用再主動(dòng)去new,ioc容器幫忙把相應(yīng)的對(duì)象注入到聲明對(duì)象中,使其變成實(shí)例化對(duì)象。(類(lèi)似主體類(lèi)提供一個(gè)軀體,ioc容器把靈魂注入進(jìn)去,使其變成一個(gè)生命體,激活他),這樣創(chuàng)建對(duì)象的主動(dòng)權(quán)就轉(zhuǎn)移交接了,
二、使用xml配置方式實(shí)現(xiàn)IOC
1.在ioc容器中配置了dao實(shí)現(xiàn)類(lèi)和service類(lèi)的bean,在容器加載的時(shí)候就會(huì)實(shí)例化這些bean到內(nèi)存中。(bean.xml配置如下)
<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 "> <!-- BookDao Bean --> <bean id="bookDao" class="com.study.DaoImpl.BookDaoImpl"></bean> <!-- BookService Bean--> <bean id="bookService" class="com.study.Service.BookService"> <!-- BookService中的聲明了BookDao對(duì)象,通過(guò)ref屬性將BookDao的bean注入到對(duì)象中 --> <property name="bookDao" ref="bookDao"/> </bean> </beans>
2. service類(lèi)中需要用到dao類(lèi)的實(shí)例(正常情況下需要new一個(gè)dao類(lèi)對(duì)象),但是用ioc容器接管后只需要聲明dao接口對(duì)象即可,然后寫(xiě)一個(gè)dao對(duì)象的set方法。(要注入的對(duì)象必須要有set方法,否則將報(bào)錯(cuò) Bean property 'bookDao' is not writable or has an invalid setter method)因?yàn)閟pring注入是根據(jù)反射機(jī)制實(shí)現(xiàn)的,他在反射注入的時(shí)候會(huì)調(diào)用該方法名的set方法,如果set方法寫(xiě)錯(cuò),或者根本沒(méi)寫(xiě),那么注入就會(huì)失敗。(BookService類(lèi)如下)
public class BookService { private BookDao bookDao; public BookService() { System.out.println("BookService實(shí)例化"); } public void setBookDao(BookDao bookDao) { System.out.println("BookService屬性初始化裝配成功"); this.bookDao = bookDao; } public void storeBook(String bookname){ System.out.println("圖書(shū)上架"); System.out.println(bookDao.addBook(bookname)); } }
如上代碼:BookSerivce類(lèi)需要用到BookDao對(duì)象,但是卻沒(méi)有new對(duì)象,只有一個(gè)set方法,這個(gè)set方法就是ioc容器注入的入口(必不可少),
3.此處我們用ApplicationContext作為容器,初始化配置文件,然后從容器中根據(jù)id名取出容器中已經(jīng)幫我們實(shí)例化好的對(duì)象。
public class TestDmeo { BookService bookService; @Test public void testStoreBook(){ System.out.println("容器初始化"); ApplicationContext app = new ClassPathXmlApplicationContext("bean.xml"); bookService = (BookService) app.getBean("bookService");//將對(duì)象注入到聲明好的BookService對(duì)象中。(bookService就是配置文件中的id) bookService.storeBook("Spring MVC"); } }
4.dao類(lèi)和實(shí)現(xiàn)類(lèi)如下:
接口類(lèi):
public interface BookDao { public String addBook(String BookName); }
實(shí)現(xiàn)類(lèi):
public class BookDaoImpl implements BookDao { public BookDaoImpl() { System.out.println("BookDao實(shí)例化"); } public String addBook(String BookName) { return BookName+"添加成功"; } }
5.運(yùn)行測(cè)試結(jié)果:
6.大體思路如下圖:
程序中除了初始化容器用了new對(duì)象,其余的基本沒(méi)有new的存在。
二、注解方式配置IOC
注解配置方式目的和xml配置的目的一樣,都是為了實(shí)現(xiàn)bean的創(chuàng)建。常用的注解如下:
@Component 在類(lèi)定義之前添加@Component注解,他會(huì)被spring容器識(shí)別,并轉(zhuǎn)為bean。
@Repository 對(duì)Dao實(shí)現(xiàn)類(lèi)進(jìn)行注解 (特殊的@Component)
@Service 用于對(duì)業(yè)務(wù)邏輯層進(jìn)行注解, (特殊的@Component)
@Controller 用于控制層注解 , (特殊的@Component)
裝配注解如下:
@Autowired 默認(rèn)按照類(lèi)型裝配注入,想按照名稱(chēng)來(lái)裝配的話(huà)要結(jié)合@Quapfier(“name”)一起使用,使用@Autowired注解可以不用set方法。@Autowired 注釋進(jìn)行自動(dòng)注入時(shí),Spring 容器中匹配的候選 Bean 數(shù)目必須有且僅有一個(gè)
@Quapfier("name") 中的name是bean的名字,也就是id,和@Autowired可以作為限定專(zhuān)配對(duì)象的名稱(chēng)
@Resource 默認(rèn)按照名稱(chēng)裝配注入,當(dāng)找不到對(duì)應(yīng)名成的bean的時(shí)候就按照類(lèi)型匹配,如果還是找不到的話(huà)就會(huì)報(bào)錯(cuò),@Autowired是spring提供的,@Resource是javaee提供,使用@Resource可以減少對(duì)spring的依賴(lài)
范例:
1.例子同上,只是配置bean的方式從xml文件中轉(zhuǎn)移到了代碼中,用注解體現(xiàn)。
2.除了把配置文件中<bean id="" class=""/>變成對(duì)應(yīng)的注解外,另外一個(gè)區(qū)別在于,bean.xml文件中的修改,需要做如下,配置才能夠使注解生效
context的配置有如下方法:
1.僅掃描特定包下的特定類(lèi):
<context:component-scan base-package="com.study" resource-pattern="Service/B*.class"/>
這是掃描Service包下B開(kāi)頭的所有類(lèi)。
2.使用<context:include-filter .../>和<context:exclude-filter .../>配置那些需要和不需要的掃描的包
Filter Type | Examples Expression | Description |
annotation | org.example.SomeAnnotation | 符合SomeAnnoation的target class(注解類(lèi)) |
assignable | org.example.SomeClass | 指定class或interface的全名(指定確切的類(lèi)或接口) |
aspectj | org.example..*Service+ | AspectJ語(yǔ)法 |
regex | org\.example\.Default.* | Regelar Expression (正則表達(dá)式) |
custom | org.example.MyTypeFilter | Spring3新增自定義Type,org.springframework.core.type.TypeFilter |
<!-- 容器掃描包下的注解配置組件 --> <context:component-scan base-package="com.study" use-default-filters="false"> <context:include-filter type="aspectj" expression="com.study.Service.*"/> <!-- 模糊過(guò)濾 --> <context:include-filter type="annotation" expression="org.springframework.stereotype.Component"/><!-- 過(guò)濾指定的注解 --> <context:include-filter type="assignable" expression="com.study.Service.BookService"/><!-- 過(guò)濾指定的類(lèi)或接口,路徑要完整,如果是接口的話(huà),所有派生類(lèi)都會(huì)被過(guò)濾 --> <context:include-filter type="regex" expression="com.*"/> </context:component-scan>
<context:exclude-filter ../>要配在<context:include-filter .../>的后面。
以上這篇詳談Spring對(duì)IOC的理解(推薦篇)就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Apache DolphinScheduler實(shí)現(xiàn)自動(dòng)化打包單機(jī)/集群部署詳解
這篇文章主要為大家介紹了Apache DolphinScheduler實(shí)現(xiàn)自動(dòng)化打包單機(jī)/集群部署詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-09-09Java轉(zhuǎn)換流(InputStreamReader/OutputStreamWriter)的使用
本文主要介紹了Java轉(zhuǎn)換流(InputStreamReader/OutputStreamWriter)的使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-01-01Mybatis注解開(kāi)發(fā)@Select執(zhí)行參數(shù)和執(zhí)行sql語(yǔ)句的方式(最新詳解)
@Select 是 Mybatis 框架中的一個(gè)注解,用于執(zhí)行 SQL 查詢(xún)語(yǔ)句,并把查詢(xún)結(jié)果映射到指定的 Java 對(duì)象中,這篇文章主要介紹了Mybatis注解開(kāi)發(fā)@Select執(zhí)行參數(shù)和執(zhí)行sql語(yǔ)句的方式,需要的朋友可以參考下2023-07-07Spring?WebClient實(shí)戰(zhàn)示例
本文主要介紹了Spring?WebClient實(shí)戰(zhàn)示例,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-01-01Junit 5中@ParameterizedTest與@EnumSource結(jié)合使用
今天小編就為大家分享一篇關(guān)于Junit 5中@ParameterizedTest與@EnumSource結(jié)合使用,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2018-12-12netty-grpc一次DirectByteBuffer內(nèi)存泄露問(wèn)題
這篇文章主要介紹了netty-grpc一次DirectByteBuffer內(nèi)存泄露問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-12-12SpringBoot+MinIO實(shí)現(xiàn)文件切片極速詳解
在現(xiàn)代Web應(yīng)用中,文件上傳是一個(gè)常見(jiàn)的需求,尤其是對(duì)于大文件的上傳,如視頻、音頻或大型文檔,所以本文就來(lái)為大家介紹一下如何使用Spring Boot和MinIO實(shí)現(xiàn)文件切片極速上傳技術(shù)吧2023-12-12Spring實(shí)現(xiàn)在非controller中獲取request對(duì)象
這篇文章主要介紹了Spring實(shí)現(xiàn)在非controller中獲取request對(duì)象方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-08-08Java使用SFTP上傳文件到服務(wù)器的簡(jiǎn)單使用
這篇文章主要介紹了Java使用SFTP上傳文件到服務(wù)器的簡(jiǎn)單使用,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2017-02-02