spring bean自动扫描分析

Spring为企业级开发提供了轻量而又强大的支持。但是为了使用spring还是需要大量的配置文件对系统中的bean进行配置。虽然提供了基于注解的配置,但其也只能省去依赖部分的配置,而对每个Bean本身的配置仍然需要。为了进一步减少配置,Spring进一步提供了从classpath自动扫描Bean组建并将其对应的BeanDefinination加入到容器中的功能。本文就对spring自动扫描组建的功能进行学习和分析。

提供自动扫描功能的核心类是:ClassPathBeanDefinitionScanner,该类根据提供个基础包名,扫描classpath下与该包名的路径下,找到复合条件的类并注册为Spring的一个Bean。 默认情况下,ClassPathBeanDefinitionScanner将会扫面所有用Spring指定了的注解标识了的类,包括:@Component、@Service、@Repository、@Controller(Spring注解配置的详细内容可以参见http://www.ibm.com/developerworks/cn/opensource/os-cn-spring-iocannt/)。也可以对扫描的机制进行配置,设置一些Filter,只有满足Filter的类才能被注册为Bean。

有两种方式使用Classpath扫描机制:第一种是直接使用AnnotationConfigApplicationContext,该类有一个scan(String basePackages)方法,可以对指定的包进行扫描;第二种是在Bean配置文件中使用如下配置开启classpath扫描功能:



Xml代码
<context:component-scan base-package="com.ronry.springtest.simple" />

<context:component-scan base-package="com.ronry.springtest.simple" />

(注意需要配置context命名空间)。开启扫描功能之后即可按普通的方式从配置文件创建一个ApplicationContext。在ApplicationContext的loadBeanDefinition时遇到component-scan元素时会以ComponentScanBeanDefinitionParser进行解析。

但AnnotationConfigApplicationContext和ComponentScanBeanDefinitionParser,内部依赖的都是ClassPathBeanDefinitionScanner。与其相关的主要类如下:

[img]http://dl.iteye.com/upload/attachment/399464/cdbd97d0-6495-3897-80e3-290ec6372cd9.jpg[/img]


ResourcePatternResolver用来从classpath中加载Resource;MetadataReaderFactory用来根据Resource生成MetadataReader;BeanNameGenerator用来生成扫描到的Bean在容器中的名字;ScopeMetadataResolver则用来处理扫描到的Bean的Scope。其中需要特别注意的是BeanNameGenerator和ScopeMetadataResolver是可配置的,在ComponentScanBeanDefinitionParser中有两个方法:parseBeanNameGenerator(element, scanner)和parseScope(element, scanner)就是用来处理这两个组件的配置的。如果没有配置,则BeanNameGenerator默认是用AnnotationBeanNameGenerator而ScopeMetadataResolver用的是AnnotationScopeMetadataResolver。

而扫描的过程大概为:


用ResourcePatternResolver从配置的classpath中加载Resource;
分别处理扫描到的每个Resource,用MetadataReaderFactory生成对应的MetadataReader;
根据MetadataReader判断Resource是否是符合条件的Component;
如果是,则生成对应的ScannedGenericBeanDefinition;不是则跳过;
对于经过上面4步生成的符合条件的ScannedGenericBeanDefinition,先用ScopeMetadataResolver生成ScopeMetadata,将得到的Scope设置到对应的ScannedGenericBeanDefinition中;
再用BeanNameGenerator生成Bean的名称;
最后,设置ScannedGenericBeanDefinition的其他属性,例如:dependsOn、lazy、autowired等;根据ScannedGenericBeanDefinition是AbstractBeanDefinition还是AnnotatedBeanDefinition,设置的方法稍有不同。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值