淺談context:component-scan注解

前言:因為好久沒有碰ssm組合式開發(fā)的東西了译仗,加上學的時候稍微咸魚了一點觉壶,好多東西其實都忘了髓需,打算抽時間一點一點的把這些內容撿起來玻褪。

這次我們來聊一聊context:component-scan注解肉渴,今天看到一段代碼,在配置文件aplicationContext.xml中看到<context:component-scan>這個注解带射,代碼如下:

<context:component-scan base-package="com.hrms">
    <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"></context:exclude-filter>
</context:component-scan>

我們先來聊一聊這個配置的作用吧同规。

通常情況下,我們創(chuàng)建一個spring的項目,如果注冊bean對象是通過注解注冊而非配置文件的話券勺,在配置文件當中都會看到<context:component-scan>這個注解绪钥,這個注解的作用大家想必都能反應過來,掃描包唄关炼,開啟注解掃描程腹。或者說更加準確的說儒拂,是注冊bean對象寸潦,當配置完這個標簽之后,spring就會自動掃描base-package屬性下面的所有包社痛,如果掃描的包中有被@Service, @Controller, @Repository, @Component注解的類的話见转,根據spring控制反轉的功能,spring會把這些類注冊成bean蒜哀。

打個比方說:我在一個類上寫上@Component注解斩箫,spring就會將這個類注冊成一個bean對象,并放到容器中撵儿,bean對象默認的名字是類名的首字母小寫乘客,如果我寫上@Component(value="abc"),那么bean對象的名字就是abc统倒,很好理解吧寨典。

啥?還不理解房匆?那我舉個栗子:(已明白的小伙伴請往下翻)
比方說我這里有一個實體類耸成,我想把它注入到spring的ioc容器當中:

public class User{
    private String name;
    private Inteager age;
}

用配置文件的方式我們應該怎么做呢?當然是在配置文件當中寫入下面的代碼:

<bean name="user" class="xx.xx.User"></bean>

然后要用這個對象的時候浴鸿,我需要先通過配置文件創(chuàng)建一個配置文件對象(例如通過ClassPathXmlApplicationContext類去new一個配置對象)井氢,然后調用配置對象的getBean方法來獲取這個對象

是不是感覺挺麻煩的,我又不想向這個對象當中注入什么復雜的屬性岳链,甚至不用注入屬性花竞,那我為什么還要在配置文件當中去寫這樣一行代碼呢?于是spring官方提供了比較人性化的操作:

@Component
public class User{
    private String name;
    private Inteager age;
}

這樣通過一個注解即可完成注冊操作掸哑,后面需要用的時候在加上@Autowired注解即可约急,便捷不少吧。當然這里的@Component可以根據情況換成@Service苗分、@Controller厌蔽、@Repository,默認情況下摔癣,只要有這四個屬性注解在類上奴饮,就相當于告訴Spring,這個類是需要它來管理的纬向。

  • @Controller: 用于控制器層
  • @Service: 用于服務層
  • @Repository: 用于DAO
  • @Component:用于其他組件

所以如果僅僅是在配置文件中寫<context:component-scan base-package="com.sparta.trans"/> Use-default-filter屬性此時為true時,那么會對base-package包或者子包下所有的java類進行掃描,并把匹配的java類注冊成bean戴卜。這種情況下可以發(fā)現掃描的力度還是非常大的

但是逾条,在SSM組合式開發(fā)當中,Controller控制層應當是由SpringMVC單獨管理的投剥,不應該交給spring管理师脂,原因是因為:SSM組合式開發(fā)當中,spring的配置文件與springmvc的配置文件分開加載薇缅,在spring容器初始化的時候危彩,會先加載(web.xml)<context-param>中的配置攒磨,之后再加載<servlet>中的<init-param>去加載前端控制器泳桦。加載springmvc的時候,如果掃描到@service會重新加載這個service的bean(都是沒有aop配置事務控制的)娩缰,可能會覆蓋之前的service灸撰,導致service的事務失效。因此service層是不應該讓SpringMVC的配置文件加載的時候再加載一遍的拼坎,所以不能只寫上文中提到的單單開啟注解掃描的配置代碼

看到這里浮毯,小伙伴應該都明白了,這種做法可能導致事務失效泰鸡!oh my god债蓝!多么令人害怕的事情,不過不要緊盛龄,因為<context:component-scan>這個標簽還有兩個子標簽饰迹,可以完美的解決這個問題,我們把目光再次回到本文開頭提到的代碼:

<context:component-scan base-package="com.hrms">
    <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"></context:exclude-filter>
</context:component-scan>

這里有一個<context:exclude-filter>注解余舶,另外一個注解是<context:include-filter>注解啊鸭,顧名思義,exclude即排除匿值,就是說赠制,我掃描的時候排除掉你這個注解,排除的注解我在后面通過expression來指定(這里排除掉的是@Controller注解)挟憔,而include即包含钟些,我掃描的時候只加載被指定的注解注解過的類。相當于手機的黑名單和白名單绊谭,(這里注意如果使用白名單記得把use-default-filters這個過濾器屬性設為false政恍,否則他會采用默認的過濾器,白名單就失效了)龙誊。這樣就可以完美的避免重復加載的問題抚垃,防止事務失效。
說完了作用,我們來看看這兩個注解的屬性鹤树,這兩個屬性都使用type和expression屬性一起協(xié)作來定義組件掃描策略:

過濾器類型 描述
annotation 過濾器掃描使用注解所標注的那些類铣焊,通過expression屬性指定要掃描的注解
assignable 過濾器掃描派生于expression屬性所指定類型的那些類
aspectj 過濾器掃描與expression屬性所指定的AspectJ表達式所匹配的那些類
custom 使用自定義的org.springframework.core.type.TypeFliter實現類,該類由expression屬性指定
regex 過濾器掃描類的名稱與expression屬性所指定正則表示式所匹配的那些類
  • 再次強調一下:若使用include-filter去定制掃描內容罕伯,要在use-default-filters="false"的情況下曲伊,不然會“失效”,被默認的過濾機制所覆蓋

這樣我們就可以愉快的開始使用注解開發(fā)啦追他,也不用擔心事務失效的問題坟募。如果你想掃描什么包,或者不想掃描什么包邑狸,完全可以根據表格中的屬性進行定制懈糯,在不需要對bean對象進行復雜的屬性注入的時候,這種開發(fā)方式是簡潔且方便的单雾。(當然需要復雜的屬性注入的時候還是寫配置文件吧赚哗,不一定方便但絕對易讀簡潔)

參考博文:

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市硅堆,隨后出現的幾起案子屿储,更是在濱河造成了極大的恐慌,老刑警劉巖渐逃,帶你破解...
    沈念sama閱讀 221,635評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件够掠,死亡現場離奇詭異,居然都是意外死亡茄菊,警方通過查閱死者的電腦和手機疯潭,發(fā)現死者居然都...
    沈念sama閱讀 94,543評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來买羞,“玉大人袁勺,你說我怎么就攤上這事⌒笃眨” “怎么了期丰?”我有些...
    開封第一講書人閱讀 168,083評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長吃挑。 經常有香客問我钝荡,道長,這世上最難降的妖魔是什么舶衬? 我笑而不...
    開封第一講書人閱讀 59,640評論 1 296
  • 正文 為了忘掉前任埠通,我火速辦了婚禮,結果婚禮上逛犹,老公的妹妹穿的比我還像新娘端辱。我一直安慰自己梁剔,他們只是感情好,可當我...
    茶點故事閱讀 68,640評論 6 397
  • 文/花漫 我一把揭開白布舞蔽。 她就那樣靜靜地躺著荣病,像睡著了一般。 火紅的嫁衣襯著肌膚如雪渗柿。 梳的紋絲不亂的頭發(fā)上个盆,一...
    開封第一講書人閱讀 52,262評論 1 308
  • 那天,我揣著相機與錄音朵栖,去河邊找鬼颊亮。 笑死,一個胖子當著我的面吹牛陨溅,可吹牛的內容都是我干的终惑。 我是一名探鬼主播,決...
    沈念sama閱讀 40,833評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼声登,長吁一口氣:“原來是場噩夢啊……” “哼狠鸳!你這毒婦竟也來了?” 一聲冷哼從身側響起悯嗓,我...
    開封第一講書人閱讀 39,736評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎卸察,沒想到半個月后脯厨,有當地人在樹林里發(fā)現了一具尸體,經...
    沈念sama閱讀 46,280評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡坑质,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,369評論 3 340
  • 正文 我和宋清朗相戀三年合武,在試婚紗的時候發(fā)現自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片涡扼。...
    茶點故事閱讀 40,503評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡稼跳,死狀恐怖,靈堂內的尸體忽然破棺而出吃沪,到底是詐尸還是另有隱情汤善,我是刑警寧澤,帶...
    沈念sama閱讀 36,185評論 5 350
  • 正文 年R本政府宣布票彪,位于F島的核電站红淡,受9級特大地震影響,放射性物質發(fā)生泄漏降铸。R本人自食惡果不足惜在旱,卻給世界環(huán)境...
    茶點故事閱讀 41,870評論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望推掸。 院中可真熱鬧桶蝎,春花似錦驻仅、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,340評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至绍豁,卻和暖如春芯咧,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背竹揍。 一陣腳步聲響...
    開封第一講書人閱讀 33,460評論 1 272
  • 我被黑心中介騙來泰國打工敬飒, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人芬位。 一個月前我還...
    沈念sama閱讀 48,909評論 3 376
  • 正文 我出身青樓无拗,卻偏偏與公主長得像,于是被迫代替她去往敵國和親昧碉。 傳聞我的和親對象是個殘疾皇子英染,可洞房花燭夜當晚...
    茶點故事閱讀 45,512評論 2 359

推薦閱讀更多精彩內容