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