浅谈context:component-scan注解

前言:因为好久没有碰ssm组合式开发的东西了,加上学的时候稍微咸鱼了一点,好多东西其实都忘了,打算抽时间一点一点的把这些内容捡起来。

这次我们来聊一聊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>

我们先来聊一聊这个配置的作用吧。

通常情况下,我们创建一个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>

然后要用这个对象的时候,我需要先通过配置文件创建一个配置文件对象(例如通过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。这种情况下可以发现扫描的力度还是非常大的

但是,在SSM组合式开发当中,Controller控制层应当是由SpringMVC单独管理的,不应该交给spring管理,原因是因为:SSM组合式开发当中,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属性一起协作来定义组件扫描策略:

过滤器类型 描述
annotation 过滤器扫描使用注解所标注的那些类,通过expression属性指定要扫描的注解
assignable 过滤器扫描派生于expression属性所指定类型的那些类
aspectj 过滤器扫描与expression属性所指定的AspectJ表达式所匹配的那些类
custom 使用自定义的org.springframework.core.type.TypeFliter实现类,该类由expression属性指定
regex 过滤器扫描类的名称与expression属性所指定正则表示式所匹配的那些类
  • 再次强调一下:若使用include-filter去定制扫描内容,要在use-default-filters="false"的情况下,不然会“失效”,被默认的过滤机制所覆盖

这样我们就可以愉快的开始使用注解开发啦,也不用担心事务失效的问题。如果你想扫描什么包,或者不想扫描什么包,完全可以根据表格中的属性进行定制,在不需要对bean对象进行复杂的属性注入的时候,这种开发方式是简洁且方便的。(当然需要复杂的属性注入的时候还是写配置文件吧,不一定方便但绝对易读简洁)

参考博文:

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,454评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,553评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,921评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,648评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,770评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,950评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,090评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,817评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,275评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,592评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,724评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,409评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,052评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,815评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,043评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,503评论 2 361
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,627评论 2 350

推荐阅读更多精彩内容