3、Spring IOC的註解使用
1、概述
上篇文章中整理了通過XML檔案進行Bean或某些屬性的賦值,xml的方式在企業開發中已經過時了,這篇文章即為進階篇。介紹如何在bean上添加註解,快速的將bean註冊到ioc容器。
2、使用註解的方式註冊Bean到 IOC容器中
如果想要將自定義的bean物件新增到IOC容器中,需要在類上新增某些註解 。
Spring中包含4個主要的元件添加註解:
@Controller:控制器,推薦給controller層新增此註解
@Service:業務邏輯,推薦給業務邏輯層新增此註解
@Repository:倉庫管理,推薦給資料訪問層新增此註解
@Component:給不屬於以上基層的元件新增此註解
注意:我們雖然人為的給不同的層新增不同的註解,但是在spring看來,可以在任意層新增任意註解。spring底層是不會給具體的層次驗證註解,這樣寫的目的只是為了提高可讀性,最偷懶的方式就是給所有想交由IOC容器管理的bean物件新增component註解
使用註解需要如下步驟:
1、新增上述四個註解中的任意一個
2、新增自動掃描註解的元件,此操作需要依賴context名稱空間
3、新增自動掃描的標籤context:component‐scan
注意:當使用註解註冊元件和使用配置檔案註冊元件是一樣的,但是要注意:
1、元件的id預設就是元件的類名首字元小寫,如果非要改名字的話,直接在註解中新增即可。如@Controller("userInfo")
2、元件預設情況下都是單例的,如果需要配置多例模式的話,可以在註解下新增@Scope註解
<!-- 定義自動掃描的基礎包: base‐package:指定掃描的基礎包,spring在啟動的時候會將基礎包及子包下所有加了註解的類都自動掃描進IOC容器--> <context:component-scan base-package="com.zhl"></context:component-scan>
package com.zhl.controller; import org.springframework.stereotype.Controller; @Controllerpublic class UserController { }
package com.zhl.service; import org.springframework.stereotype.Service; @Service public class UserService { }
package com.zhl.dao; import org.springframework.stereotype.Repository; @Repository public class UserDao { }
3、定義掃描包時要包含的類和不要包含的類
當定義好基礎的掃描包後,在某些情況下可能要有選擇性的配置是否要註冊bean到IOC容器中,此時可以通過如下的方式進行配置。
<!-- 定義自動掃描的基礎包: base‐package:指定掃描的基礎包,spring在啟動的時候會將基礎包及子包下所有加了注 解的類都自動掃描進IOC容器--> <context:component-scan base-package="com.zhl.entity" use-default-filters="false"> <!--當定義好基礎掃描的包之後,可以排除包中的某些類,使用如下的方式: type:表示指定過濾的規則 annotation:按照註解進行排除,標註了指定註解的元件不要,expression表示要過濾的註解的全限定類名,該註解下的Bean全部排除 assignable:指定排除某個具體的類,按照類排除,expression表示不註冊的具體類名--> <!-- <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>--> <!--<context:exclude-filter type="assignable" expression="com.zhl.entity.User"/> --> <!--指定只掃描哪些元件,預設情況下是全部掃描的,所以此時要配置的話需要在component‐scan標籤中新增 use‐default‐filters="false"--> <!--<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>--> <context:include-filter type="assignable" expression="com.zhl.entity.User"/> </context:component-scan>
4、使用@AutoWired進行自動注入
使用註解的方式實現自動注入,需要使用@AutoWired註解。
注意:當使用AutoWired註解的時候,自動裝配的時候是根據型別實現的。
a、如果只找到一個,則直接進行賦值,
b、如果沒有找到,則直接丟擲異常,
c、如果找到多個,那麼會按照變數名作為id繼續匹配,
c.1、匹配上直接進行裝配
c.2、如果匹配不上則直接報異常
package com.zhl.controller; import com.zhl.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; @Controller public class UserController { /* 使用@Autowired來實現自動注入 bytype? byname? ·預設優先根據型別去匹配 ·如果匹配到多個型別則會按照名字匹配 ·如果名又沒有匹配到則會報錯: 1.可以去修改屬性的名字對應bean的名字:userServiceImpl 2.可以去修改Bean的名字對應屬性的名字:@Service("userService") 3.可以通過@Qualifier設定屬性的名字(覆蓋) :@Qualifier("userServiceImpl") 4.可以通過@Primary 設定其中一個Bean為主要的自動注入Bean:@Primary 5.使用泛型作為自動注入限定符 */ @Autowired private UserService userService; public void getUser() { userService.getUser(); } }
package com.zhl.service; import org.springframework.stereotype.Service; @Service public class UserService { public void getUser() { System.out.println("返回User"); } }
5、@AutoWired可以進行定義在方法上
此註解不僅可以使 用在成員變數上,也可以使用在方法上。
package com.zhl.controller; import com.zhl.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; @Controller public class UserController { /* 使用@Autowired來實現自動注入 bytype? byname? ·預設優先根據型別去匹配 ·如果匹配到多個型別則會按照名字匹配 ·如果名又沒有匹配到則會報錯: 1.可以去修改屬性的名字對應bean的名字:userServiceImpl 2.可以去修改Bean的名字對應屬性的名字:@Service("userService") 3.可以通過@Qualifier設定屬性的名字(覆蓋) :@Qualifier("userServiceImpl") 4.可以通過@Primary 設定其中一個Bean為主要的自動注入Bean:@Primary 5.使用泛型作為自動注入限定符 */ @Autowired private UserService userService; public void getUser() { userService.getUser(); } /** * @Autowired 也可以寫在構造器上面 * ·預設優先根據引數型別去匹配 * ·如果匹配到多個型別則會按照引數名字匹配 */ @Autowired public UserController(UserService userService) { this.userService = userService; } /** * @Autowired 也可以寫在方法上面 * ·預設優先根據引數型別去匹配 * ·如果匹配到多個型別則會按照引數名字匹配 * @param userService * 當方法上有@AutoWired註解時: * 1、此方法在bean建立的時候會自動呼叫 * 2、這個方法的每一個引數都會自動注入值 */ @Autowired public void createUserSerive(UserService userService){ this.userService=userService; } }
6、自動裝配的註解@AutoWired,@Resource
在使用自動裝配的時候,除了可以使用@AutoWired註解之外,還可以使用@Resource註解,區別如下:
a、@AutoWired:是spring中提供的註解,@Resource:是jdk中定義的 註解,依靠的是java的標準
b、@AutoWired預設是按照型別進行裝配,預設情況下要求依賴的物件必須存在,@Resource預設是按照名字進行匹配的,同時可以指定name屬性。
c、@AutoWired只適合spring框架,而@Resource擴充套件性更好
d、@Autowired如果需要按照名稱匹配需要和@Qualifier一起使用