Spring框架学习[注解扫描和读取Bean](五)

2014-11-24 03:05:58 · 作者: · 浏览: 5
e Service { String value() default ;
  • }

    c.Controller注解:

    [java
    1. @Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME)
    2. @Documented @Component
    3. public @interface Controller { String value() default ;
    4. }

      d.Repository注解:

      [java]
      1. @Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME)
      2. @Documented @Component
      3. public @interface Repository { String value() default ;
      4. }

        通过分析Spring这4个常用的注解源码,我们看到:@Service、@Controller和@Repository注解都添加了一个@Component注解,因此他们都属于@Component

        注解。

        (2).ClassPathBeanDefinitionScanner扫描给定的包及其子包:

        AnnotationConfigApplicationContext通过调用类路径Bean定义扫描器ClassPathBeanDefinitionScanner扫描给定包及其子包下的所有类,主要源码如下:

        [java]
        1. public class ClassPathBeanDefinitionScanner extends ClassPathScanningCandidateComponentProvider { //创建一个类路径Bean定义扫描器
        2. public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry) { this(registry, true);
        3. } //为容器创建一个类路径Bean定义扫描器,并指定是否使用默认的扫描过滤规则。
        4. //即Spring默认扫描配置:@Component、@Repository、@Service、@Controller //注解的Bean,同时也支持JavaEE6的@ManagedBean和JSR-330的@Named注解
        5. public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters) { //调用父类ClassPathScanningCandidateComponentProvider构造方法设置过滤规则
        6. super(useDefaultFilters); Assert.notNull(registry, BeanDefinitionRegistry must not be null);
        7. //为容器设置加载Bean定义的注册器 this.registry = registry;
        8. //如果注册器是资源加载器,则为容器设置资源加载器 if (this.registry instanceof ResourceLoader) {
        9. setResourceLoader((ResourceLoader) this.registry); }
        10. } //调用类路径Bean定义扫描器入口方法
        11. public int scan(String... basePackages) { //获取容器中已经注册的Bean个数
        12. int beanCountAtScanStart = this.registry.getBeanDefinitionCount(); //启动扫描器扫描给定包
        13. doScan(basePackages); //注册注解配置(Annotation config)处理器
        14. if (this.includeAnnotationConfig) { AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
        15. } //返回注册的Bean个数
        16. return this.registry.getBeanDefinitionCount() - beanCountAtScanStart; }
        17. //类路径Bean定义扫描器扫描给定包及其子包 protected Set doScan(String... basePackages) {
        18. //创建一个集合,存放扫描到Bean定义的封装类 Set beanDefinitions = new LinkedHashSet ();
        19. //遍历扫描所有给定的包 for (String basePackage : basePackages) {
        20. //调用父类ClassPathScanningCandidateComponentProvider的方法 //扫描给定类路径,获取符合条件的Bean定义
        21. Set candidates = findCandidateComponents(basePackage); //遍历扫描到的Bean
        22. for (BeanDefinition candidate : candidates) { //获取Bean定义类中@Scope注解的值,即获取Bean的作用域
        23. ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate); //为Bean设置注解配置的作用域
        24. candidate.setScope(scopeMetadata.getScopeName()); //为Bean生成名称
        25. String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry); //如果扫描到的Bean不是Spring的注解Bean,则为Bean设置默认值,
        26. //设置Bean的自动依赖注入装配属性等 if (candidate instanceof AbstractBeanDefinition) {
        27. postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName); }
        28. //如果扫描到的Bean是Spring的注解Bean,则处理其通用的Spring注解 if (candidate instanceof AnnotatedBeanDefinition) {
        29. //处理注解Bean中通用的注解,在分析注解Bean定义类读取器时已经分析过 AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate); }
        30. //根据Bean名称检查指定的Bean是否需要在容器中注册,或者在容器中冲突 if (checkCandidate(beanName, candidate)) {
        31. BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName); //根据注解中配置的作用域,为Bean应用相应的代理模式
        32. def