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

2014-11-24 03:05:58 · 作者: · 浏览: 6
ew ScannedGenericBeanDefinition(metadataReader); //设置Bean定义来源于resource
  • sbd.setResource(resource); //为元数据元素设置配置资源对象
  • sbd.setSource(resource); //检查Bean是否是一个可实例化的对象
  • if (isCandidateComponent(sbd)) { if (debugEnabled) {
  • logger.debug(Identified candidate component class: + resource); }
  • candidates.add(sbd); }
  • else { if (debugEnabled) {
  • logger.debug(Ignored because not a concrete top-level class: + resource); }
  • } }
  • else { if (traceEnabled) {
  • logger.trace(Ignored because not matching any filter: + resource); }
  • } }
  • catch (Throwable ex) { throw new BeanDefinitionStoreException(
  • Failed to read candidate component class: + resource, ex); }
  • } else {
  • if (traceEnabled) { logger.trace(Ignored because not readable: + resource);
  • } }
  • } }
  • catch (IOException ex) { throw new BeanDefinitionStoreException(I/O failure during classpath scanning, ex);
  • } return candidates;
  • } //判断元信息读取器读取的类是否符合容器定义的注解过滤规则
  • protected boolean isCandidateComponent(MetadataReader metadataReader) throws IOException { //如果读取的类的注解在排除注解过滤规则中,返回false
  • for (TypeFilter tf : this.excludeFilters) { if (tf.match(metadataReader, this.metadataReaderFactory)) {
  • return false; }
  • } //如果读取的类的注解在包含的注解的过滤规则中,则返回ture
  • for (TypeFilter tf : this.includeFilters) { if (tf.match(metadataReader, this.metadataReaderFactory)) {
  • return true; }
  • } //如果读取的类的注解既不在排除规则,也不在包含规则中,则返回false
  • return false; }
  • …… }

    5.AnnotationConfigWebApplicationContext载入注解Bean定义:

    AnnotationConfigWebApplicationContext是AnnotationConfigApplicationContext的Web版,它们对于注解Bean的注册和扫描是基本相同的,但是AnnotationConfigWebApplicationContext对注解Bean定义的载入稍有不同,AnnotationConfigWebApplicationContext注入注解Bean定义源码如下:

    [java] view plaincopy
    1. //载入注解Bean定义资源 protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) {
    2. //为容器设置注解Bean定义读取器 AnnotatedBeanDefinitionReader reader = new AnnotatedBeanDefinitionReader(beanFactory);
    3. //为容器设置类路径Bean定义扫描器 ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(beanFactory);
    4. //获取容器的Bean名称生成器 BeanNameGenerator beanNameGenerator = getBeanNameGenerator();
    5. //获取容器的作用域元信息解析器 ScopeMetadataResolver scopeMetadataResolver = getScopeMetadataResolver();
    6. //为注解Bean定义读取器和类路径扫描器设置Bean名称生成器 if (beanNameGenerator != null) {
    7. reader.setBeanNameGenerator(beanNameGenerator); scanner.setBeanNameGenerator(beanNameGenerator);
    8. } //为注解Bean定义读取器和类路径扫描器设置作用域元信息解析器
    9. if (scopeMetadataResolver != null) { reader.setScopeMetadataResolver(scopeMetadataResolver);
    10. scanner.setScopeMetadataResolver(scopeMetadataResolver); }
    11. //获取容器定义的Bean定义资源路径 String[] configLocations = getConfigLocations();
    12. //如果定位的Bean定义资源路径不为空 if (configLocations != null) {
    13. for (String configLocation : configLocations) { try {
    14. //使用当前容器的类加载器加载定位路径的字节码类文件 Class clazz = getClassLoader().loadClass(configLocation);
    15. if (logger.isInfoEnabled()) { logger.info(Successfully resolved class for [ + configLocation + ]);
    16. } reader.register(clazz);
    17. } catch (ClassNotFoundException ex) {
    18. if (logger.isDebugEnabled()) { logger.debug(Could not load class for config location [ + configLocation +
    19. ] - trying package scan. + ex); }
    20. //如果容器类加载器加载定义路径的Bean定义资源失败,则启用 //容器类路径扫描器扫描给定路径包及其子包中的类
    21. int count = scanner.scan(configLocation); if (logger.isInfoEnabled()) {
    22. if (count == 0) { logger.info(No annotated classes found for specified class/package [