一、ioc控制反轉和di依賴注入
1.控制反轉,字面可以理解為:主動權的轉移,原來一個應用程序內的對象是類通過new去主動創建并實例化的,對對像創建的主動權在程序代碼中。程序不僅要管理業務邏輯也要管理對的象創建和依賴關系。這是很累的,也跟軟件工程 "低耦合高內聚" 的概念不十分符合。
有了spring的ioc容器之后,對象的實例化和依賴關系管理都由ioc容器進行統一管理,主體類只要依賴ioc容器就夠了,需要啥,容器會給他注入進去,也就是只要聲明對象不用再主動去new,ioc容器幫忙把相應的對象注入到聲明對象中,使其變成實例化對象。(類似主體類提供一個軀體,ioc容器把靈魂注入進去,使其變成一個生命體,激活他),這樣創建對象的主動權就轉移交接了,
二、使用xml配置方式實現ioc
1.在ioc容器中配置了dao實現類和service類的bean,在容器加載的時候就會實例化這些bean到內存中。(bean.xml配置如下)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
<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注入是根據反射機制實現的,他在反射注入的時候會調用該方法名的set方法,如果set方法寫錯,或者根本沒寫,那么注入就會失敗。(bookservice類如下)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
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作為容器,初始化配置文件,然后從容器中根據id名取出容器中已經幫我們實例化好的對象。
1
2
3
4
5
6
7
8
9
10
11
|
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類和實現類如下:
接口類:
1
2
3
|
public interface bookdao { public string addbook(string bookname); } |
實現類:
1
2
3
4
5
6
7
8
9
10
|
public class bookdaoimpl implements bookdao { public bookdaoimpl() { system.out.println( "bookdao實例化" ); } public string addbook(string bookname) { return bookname+ "添加成功" ; } } |
5.運行測試結果:
6.大體思路如下圖:
程序中除了初始化容器用了new對象,其余的基本沒有new的存在。
二、注解方式配置ioc
注解配置方式目的和xml配置的目的一樣,都是為了實現bean的創建。常用的注解如下:
@component 在類定義之前添加@component注解,他會被spring容器識別,并轉為bean。
@repository 對dao實現類進行注解 (特殊的@component)
@service 用于對業務邏輯層進行注解, (特殊的@component)
@controller 用于控制層注解 , (特殊的@component)
裝配注解如下:
@autowired 默認按照類型裝配注入,想按照名稱來裝配的話要結合@quapfier(“name”)一起使用,使用@autowired注解可以不用set方法。@autowired 注釋進行自動注入時,spring 容器中匹配的候選 bean 數目必須有且僅有一個
@quapfier("name") 中的name是bean的名字,也就是id,和@autowired可以作為限定專配對象的名稱
@resource 默認按照名稱裝配注入,當找不到對應名成的bean的時候就按照類型匹配,如果還是找不到的話就會報錯,@autowired是spring提供的,@resource是javaee提供,使用@resource可以減少對spring的依賴
范例:
1.例子同上,只是配置bean的方式從xml文件中轉移到了代碼中,用注解體現。
2.除了把配置文件中<bean id="" class=""/>變成對應的注解外,另外一個區別在于,bean.xml文件中的修改,需要做如下,配置才能夠使注解生效
context的配置有如下方法:
1.僅掃描特定包下的特定類:
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 (正則表達式) |
custom | org.example.mytypefilter | spring3新增自定義type,org.springframework.core.type.typefilter |
1
2
3
4
5
6
7
|
<!-- 容器掃描包下的注解配置組件 --> <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的理解(推薦篇)就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支持服務器之家。
原文鏈接:http://www.cnblogs.com/caijh/p/7688044.html