? ? 在上一節(jié)中介紹了Spring IOC基于XML配置文件進(jìn)行bean或其他屬性的賦值及使用,但是另一個(gè)種方式在SSM開發(fā)中使用很多的,就是在bean上天假注解,快速的將bean注冊(cè)到ioc容器中。
一、使用注解的方式注冊(cè)bean到IOC容器中
? ? 1、主要使用的幾個(gè)注解:
? ? ? ? @Controller:標(biāo)記在控制層的類注冊(cè)為Bean組件
? ? ? ? @Service:標(biāo)記在業(yè)務(wù)邏輯層的類注冊(cè)為Bean組件
? ? ? ? @Repository:標(biāo)記在數(shù)據(jù)訪問層的類注冊(cè)為Bean組件
? ? ? ? @Component:標(biāo)記非三層的普通的類注冊(cè)為Bean組件
? ? ? ? 還有在前后端分離的情況下使用的@RestController,在控制層的類使用的
? ? 2、不是非要每一層都對(duì)應(yīng)相應(yīng)的注解,這么做主要是為了增強(qiáng)代碼可讀性,以及利于Spring進(jìn)行管理。
? ? 3、怎么使用注解將一個(gè)類注冊(cè)為Bean的步驟:
? ? ? ? 設(shè)置掃描包c(diǎn)ontect:component-scan
? ? ? ? 在對(duì)應(yīng)的類名上加注解
? 使用上面的注解會(huì)自動(dòng)將類名的首字母小寫設(shè)置為Bean的名字。
<context:component-scan base-package="com.engine" >
? ? <context:include-filter type="assignable" expression="com.engine.controller.UserController"/>
????<context:exclude-filter type="annotation" expression=""/>
</context:component-scan>
? ? 排除掃描:context:exclude-filter??設(shè)置需要排除掃描的選項(xiàng)
? ? 包含掃描:context:include-filter? 設(shè)置需要包含掃描的選項(xiàng)
? ? type:
? ? ? ? 1) annotation 默認(rèn),根據(jù)注解的完整限定名設(shè)置排除、包含
? ? ? ? 2)?assignable 根據(jù)類的完整限定名設(shè)置排除、包含
? ? ? ? ?還有aspectj 根據(jù)切面表達(dá)式設(shè)置、regex 根據(jù)正則表達(dá)式設(shè)置、custom 根據(jù)接口org.springframework.core.type .TypeFilter設(shè)置,下面三種形式一般很少使用,這里不做詳細(xì)介紹。
? ??use-default-filters是contect:component-scan的一個(gè)屬性,默認(rèn)為true,表示會(huì)包含@Controller @Service @Repository @Component注解,如果設(shè)置為false,則表示不會(huì)掃描@Controller @Service @Repository @Component注解。
? ? 4、使用注解的步驟
? ? ? ? 1)添加@Controller @Service @Repository @Component注解中的一個(gè)
? ? ? ? 2)添加自動(dòng)掃描注冊(cè)的組件,此操作需要依賴context命名空間,如果編譯器使用的是idea則會(huì)自動(dòng)幫忙引入,如果是其他的可能需要手動(dòng)引入,這里需要注意一下。
? ? ? ? 3)添加自動(dòng)掃描標(biāo)簽contect:component-scan。
? ? ? 注:
? ? ? ? 1)組件的id默認(rèn)就是組件的類名的首字母小寫,如果想要改名字的話,直接在注解中添加即可,例:@Service("user")
? ? ? ? 2)組件默認(rèn)情況下都是單例的,如果需要配置多例模式的話,可以在注解下添加@Scope注解。
二、使用@Autowired進(jìn)行自動(dòng)注入
? ? 1、當(dāng)使用@Autowired注解的時(shí)候,自動(dòng)裝配的時(shí)候是根據(jù)類型實(shí)現(xiàn)的。
? ? ? ? 如果只找到一個(gè),則直接進(jìn)行賦值
? ? ? ? 如果沒有找到,則直接拋出異常
? ? ? ? 如果找到多個(gè),則會(huì)按照變量名作為id進(jìn)行匹配:
? ? ? ? ? ? 1)匹配上的直接進(jìn)行裝配。
? ? ? ? ? ? 2)如果匹配不上則會(huì)報(bào)異常。
? ? 2、如果名字也沒有匹配到導(dǎo)致報(bào)錯(cuò)的解決辦法:
? ? ? ? 1)可以去修改屬性的名字對(duì)應(yīng)bean的名字:private UserService userServiceImpl;(當(dāng)userService的名字被多個(gè)類實(shí)現(xiàn)的時(shí)候修改屬性名字到具體的實(shí)現(xiàn)類上)
? ? ? ? 2)可以去修改Bean的名字對(duì)應(yīng)的屬性的名字:@Service("userService")
? ? ? ? 3)可以通過@Qualifer 設(shè)置屬性的名字(采用覆蓋的方式):@Qualifier("userServiceImpl")
? ? ? ? 4)可以通過@Primary設(shè)置其中一個(gè)Bean為主要的注入Bean:在想要主要使用的實(shí)現(xiàn)類上加@Primary注解
? ? ? ? 5)使用泛型作為自動(dòng)注入限定符
? ? 3、@Autowired可以寫在方法上面
? ? ? ? 被該注解修飾的方式會(huì)默認(rèn)優(yōu)先根據(jù)參數(shù)類型去匹配。
? ? ? ? 如果匹配到多個(gè)類型則會(huì)按照參數(shù)名字匹配。
????????當(dāng)方法上有@AutoWired注解時(shí):此方法會(huì)在bean創(chuàng)建的時(shí)候自動(dòng)調(diào)用,這個(gè)方法的每一個(gè)參數(shù)都會(huì)自動(dòng)注入值
? ? ? ? @Qualifier注解也可以作用在屬性上,用來被當(dāng)作id去匹配容器中的對(duì)象,如果沒有此注解,那么直接按照類型進(jìn)行匹配。
? ? 同理,該注解也可以寫在構(gòu)造器上,方法與上面一致
三、@Autowired和@Resource的區(qū)別
? ? 1、前者是Spring提供的注解,后者是JDK中定義的注解,依靠的是Java標(biāo)準(zhǔn)
? ? 2、前者默認(rèn)是按照類型進(jìn)行裝配,默認(rèn)情況下要求依賴的對(duì)象必須存在,后者默認(rèn)按照名字進(jìn)行匹配,同時(shí)可以指定name屬性
? ? 3、前者只適用于spring框架,而后者的擴(kuò)展性會(huì)更好。