Spring源碼(八)-Spring-IOC中的注解

前言

這段時(shí)間bug有點(diǎn)多,白天的時(shí)間幾乎都用在改bug了,近一個(gè)月都很少看書了爽航,得趕緊改完bug看書饭耳。在spring源碼分析結(jié)束之后衰腌,我們也已經(jīng)完成了循環(huán)依賴的解決方案以及設(shè)計(jì)模式,那么接下來(lái)我們分析下Spring中常用的注解饶囚。
這里先說(shuō)明下注解類型紫岩。

  • Annotition的類型使用關(guān)鍵字 @interface 而不是interface歇万。它繼承了java.lang.annotition.Annotition接口诅愚,并非申明了一個(gè)interface。

  • Annotation類型摹蘑、方法定義是獨(dú)特的、受限制的:

  • Annotation類型的方法必須申明為無(wú)參數(shù)制妄、無(wú)異常拋出的衔掸。這些方法定義了 Annotation的成員:方法名為成員名磷斧,而方法返回值為成員的類型。

特別的,如果方法名為 value()胳蛮, 則在注解的地方需要設(shè)置屬性值時(shí)可以直接寫入值抚垄,如:@Target({ElemenetType.TYPE}) 而不必寫為 @Target(value={ElemenetType.TYPE})
方法返回值必須為primitive類型浙滤、Class類型、枚舉類型揖膜、Annotation類型或者由前面類型之一作為元素的一位數(shù)組趁仙。

方法的后面可以使用default關(guān)鍵字加一個(gè)默認(rèn)數(shù)值來(lái)申明成員的默認(rèn)值薇组,null不能作為成員的默認(rèn)值炭菌,這與我們?cè)诜茿nnotation類型中定義方法有很大不同酌毡。
Annotation類型和他的方法不能使用Annotation類型的參數(shù)停团,成員不能是generic舌胶。只有返回值類型是Class的方法可以在Annotation類型中使用generic,因?yàn)榇朔椒軌蛴妙愞D(zhuǎn)換將各種類型轉(zhuǎn)換為Class洞辣。
Annotation類型又與接口有著近似之處:它可以定義常量、靜態(tài)成員類型(比如枚舉類型定義)沸久;Annotation類型也可以如接口一般被實(shí)現(xiàn)或者繼承挺峡。

1裳朋、元注解

元注解的作用就是負(fù)責(zé)注解其他注解暖眼。Java5.0定義了4個(gè)標(biāo)準(zhǔn)的meta-annotation類型,它們被用來(lái)提供對(duì)其它annotation類型作說(shuō)明 丧鸯。

  • 1.@Target,
  • 2.@Retention,
  • 3.@Documented,
  • 4.@Inherited
    這些可以通過(guò)Spirngboot的注解@SpringBootApplication了解到置尔。
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = {
        @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
        @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {

1.1、@Target

用于設(shè)定注解使用范圍
【詳細(xì)參考】@Target注解
Target通過(guò)ElementType來(lái)指定注解可使用范圍的枚舉集合。

  • ElementType.TYPE: 接口椅您、類、枚舉韭邓、注解
  • ElementType.FIELD: 字段凰浮、枚舉的常量
  • ElementType.METHOD: 方法
  • ElementType.PARAMETER: 方法參數(shù)
  • ElementType.CONSTRUCTOR: 構(gòu)造函數(shù)
  • ElementType.LOCAL_VARIABLE: 局部變量
  • ElementType.ANNOTATION_TYPE: 注解
  • ElementType.PACKAGE: 包

1.2、@Retention

定義注解的保留策略劝贸。
【詳細(xì)參考】@Retention
通過(guò)RetentionPolicy來(lái)指定注解的枚舉集合。

  • RetentionPolicy.SOURCE :注解僅存在于源碼中宫补,在class字節(jié)碼文件中不包含
  • RetentionPolicy.CLASS:默認(rèn)的保留策略虐秦,注解會(huì)在class字節(jié)碼文件中存在,但運(yùn)行時(shí)無(wú)法獲得
  • RetentionPolicy.RUNTIME:注解會(huì)在class字節(jié)碼文件中存在抚太,在運(yùn)行時(shí)可以通過(guò)反射獲取到

1.3、@Documented

用于描述其它類型的annotation應(yīng)該被作為被標(biāo)注的程序成員的公共API捞稿,因此可以被例如javadoc此類的工具文檔化剩愧。Documented是一個(gè)標(biāo)記注解仁卷,沒(méi)有成員。

1.4橙垢、@Inherited

說(shuō)明子類可以繼承父類中的該注解

  • 被@Inherited注解的注解只有在class上使用才會(huì)有“自動(dòng)繼承的特性”
  • “自動(dòng)繼承的特性”是指如果在子類上搜索注解珍手,其父類上的被@Inherited注解過(guò)的注解會(huì)考慮在內(nèi)
    【參考】@Inherited

2厦坛、Spring-IOC中的注解

2.1 五垮、Autowired注解

按照byType注入,這是最核心的注解杜秸,左右就不說(shuō)明了放仗,直接看源碼

@Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Autowired {
    boolean required() default true;
}

這里我們看到了元注解,說(shuō)明所有的注解都是基于這四種元注解。

  • @Autowired 根據(jù)bean 類型從spring 上下文中進(jìn)行查找撬碟,注冊(cè)類型必須唯一诞挨,否則報(bào)異常。與@Resource 的區(qū)別在于呢蛤,@Resource 允許通過(guò)bean 名稱或bean 類型兩種方式進(jìn)行查找@Autowired(required=false) 表示惶傻,如果spring 上下文中沒(méi)有找到該類型的bean 時(shí), 才會(huì)使用new()的方式;

  • @Autowired 標(biāo)注作用于 Map 類型時(shí)其障,如果 Map 的 key 為 String 類型银室,則 Spring 會(huì)將容器中所有類型符合 Map 的 value 對(duì)應(yīng)的類型的 Bean 增加進(jìn)來(lái),用 Bean 的 id 或 name 作為 Map 的 key励翼。

  • @Autowired 還有一個(gè)作用就是蜈敢,如果將其標(biāo)注在 BeanFactory 類型、ApplicationContext 類型抚笔、ResourceLoader 類型扶认、ApplicationEventPublisher 類型、MessageSource 類型上殊橙,那么 Spring 會(huì)自動(dòng)注入這些實(shí)現(xiàn)類的實(shí)例辐宾,不需要額外的操作狱从。

2.2 @Qualifier

通常和 @Autowired一起使用

@Autowired
@Qualifier("softService")
private ISoftPMService softPMService;
  • 說(shuō)明
    使用@Autowired 時(shí),如果找到多個(gè)同一類型的bean叠纹,則會(huì)拋異常季研,此時(shí)可以使用 @Qualifier("beanName"),明確指定bean的名稱進(jìn)行注入誉察,此時(shí)與 @Resource指定name屬性作用相同与涡。

2.3 @Resource

@Resource默認(rèn)按照ByName自動(dòng)注入
@Resource有兩個(gè)重要的屬性:name和type,而Spring將@Resource注解的name屬性解析為bean的名字持偏,而type屬性則解析為bean的類型

2.4驼卖、RequestMapping

這是springMVC中最常用的注解,在Spring4.0以后的版本推出了@GetMapping,@PostMapping,@PutMapping,@DeleteMapping等鸿秆,這些是為restful風(fēng)格提供的封裝注解酌畜,其實(shí)就是@RequestMapping和對(duì)應(yīng)RequestMethod合并的注解。

  • 作用 :@GetMapping = @RequestMapping(method = RequestMethod.GET)
  • 說(shuō)明:可以作用在類或者方法上卿叽,請(qǐng)求地址為類上的地址+方法上的地址
  • 參數(shù)綁定說(shuō)明:
    如:http://localhost/user/list?userId=10&userName=tom
@GetMapping("/user/list")
public User getUser(User user){
    
    ···········
    
}

這樣userId和username會(huì)映射到user對(duì)應(yīng)的屬性上桥胞。

2.5、@RequestParam考婴,@PathVariable

用于綁定參數(shù)贩虾,@PathVariable用于邦迪地址中rest風(fēng)格的參數(shù),@RequestParam用于綁定普通提交的參數(shù)沥阱。

@PostMapping("/status/update/{id}")
public RestResult updateStatus(@PathVariable Long id, @RequestParam("status") Boolean status) {
    
    ··········
    
}

@RequestParam(value="id",required=false)缎罢,required = faluse該參數(shù)非必須,默認(rèn)為true

2.6喳钟、@Scope

該方法指定bean的創(chuàng)建類型屁使,默認(rèn)為單例,另外scope還有prototype、request奔则、session蛮寂、global session作用域。scope="prototype"多例

  • 1.singleton : 全局有且僅有一個(gè)實(shí)例

  • 2.prototype:每次獲取Bean的時(shí)候會(huì)有一個(gè)新的實(shí)例

  • 3易茬、request:request表示該針對(duì)每一次HTTP請(qǐng)求都會(huì)產(chǎn)生一個(gè)新的bean酬蹋,同時(shí)該bean僅在當(dāng)前HTTP request內(nèi)有效

  • 4、session:session作用域表示該針對(duì)每一次HTTP請(qǐng)求都會(huì)產(chǎn)生一個(gè)新的bean抽莱,同時(shí)該bean僅在當(dāng)前HTTP session內(nèi)有效

  • 5范抓、global session作用域類似于標(biāo)準(zhǔn)的HTTPSession作用域,不過(guò)它僅僅在基于portlet的web應(yīng)用中才有意義

2.7食铐、@Service匕垫,@Repository,@Component

用于標(biāo)注業(yè)務(wù)層組件,可以看到該注解默認(rèn)使用了@Component
【@Service】

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Service {
  String value() default "";
}

【@Repository】

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Repository {
    String value() default "";
}

【@Component】

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Component {
    String value() default "";
}

由此可見(jiàn)這三個(gè)注解沒(méi)有功能沒(méi)有太大的區(qū)別虐呻,主要是用來(lái)標(biāo)注業(yè)務(wù)象泵,做業(yè)務(wù)方面的區(qū)分寞秃。

  • @Service用于標(biāo)注業(yè)務(wù)層組件

  • @Repository用于標(biāo)注數(shù)據(jù)訪問(wèn)組件,即DAO組件

  • @Component泛指組件偶惠,當(dāng)組件不好歸類的時(shí)候春寿,我們可以使用這個(gè)注解進(jìn)行標(biāo)注。

2.8忽孽、@Controller绑改、@RestController

用于標(biāo)注控制層組件即SpringMVC中的Controler
在4.0之后推出了@RestController其實(shí)就是@Controller和@ResponseBody的合集

2.9、@ResponseBody

該注解用于將Controller的方法返回的對(duì)象兄一,通過(guò)適當(dāng)?shù)腍ttpMessageConverter轉(zhuǎn)換為指定格式后厘线,寫入到Response對(duì)象的body數(shù)據(jù)區(qū)。
作用域類或者方法上
【詳細(xì)參考】(http://www.cnblogs.com/fangjian0423/p/springMVC-request-param-analysis.html)
這塊詳細(xì)的到springMVC源碼分析的時(shí)候再講

3.0出革、@RequestBody

  • 該注解用于讀取Request請(qǐng)求的body部分?jǐn)?shù)據(jù)皆的,使用系統(tǒng)默認(rèn)配置的HttpMessageConverter進(jìn)行解析,然后把相應(yīng)的數(shù)據(jù)綁定到要返回的對(duì)象上蹋盆;

  • 再把HttpMessageConverter返回的對(duì)象數(shù)據(jù)綁定到 controller中方法的參數(shù)上。

寫在最后

這一篇主要是寫了一些Sping的注解硝全,下一篇講下配合SpingBoot推出的注解

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末栖雾,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子伟众,更是在濱河造成了極大的恐慌析藕,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,122評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件凳厢,死亡現(xiàn)場(chǎng)離奇詭異账胧,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)先紫,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,070評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門治泥,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人遮精,你說(shuō)我怎么就攤上這事居夹。” “怎么了本冲?”我有些...
    開(kāi)封第一講書人閱讀 164,491評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵准脂,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我檬洞,道長(zhǎng)狸膏,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書人閱讀 58,636評(píng)論 1 293
  • 正文 為了忘掉前任添怔,我火速辦了婚禮湾戳,結(jié)果婚禮上贤旷,老公的妹妹穿的比我還像新娘。我一直安慰自己院塞,他們只是感情好遮晚,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,676評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著拦止,像睡著了一般县遣。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上汹族,一...
    開(kāi)封第一講書人閱讀 51,541評(píng)論 1 305
  • 那天萧求,我揣著相機(jī)與錄音,去河邊找鬼顶瞒。 笑死夸政,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的榴徐。 我是一名探鬼主播守问,決...
    沈念sama閱讀 40,292評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼坑资!你這毒婦竟也來(lái)了耗帕?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 39,211評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤袱贮,失蹤者是張志新(化名)和其女友劉穎仿便,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體攒巍,經(jīng)...
    沈念sama閱讀 45,655評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡嗽仪,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,846評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了柒莉。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片闻坚。...
    茶點(diǎn)故事閱讀 39,965評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖常柄,靈堂內(nèi)的尸體忽然破棺而出鲤氢,到底是詐尸還是另有隱情,我是刑警寧澤西潘,帶...
    沈念sama閱讀 35,684評(píng)論 5 347
  • 正文 年R本政府宣布卷玉,位于F島的核電站,受9級(jí)特大地震影響喷市,放射性物質(zhì)發(fā)生泄漏相种。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,295評(píng)論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望寝并。 院中可真熱鬧箫措,春花似錦、人聲如沸衬潦。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,894評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)镀岛。三九已至弦牡,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間漂羊,已是汗流浹背驾锰。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,012評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留走越,地道東北人椭豫。 一個(gè)月前我還...
    沈念sama閱讀 48,126評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像旨指,于是被迫代替她去往敵國(guó)和親赏酥。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,914評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容