Spring源码解析之注解的扫描
来源:互联网 发布:如何下载喀秋莎软件 编辑:程序博客网 时间:2024/05/17 02:04
阅读须知
研究了半天markdown也没发现怎么为代码块中的重点代码做特殊标记,所以这里使用//单行注释做代码的简单注释,而/**/多行注释的代码注释的同时会做深入分析,同时为了避免篇幅过长,删掉了Spring原来的注释和空行,建议配合Spring源代码进行阅读,本文对应的Spring源码的版本为4.3.8。
正文
现在我们使用Spring的时候,基本上很少使用标签配置的方式来声明bean了,都是使用注解的方式来声明bean,下面我们就来分析一下这部分的源码实现。
在使用注解之前,我们要首先配置一下<context:component-scan/>
标签,我们就以这个标签的解析作为入口来分析,这里需要读者了解Spring自定义标签解析的流程,不了解的可以看一下笔者之前关于Spring自定义标签解析的的文章,这里给出传送门,锁定ContextNamespaceHandler:
public void init() { registerBeanDefinitionParser("property-placeholder", new PropertyPlaceholderBeanDefinitionParser()); registerBeanDefinitionParser("property-override", new PropertyOverrideBeanDefinitionParser()); registerBeanDefinitionParser("annotation-config", new AnnotationConfigBeanDefinitionParser()); /*注册<context:component-scan/>标签解析器*/ registerBeanDefinitionParser("component-scan", new ComponentScanBeanDefinitionParser()); registerBeanDefinitionParser("load-time-weaver", new LoadTimeWeaverBeanDefinitionParser()); registerBeanDefinitionParser("spring-configured", new SpringConfiguredBeanDefinitionParser()); registerBeanDefinitionParser("mbean-export", new MBeanExportBeanDefinitionParser()); registerBeanDefinitionParser("mbean-server", new MBeanServerBeanDefinitionParser());}
分析ComponentScanBeanDefinitionParser的parse方法:
public BeanDefinition parse(Element element, ParserContext parserContext) { String basePackage = element.getAttribute(BASE_PACKAGE_ATTRIBUTE); //获取base-package属性 basePackage = parserContext.getReaderContext().getEnvironment().resolvePlaceholders(basePackage); //处理包路径中的特殊符号,如${} //分割 String[] basePackages = StringUtils.tokenizeToStringArray(basePackage, ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS); /*配置Scanner*/ ClassPathBeanDefinitionScanner scanner = configureScanner(parserContext, element); /*扫描*/ Set<BeanDefinitionHolder> beanDefinitions = scanner.doScan(basePackages); /*注册一些注解相关的PostProcessor,将BeanDefinition注册完成的事件通知给相关监听器*/ registerComponents(parserContext.getReaderContext(), beanDefinitions, element); return null;}
ComponentScanBeanDefinitionParser:
protected ClassPathBeanDefinitionScanner configureScanner(ParserContext parserContext, Element element) { boolean useDefaultFilters = true; //use-default-filters属性,默认为true if (element.hasAttribute(USE_DEFAULT_FILTERS_ATTRIBUTE)) { useDefaultFilters = Boolean.valueOf(element.getAttribute(USE_DEFAULT_FILTERS_ATTRIBUTE)); } /*创建Scanner*/ ClassPathBeanDefinitionScanner scanner = createScanner(parserContext.getReaderContext(), useDefaultFilters); scanner.setBeanDefinitionDefaults(parserContext.getDelegate().getBeanDefinitionDefaults()); scanner.setAutowireCandidatePatterns(parserContext.getDelegate().getAutowireCandidatePatterns()); //resource-pattern属性 if (element.hasAttribute(RESOURCE_PATTERN_ATTRIBUTE)) { scanner.setResourcePattern(element.getAttribute(RESOURCE_PATTERN_ATTRIBUTE)); } try { /*解析name-generator属性*/ parseBeanNameGenerator(element, scanner); } catch (Exception ex) { parserContext.getReaderContext().error(ex.getMessage(), parserContext.extractSource(element), ex.getCause()); } try { /*解析scope-resolver属性和scoped-proxy属性*/ parseScope(element, scanner); } catch (Exception ex) { parserContext.getReaderContext().error(ex.getMessage(), parserContext.extractSource(element), ex.getCause()); } /*解析include-filter子标签和exclude-filter子标签*/ parseTypeFilters(element, scanner, parserContext); return scanner;}
ComponentScanBeanDefinitionParser:
protected ClassPathBeanDefinitionScanner createScanner(XmlReaderContext readerContext, boolean useDefaultFilters) { /*创建ClassPathBeanDefinitionScanner*/ return new ClassPathBeanDefinitionScanner(readerContext.getRegistry(), useDefaultFilters, readerContext.getEnvironment(), readerContext.getResourceLoader());}
ClassPathBeanDefinitionScanner:
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters, Environment environment, ResourceLoader resourceLoader) { Assert.notNull(registry, "BeanDefinitionRegistry must not be null"); this.registry = registry; if (useDefaultFilters) { /*注册默认的过滤器*/ registerDefaultFilters(); } setEnvironment(environment); setResourceLoader(resourceLoader);}
ClassPathScanningCandidateComponentProvider:
protected void registerDefaultFilters() { //添加默认的Component注解的过滤器 this.includeFilters.add(new AnnotationTypeFilter(Component.class)); ClassLoader cl = ClassPathScanningCandidateComponentProvider.class.getClassLoader(); try { this.includeFilters.add(new AnnotationTypeFilter( ((Class<? extends Annotation>) ClassUtils.forName("javax.annotation.ManagedBean", cl)), false)); logger.debug("JSR-250 'javax.annotation.ManagedBean' found and supported for component scanning"); } catch (ClassNotFoundException ex) { } try { this.includeFilters.add(new AnnotationTypeFilter( ((Class<? extends Annotation>) ClassUtils.forName("javax.inject.Named", cl)), false)); logger.debug("JSR-330 'javax.inject.Named' annotation found and supported for component scanning"); } catch (ClassNotFoundException ex) { }}
这里我们看到了默认的@Component注解过滤器的添加,而我们常用的@Service、@Controller等注解都使用了@Component注解,所以同样会匹配这个过滤器。
@Target({ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)@Documented@Component //@Service注解也使用了@Componentpublic @interface Service { String value() default "";}
ClassPathBeanDefinitionScanner:
protected void parseBeanNameGenerator(Element element, ClassPathBeanDefinitionScanner scanner) { //如果配置了name-generator属性则设置为自定义的BeanNameGenerator if (element.hasAttribute(NAME_GENERATOR_ATTRIBUTE)) { BeanNameGenerator beanNameGenerator = (BeanNameGenerator) instantiateUserDefinedStrategy( element.getAttribute(NAME_GENERATOR_ATTRIBUTE), BeanNameGenerator.class, scanner.getResourceLoader().getClassLoader()); scanner.setBeanNameGenerator(beanNameGenerator); }}
ClassPathBeanDefinitionScanner:
protected void parseScope(Element element, ClassPathBeanDefinitionScanner scanner) { //scope-resolver属性 if (element.hasAttribute(SCOPE_RESOLVER_ATTRIBUTE)) { //不能与scoped-proxy同时出现 if (element.hasAttribute(SCOPED_PROXY_ATTRIBUTE)) { throw new IllegalArgumentException( "Cannot define both 'scope-resolver' and 'scoped-proxy' on <component-scan> tag"); } ScopeMetadataResolver scopeMetadataResolver = (ScopeMetadataResolver) instantiateUserDefinedStrategy( element.getAttribute(SCOPE_RESOLVER_ATTRIBUTE), ScopeMetadataResolver.class, scanner.getResourceLoader().getClassLoader()); scanner.setScopeMetadataResolver(scopeMetadataResolver); } //scope-proxy属性 if (element.hasAttribute(SCOPED_PROXY_ATTRIBUTE)) { String mode = element.getAttribute(SCOPED_PROXY_ATTRIBUTE); //targetClass、interfaces、no三个属性值的设置 if ("targetClass".equals(mode)) { scanner.setScopedProxyMode(ScopedProxyMode.TARGET_CLASS); } else if ("interfaces".equals(mode)) { scanner.setScopedProxyMode(ScopedProxyMode.INTERFACES); } else if ("no".equals(mode)) { scanner.setScopedProxyMode(ScopedProxyMode.NO); } else { throw new IllegalArgumentException("scoped-proxy only supports 'no', 'interfaces' and 'targetClass'"); } }}
ClassPathBeanDefinitionScanner:
protected void parseTypeFilters(Element element, ClassPathBeanDefinitionScanner scanner, ParserContext parserContext) { ClassLoader classLoader = scanner.getResourceLoader().getClassLoader(); NodeList nodeList = element.getChildNodes(); for (int i = 0; i < nodeList.getLength(); i++) { Node node = nodeList.item(i); if (node.getNodeType() == Node.ELEMENT_NODE) { String localName = parserContext.getDelegate().getLocalName(node); try { //子标签include-filter if (INCLUDE_FILTER_ELEMENT.equals(localName)) { TypeFilter typeFilter = createTypeFilter((Element) node, classLoader, parserContext); scanner.addIncludeFilter(typeFilter); } //子标签exclude-filter else if (EXCLUDE_FILTER_ELEMENT.equals(localName)) { TypeFilter typeFilter = createTypeFilter((Element) node, classLoader, parserContext); scanner.addExcludeFilter(typeFilter); } } catch (Exception ex) { parserContext.getReaderContext().error( ex.getMessage(), parserContext.extractSource(element), ex.getCause()); } } }}
到这配置解析的准备工作就完成了,下面就是扫描的流程:
ClassPathBeanDefinitionScanner:
protected Set<BeanDefinitionHolder> doScan(String... basePackages) { Assert.notEmpty(basePackages, "At least one base package must be specified"); Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<BeanDefinitionHolder>(); for (String basePackage : basePackages) { /*获取候选的BeanDefinition*/ Set<BeanDefinition> candidates = findCandidateComponents(basePackage); for (BeanDefinition candidate : candidates) { /*处理@Scope注解元数据*/ ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate); candidate.setScope(scopeMetadata.getScopeName()); //生成beanName String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry); if (candidate instanceof AbstractBeanDefinition) { postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName); } if (candidate instanceof AnnotatedBeanDefinition) { //其他注解的处理 AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate); } //检查BeanDefinition if (checkCandidate(beanName, candidate)) { BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName); definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry); beanDefinitions.add(definitionHolder); //注册BeanDefinition registerBeanDefinition(definitionHolder, this.registry); } } } return beanDefinitions;}
ClassPathBeanDefinitionScanner:
public Set<BeanDefinition> findCandidateComponents(String basePackage) { Set<BeanDefinition> candidates = new LinkedHashSet<BeanDefinition>(); try { //处理包路径中的特殊字符,并且拼接classpath*:前缀和/**/*.class后缀 String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX + resolveBasePackage(basePackage) + '/' + this.resourcePattern; //获取包路径加的文件并转换成FileSystemResource资源 Resource[] resources = this.resourcePatternResolver.getResources(packageSearchPath); boolean traceEnabled = logger.isTraceEnabled(); boolean debugEnabled = logger.isDebugEnabled(); for (Resource resource : resources) { if (traceEnabled) { logger.trace("Scanning " + resource); } if (resource.isReadable()) { try { MetadataReader metadataReader = this.metadataReaderFactory.getMetadataReader(resource); /*用之前添加的filter过滤资源*/ if (isCandidateComponent(metadataReader)) { ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader); sbd.setResource(resource); sbd.setSource(resource); /*过滤class*/ 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;}
根据包路径获取资源就是递归获取包路径下的所有File,并包装成FileSystemResource返回,具体逻辑就不多赘述了,有兴趣的读者可以自行了解。
ClassPathBeanDefinitionScanner:
protected boolean isCandidateComponent(MetadataReader metadataReader) throws IOException { //excludeFilter过滤 for (TypeFilter tf : this.excludeFilters) { if (tf.match(metadataReader, this.metadataReaderFactory)) { return false; } } //includeFilter过滤 for (TypeFilter tf : this.includeFilters) { if (tf.match(metadataReader, this.metadataReaderFactory)) { //@Conditional注解解析和判断 return isConditionMatch(metadataReader); } } return false;}
默认情况excludeFilters是空的,includeFilters包含之前添加的@Component注解的AnnotationTypeFilter,所以这里会过滤掉不包含@Component注解的类。
ClassPathBeanDefinitionScanner:
protected boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) { AnnotationMetadata metadata = beanDefinition.getMetadata(); //独立的非接口非抽象类的普通类,或者@Lookup注解的抽象类 return (metadata.isIndependent() && (metadata.isConcrete() || (metadata.isAbstract() && metadata.hasAnnotatedMethods(Lookup.class.getName()))));}
下面就是最后一步,注册BeanDefinition后的事件通知,并且注册一些注解相关的PostProcessor:
ComponentScanBeanDefinitionParser:
protected void registerComponents( XmlReaderContext readerContext, Set<BeanDefinitionHolder> beanDefinitions, Element element) { Object source = readerContext.extractSource(element); CompositeComponentDefinition compositeDef = new CompositeComponentDefinition(element.getTagName(), source); for (BeanDefinitionHolder beanDefHolder : beanDefinitions) { compositeDef.addNestedComponent(new BeanComponentDefinition(beanDefHolder)); } boolean annotationConfig = true; //获取annotation-config属性,默认为true if (element.hasAttribute(ANNOTATION_CONFIG_ATTRIBUTE)) { annotationConfig = Boolean.valueOf(element.getAttribute(ANNOTATION_CONFIG_ATTRIBUTE)); } if (annotationConfig) { /*注册一些注解相关的PostProcessor*/ Set<BeanDefinitionHolder> processorDefinitions = AnnotationConfigUtils.registerAnnotationConfigProcessors(readerContext.getRegistry(), source); for (BeanDefinitionHolder processorDefinition : processorDefinitions) { compositeDef.addNestedComponent(new BeanComponentDefinition(processorDefinition)); } } //BeanDefinition注册完成事件通知 readerContext.fireComponentRegistered(compositeDef);}
AnnotationConfigUtils:
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors( BeanDefinitionRegistry registry, Object source) { DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry); if (beanFactory != null) { if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) { beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE); } if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) { beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver()); } } Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<BeanDefinitionHolder>(4); if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) { /*对@Configuration、@Bean、@Import、@Component、@ComponentScan、@ImportResource等注解的支持*/ RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class); def.setSource(source); beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)); } if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) { //对@Autowire和@Value注解的支持 RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class); def.setSource(source); beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)); } if (!registry.containsBeanDefinition(REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) { //对@Required注解的支持 RootBeanDefinition def = new RootBeanDefinition(RequiredAnnotationBeanPostProcessor.class); def.setSource(source); beanDefs.add(registerPostProcessor(registry, def, REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME)); } //JSR-250规范 if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) { //对@Resource、@PostConstruct、@PreDestroy注解的支持 RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class); def.setSource(source); beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)); } //对JPA的支持 if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) { RootBeanDefinition def = new RootBeanDefinition(); try { def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, AnnotationConfigUtils.class.getClassLoader())); } catch (ClassNotFoundException ex) { throw new IllegalStateException( "Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex); } def.setSource(source); beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)); } if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) { //对@EventListener事件监听器注解的支持 RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class); def.setSource(source); beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME)); } if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) { //注册事件监听器工厂EventListenerFactory,在上面注册的EventListenerMethodProcessor在根据@EventListener注解信息创建事件监听器时会用到 RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class); def.setSource(source); beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME)); } return beanDefs;}
这里注册了一些PostProcessor,用于对各种注解的支持,当然这里只是注册了处理器,并不会真正的解析注解,在上篇文章中我们介绍了BeanFactoryPostProcessor和BeanPostProcessor的作用,AutowiredAnnotationBeanPostProcessor、RequiredAnnotationBeanPostProcessor、CommonAnnotationBeanPostProcessor都实现了BeanPostProcessor,所以会在bean创建的期间被调用,而ConfigurationClassPostProcessor实现了BeanFactoryPostProcessor,所以它会在bean创建之前被调用,我们来分析一下ConfigurationClassPostProcessor:
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) { int registryId = System.identityHashCode(registry); if (this.registriesPostProcessed.contains(registryId)) { throw new IllegalStateException( "postProcessBeanDefinitionRegistry already called on this post-processor against " + registry); } if (this.factoriesPostProcessed.contains(registryId)) { throw new IllegalStateException( "postProcessBeanFactory already called on this post-processor against " + registry); } this.registriesPostProcessed.add(registryId); /*解析@Configuration注解,注册BeanDefinition*/ processConfigBeanDefinitions(registry);}
ConfigurationClassPostProcessor:
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) { List<BeanDefinitionHolder> configCandidates = new ArrayList<BeanDefinitionHolder>(); String[] candidateNames = registry.getBeanDefinitionNames(); for (String beanName : candidateNames) { BeanDefinition beanDef = registry.getBeanDefinition(beanName); //如果已经处理过,无需再次处理 if (ConfigurationClassUtils.isFullConfigurationClass(beanDef) || ConfigurationClassUtils.isLiteConfigurationClass(beanDef)) { if (logger.isDebugEnabled()) { logger.debug("Bean definition has already been processed as a configuration class: " + beanDef); } } /*判断是有含有相关的几个注解*/ else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) { configCandidates.add(new BeanDefinitionHolder(beanDef, beanName)); } } if (configCandidates.isEmpty()) { //没有@Configuration直接返回 return; } //按照注解的@Order进行排序 Collections.sort(configCandidates, new Comparator<BeanDefinitionHolder>() { @Override public int compare(BeanDefinitionHolder bd1, BeanDefinitionHolder bd2) { int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition()); int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition()); return (i1 < i2) ? -1 : (i1 > i2) ? 1 : 0; } }); SingletonBeanRegistry sbr = null; //如果有自定义的beanName生成器,则应用 if (registry instanceof SingletonBeanRegistry) { sbr = (SingletonBeanRegistry) registry; if (!this.localBeanNameGeneratorSet && sbr.containsSingleton(CONFIGURATION_BEAN_NAME_GENERATOR)) { BeanNameGenerator generator = (BeanNameGenerator) sbr.getSingleton(CONFIGURATION_BEAN_NAME_GENERATOR); this.componentScanBeanNameGenerator = generator; this.importBeanNameGenerator = generator; } } //@Configuration注解的解析器 ConfigurationClassParser parser = new ConfigurationClassParser( this.metadataReaderFactory, this.problemReporter, this.environment, this.resourceLoader, this.componentScanBeanNameGenerator, registry); Set<BeanDefinitionHolder> candidates = new LinkedHashSet<BeanDefinitionHolder>(configCandidates); Set<ConfigurationClass> alreadyParsed = new HashSet<ConfigurationClass>(configCandidates.size()); do { parser.parse(candidates); /*解析*/ parser.validate(); //因为CGLIB代理的关系,这里需要校验@Configuration注解的类和@Bean注解的方法都是可以被覆盖的,也就是类不能被final修饰,方法可以重写 Set<ConfigurationClass> configClasses = new LinkedHashSet<ConfigurationClass>(parser.getConfigurationClasses()); configClasses.removeAll(alreadyParsed); //移除已经解析过的 if (this.reader == null) { //创建BeanDefinitionReader this.reader = new ConfigurationClassBeanDefinitionReader( registry, this.sourceExtractor, this.resourceLoader, this.environment, this.importBeanNameGenerator, parser.getImportRegistry()); } /*加载BeanDefinition*/ this.reader.loadBeanDefinitions(configClasses); alreadyParsed.addAll(configClasses); candidates.clear(); //个人理解这个判断的含义是在这期间可能有新的BeanDefinition被注册了,所以要判断新注册的BeanDefinition中是否有需要解析的 if (registry.getBeanDefinitionCount() > candidateNames.length) { String[] newCandidateNames = registry.getBeanDefinitionNames(); //获取新的beanDefinitionNames Set<String> oldCandidateNames = new HashSet<String>(Arrays.asList(candidateNames)); //旧的beanDefinitionNames Set<String> alreadyParsedClasses = new HashSet<String>(); //保存已经解析过的className for (ConfigurationClass configurationClass : alreadyParsed) { alreadyParsedClasses.add(configurationClass.getMetadata().getClassName()); } //遍历新的beanDefinitionNames for (String candidateName : newCandidateNames) { if (!oldCandidateNames.contains(candidateName)) { BeanDefinition bd = registry.getBeanDefinition(candidateName); //如果在旧的中不包含并且class没有被解析过,则判断是否需要解析 if (ConfigurationClassUtils.checkConfigurationClassCandidate(bd, this.metadataReaderFactory) && !alreadyParsedClasses.contains(bd.getBeanClassName())) { candidates.add(new BeanDefinitionHolder(bd, candidateName)); } } } candidateNames = newCandidateNames; } } while (!candidates.isEmpty()); if (sbr != null) { //对ImportAware的支持 if (!sbr.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) { sbr.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry()); } } //清理元数据缓存 if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) { ((CachingMetadataReaderFactory) this.metadataReaderFactory).clearCache(); }}
ConfigurationClassUtils:
public static boolean checkConfigurationClassCandidate(BeanDefinition beanDef, MetadataReaderFactory metadataReaderFactory) { String className = beanDef.getBeanClassName(); if (className == null) { return false; } AnnotationMetadata metadata; //根据不同类型的的BeanDefinition获取对应的metadata元数据 if (beanDef instanceof AnnotatedBeanDefinition && className.equals(((AnnotatedBeanDefinition) beanDef).getMetadata().getClassName())) { metadata = ((AnnotatedBeanDefinition) beanDef).getMetadata(); } else if (beanDef instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) beanDef).hasBeanClass()) { Class<?> beanClass = ((AbstractBeanDefinition) beanDef).getBeanClass(); metadata = new StandardAnnotationMetadata(beanClass, true); } else { try { MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(className); metadata = metadataReader.getAnnotationMetadata(); } catch (IOException ex) { if (logger.isDebugEnabled()) { logger.debug("Could not find class file for introspecting configuration annotations: " + className, ex); } return false; } } /*判断是否有@Configuration注解*/ if (isFullConfigurationCandidate(metadata)) { beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_FULL); } /*判断是否有另外相关的几个注解*/ else if (isLiteConfigurationCandidate(metadata)) { beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_LITE); } else { return false; } //如果有@Order注解,设置order属性用于排序 Map<String, Object> orderAttributes = metadata.getAnnotationAttributes(Order.class.getName()); if (orderAttributes != null) { beanDef.setAttribute(ORDER_ATTRIBUTE, orderAttributes.get(AnnotationUtils.VALUE)); } return true;}
ConfigurationClassUtils:
public static boolean isFullConfigurationCandidate(AnnotationMetadata metadata) { //是否有@Configuration类注解 return metadata.isAnnotated(Configuration.class.getName());}
ConfigurationClassUtils:
public static boolean isLiteConfigurationCandidate(AnnotationMetadata metadata) { if (metadata.isInterface()) { //接口不通过 return false; } /*是否有candidateIndicators中包含的类注解*/ for (String indicator : candidateIndicators) { if (metadata.isAnnotated(indicator)) { return true; } } try { //是否有@Bean方法注解 return metadata.hasAnnotatedMethods(Bean.class.getName()); } catch (Throwable ex) { if (logger.isDebugEnabled()) { logger.debug("Failed to introspect @Bean methods on class [" + metadata.getClassName() + "]: " + ex); } return false; }}
ConfigurationClassUtils:
static { candidateIndicators.add(Component.class.getName()); candidateIndicators.add(ComponentScan.class.getName()); candidateIndicators.add(Import.class.getName()); candidateIndicators.add(ImportResource.class.getName());}
下面就是配置解析的流程:
ConfigurationClassParser:
public void parse(Set<BeanDefinitionHolder> configCandidates) { this.deferredImportSelectors = new LinkedList<DeferredImportSelectorHolder>(); for (BeanDefinitionHolder holder : configCandidates) { BeanDefinition bd = holder.getBeanDefinition(); try { if (bd instanceof AnnotatedBeanDefinition) { /*解析配置*/ parse(((AnnotatedBeanDefinition) bd).getMetadata(), holder.getBeanName()); } else if (bd instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) bd).hasBeanClass()) { /*解析配置*/ parse(((AbstractBeanDefinition) bd).getBeanClass(), holder.getBeanName()); } else { /*解析配置*/ parse(bd.getBeanClassName(), holder.getBeanName()); } } catch (BeanDefinitionStoreException ex) { throw ex; } catch (Throwable ex) { throw new BeanDefinitionStoreException( "Failed to parse configuration class [" + bd.getBeanClassName() + "]", ex); } } /*处理延迟导入*/ processDeferredImportSelectors();}
ConfigurationClassParser:
protected final void parse(String className, String beanName) throws IOException { MetadataReader reader = this.metadataReaderFactory.getMetadataReader(className); /*解析配置*/ processConfigurationClass(new ConfigurationClass(reader, beanName));}protected final void parse(Class<?> clazz, String beanName) throws IOException { /*解析配置*/ processConfigurationClass(new ConfigurationClass(clazz, beanName));}protected final void parse(AnnotationMetadata metadata, String beanName) throws IOException { /*解析配置*/ processConfigurationClass(new ConfigurationClass(metadata, beanName));}
三个重载的parse方法最终都会被包装成ConfigurationClass调用processConfigurationClass方法:
ConfigurationClassParser:
protected void processConfigurationClass(ConfigurationClass configClass) throws IOException { /*判断是否需要跳过*/ if (this.conditionEvaluator.shouldSkip(configClass.getMetadata(), ConfigurationPhase.PARSE_CONFIGURATION)) { return; } ConfigurationClass existingClass = this.configurationClasses.get(configClass); //是否已经配置过 if (existingClass != null) { //是否已经注册 if (configClass.isImported()) { if (existingClass.isImported()) { //已经存在的ConfigurationClass合并新ConfigurationClass的导入者 existingClass.mergeImportedBy(configClass); } //注册过无需再次注册 return; } else { //这里代表有重复的BeanDefinition,将已经存在的去掉重新注册 this.configurationClasses.remove(configClass); for (Iterator<ConfigurationClass> it = this.knownSuperclasses.values().iterator(); it.hasNext();) { if (configClass.equals(it.next())) { it.remove(); } } } } //递归处理当前ConfigurationClass和它的父类 SourceClass sourceClass = asSourceClass(configClass); do { /*处理ConfigurationClass*/ sourceClass = doProcessConfigurationClass(configClass, sourceClass); } while (sourceClass != null); //保存已经处理过的ConfigurationClass this.configurationClasses.put(configClass, configClass);}
ConditionEvaluator:
public boolean shouldSkip(AnnotatedTypeMetadata metadata, ConfigurationPhase phase) { //是否有@Conditional注解,没有则不用判断其中配置的条件,无需跳过 if (metadata == null || !metadata.isAnnotated(Conditional.class.getName())) { return false; } //如果处理阶段(包括解析配置阶段和注册bean阶段)等于null,递归判断是否需要跳过 if (phase == null) { if (metadata instanceof AnnotationMetadata && ConfigurationClassUtils.isConfigurationCandidate((AnnotationMetadata) metadata)) { //这里判断的几个注解与上面是相同的 return shouldSkip(metadata, ConfigurationPhase.PARSE_CONFIGURATION); } return shouldSkip(metadata, ConfigurationPhase.REGISTER_BEAN); } List<Condition> conditions = new ArrayList<Condition>(); //遍历@Conditional的value属性值 for (String[] conditionClasses : getConditionClasses(metadata)) { for (String conditionClass : conditionClasses) { //转换成Condition对象 Condition condition = getCondition(conditionClass, this.context.getClassLoader()); conditions.add(condition); } } AnnotationAwareOrderComparator.sort(conditions); //按照order排序 for (Condition condition : conditions) { ConfigurationPhase requiredPhase = null; if (condition instanceof ConfigurationCondition) { requiredPhase = ((ConfigurationCondition) condition).getConfigurationPhase(); } if (requiredPhase == null || requiredPhase == phase) { //如果Condition条件不匹配,则需要跳过 if (!condition.matches(this.context, metadata)) { return true; } } } return false;}
这里简单介绍一下@Conditional注解,注意不是上文的@Configuration注解,我们可以实现Condition接口来定义个性化的匹配条件,并在@Conditional注解中声明这些Condition,Spring会按照我们定义的条件来确定是否创建注解范围内的bean。
ConfigurationClassParser:
protected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass) throws IOException { //递归处理成员内部类 processMemberClasses(configClass, sourceClass); //提取@PropertySource注解的属性遍历进行处理 for (AnnotationAttributes propertySource : AnnotationConfigUtils.attributesForRepeatable( sourceClass.getMetadata(), PropertySources.class, org.springframework.context.annotation.PropertySource.class)) { if (this.environment instanceof ConfigurableEnvironment) { /*处理属性*/ processPropertySource(propertySource); } else { logger.warn("Ignoring @PropertySource annotation on [" + sourceClass.getMetadata().getClassName() + "]. Reason: Environment must implement ConfigurableEnvironment"); } } //提取@ComponentScan注解的属性遍历进行处理 Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable( sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class); if (!componentScans.isEmpty() && !this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) { //同样的@Conditional注解条件判断 for (AnnotationAttributes componentScan : componentScans) { Set<BeanDefinitionHolder> scannedBeanDefinitions = this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName()); /*解析*/ //如果扫描生成的BeanDefinition有需要进一步处理的,递归再次进行同样的解析处理 for (BeanDefinitionHolder holder : scannedBeanDefinitions) { if (ConfigurationClassUtils.checkConfigurationClassCandidate( holder.getBeanDefinition(), this.metadataReaderFactory)) { parse(holder.getBeanDefinition().getBeanClassName(), holder.getBeanName()); } } } } /*提取@Import注解的属性遍历进行处理*/ processImports(configClass, sourceClass, getImports(sourceClass), true); //提取@ImportResource注解的属性遍历进行处理 if (sourceClass.getMetadata().isAnnotated(ImportResource.class.getName())) { AnnotationAttributes importResource = AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class); String[] resources = importResource.getStringArray("locations"); //locations属性 Class<? extends BeanDefinitionReader> readerClass = importResource.getClass("reader"); //reader属性 for (String resource : resources) { //处理路径中的特殊符号 String resolvedResource = this.environment.resolveRequiredPlaceholders(resource); configClass.addImportedResource(resolvedResource, readerClass); } } /*提取@Bean注解的方法的元数据*/ Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass); for (MethodMetadata methodMetadata : beanMethods) { configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass)); } //处理实现的所有接口中@Bean注解的方法,去上面的处理方法一样,但不是抽象方法,因为java8中接口有默认方法和其他具体方法,这里只会处理这些方法的@Bean注解 processInterfaces(configClass, sourceClass); //处理父类 if (sourceClass.getMetadata().hasSuperClass()) { String superclass = sourceClass.getMetadata().getSuperClassName(); //java包的父类和已经处理过的父类不处理 if (!superclass.startsWith("java") && !this.knownSuperclasses.containsKey(superclass)) { //标记父类已经处理过 this.knownSuperclasses.put(superclass, configClass); //返回父类的SourceClass再次进行递归处理 return sourceClass.getSuperClass(); } } return null;}
ConfigurationClassParser:
private void processPropertySource(AnnotationAttributes propertySource) throws IOException { String name = propertySource.getString("name"); //name属性 if (!StringUtils.hasLength(name)) { name = null; } String encoding = propertySource.getString("encoding"); //encoding属性 if (!StringUtils.hasLength(encoding)) { encoding = null; } String[] locations = propertySource.getStringArray("value"); //value属性 Assert.isTrue(locations.length > 0, "At least one @PropertySource(value) location is required"); boolean ignoreResourceNotFound = propertySource.getBoolean("ignoreResourceNotFound"); //ignoreResourceNotFound属性 Class<? extends PropertySourceFactory> factoryClass = propertySource.getClass("factory"); //factory属性 PropertySourceFactory factory = (factoryClass == PropertySourceFactory.class ? DEFAULT_PROPERTY_SOURCE_FACTORY : BeanUtils.instantiateClass(factoryClass)); for (String location : locations) { try { //处理路径中的特殊字符 String resolvedLocation = this.environment.resolveRequiredPlaceholders(location); //根据路径获取资源 Resource resource = this.resourceLoader.getResource(resolvedLocation); //添加属性到Environment环境对象中的propertySources中, addPropertySource(factory.createPropertySource(name, new EncodedResource(resource, encoding))); } catch (IllegalArgumentException ex) { if (ignoreResourceNotFound) { if (logger.isInfoEnabled()) { logger.info("Properties location [" + location + "] not resolvable: " + ex.getMessage()); } } else { throw ex; } } catch (IOException ex) { if (ignoreResourceNotFound && (ex instanceof FileNotFoundException || ex instanceof UnknownHostException)) { if (logger.isInfoEnabled()) { logger.info("Properties location [" + location + "] not resolvable: " + ex.getMessage()); } } else { throw ex; } } }}
ComponentScanAnnotationParser:
public Set<BeanDefinitionHolder> parse(AnnotationAttributes componentScan, final String declaringClass) { Assert.state(this.environment != null, "Environment must not be null"); Assert.state(this.resourceLoader != null, "ResourceLoader must not be null"); //创建Scanner ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(this.registry, componentScan.getBoolean("useDefaultFilters"), this.environment, this.resourceLoader); Class<? extends BeanNameGenerator> generatorClass = componentScan.getClass("nameGenerator"); boolean useInheritedGenerator = (BeanNameGenerator.class == generatorClass); //nameGenerator属性 scanner.setBeanNameGenerator(useInheritedGenerator ? this.beanNameGenerator : BeanUtils.instantiateClass(generatorClass)); ScopedProxyMode scopedProxyMode = componentScan.getEnum("scopedProxy"); //scopedProxy属性 if (scopedProxyMode != ScopedProxyMode.DEFAULT) { scanner.setScopedProxyMode(scopedProxyMode); } else { Class<? extends ScopeMetadataResolver> resolverClass = componentScan.getClass("scopeResolver"); //scopeResolver属性 scanner.setScopeMetadataResolver(BeanUtils.instantiateClass(resolverClass)); } scanner.setResourcePattern(componentScan.getString("resourcePattern")); //resourcePattern属性 //includeFilters属性 for (AnnotationAttributes filter : componentScan.getAnnotationArray("includeFilters")) { for (TypeFilter typeFilter : typeFiltersFor(filter)) { scanner.addIncludeFilter(typeFilter); } } //excludeFilters属性 for (AnnotationAttributes filter : componentScan.getAnnotationArray("excludeFilters")) { for (TypeFilter typeFilter : typeFiltersFor(filter)) { scanner.addExcludeFilter(typeFilter); } } //lazyInit属性 boolean lazyInit = componentScan.getBoolean("lazyInit"); if (lazyInit) { scanner.getBeanDefinitionDefaults().setLazyInit(true); } Set<String> basePackages = new LinkedHashSet<String>(); String[] basePackagesArray = componentScan.getStringArray("basePackages"); //basePackages属性 for (String pkg : basePackagesArray) { String[] tokenized = StringUtils.tokenizeToStringArray(this.environment.resolvePlaceholders(pkg), ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS); basePackages.addAll(Arrays.asList(tokenized)); } for (Class<?> clazz : componentScan.getClassArray("basePackageClasses")) { basePackages.add(ClassUtils.getPackageName(clazz)); } if (basePackages.isEmpty()) { basePackages.add(ClassUtils.getPackageName(declaringClass)); } scanner.addExcludeFilter(new AbstractTypeHierarchyTraversingFilter(false, false) { @Override protected boolean matchClassName(String className) { return declaringClass.equals(className); } }); //扫描 return scanner.doScan(StringUtils.toStringArray(basePackages));}
这里看起来是不是很熟悉,没错啦,文章开始解析<context:component-scan/>
标签时也是同样的流程,只不过这里是解析注解方式的@ComponentScan。
ConfigurationClassParser:
private void processImports(ConfigurationClass configClass, SourceClass currentSourceClass, Collection<SourceClass> importCandidates, boolean checkForCircularImports) throws IOException { if (importCandidates.isEmpty()) { return; } //栈中链式导入的检查,检查正在导入的class是否有冲突 if (checkForCircularImports && isChainedImportOnStack(configClass)) { this.problemReporter.error(new CircularImportProblem(configClass, this.importStack)); } else { this.importStack.push(configClass); //入栈标识正在解析中 try { for (SourceClass candidate : importCandidates) { //我们可以实现ImportSelector来决定导入哪些配置 if (candidate.isAssignable(ImportSelector.class)) { Class<?> candidateClass = candidate.loadClass(); ImportSelector selector = BeanUtils.instantiateClass(candidateClass, ImportSelector.class); ParserStrategyUtils.invokeAwareMethods( selector, this.environment, this.resourceLoader, this.registry); //执行selector实现的Aware的相关set方法 if (this.deferredImportSelectors != null && selector instanceof DeferredImportSelector) { //如果是延迟导入的selector添加到延迟导入的集合中稍后处理 this.deferredImportSelectors.add( new DeferredImportSelectorHolder(configClass, (DeferredImportSelector) selector)); } else { //提取 String[] importClassNames = selector.selectImports(currentSourceClass.getMetadata()); Collection<SourceClass> importSourceClasses = asSourceClasses(importClassNames); //递归解析 processImports(configClass, currentSourceClass, importSourceClasses, false); } } //我们可以实现ImportBeanDefinitionRegistrar来注册额外的BeanDefinition else if (candidate.isAssignable(ImportBeanDefinitionRegistrar.class)) { Class<?> candidateClass = candidate.loadClass(); ImportBeanDefinitionRegistrar registrar = BeanUtils.instantiateClass(candidateClass, ImportBeanDefinitionRegistrar.class); ParserStrategyUtils.invokeAwareMethods( registrar, this.environment, this.resourceLoader, this.registry); configClass.addImportBeanDefinitionRegistrar(registrar, currentSourceClass.getMetadata()); } else { //如果两者都不是就按照@Configuration注解类的解析方式再次解析一遍 this.importStack.registerImport( currentSourceClass.getMetadata(), candidate.getMetadata().getClassName()); processConfigurationClass(candidate.asConfigClass(configClass)); } } } catch (BeanDefinitionStoreException ex) { throw ex; } catch (Throwable ex) { throw new BeanDefinitionStoreException( "Failed to process import candidates for configuration class [" + configClass.getMetadata().getClassName() + "]", ex); } finally { this.importStack.pop(); //出栈表示已经解析完 } }}
下面是延迟导入的处理:
ConfigurationClassParser:
private void processDeferredImportSelectors() { List<DeferredImportSelectorHolder> deferredImports = this.deferredImportSelectors; this.deferredImportSelectors = null; Collections.sort(deferredImports, DEFERRED_IMPORT_COMPARATOR); //排序 for (DeferredImportSelectorHolder deferredImport : deferredImports) { ConfigurationClass configClass = deferredImport.getConfigurationClass(); try { //同样的提取 String[] imports = deferredImport.getImportSelector().selectImports(configClass.getMetadata()); //同样的处理 processImports(configClass, asSourceClass(configClass), asSourceClasses(imports), false); } catch (BeanDefinitionStoreException ex) { throw ex; } catch (Throwable ex) { throw new BeanDefinitionStoreException( "Failed to process import candidates for configuration class [" + configClass.getMetadata().getClassName() + "]", ex); } }}
最后就是注册BeanDefinition了:
ConfigurationClassBeanDefinitionReader:
public void loadBeanDefinitions(Set<ConfigurationClass> configurationModel) { TrackedConditionEvaluator trackedConditionEvaluator = new TrackedConditionEvaluator(); for (ConfigurationClass configClass : configurationModel) { /*加载BeanDefinition*/ loadBeanDefinitionsForConfigurationClass(configClass, trackedConditionEvaluator); }}
ConfigurationClassBeanDefinitionReader:
private void loadBeanDefinitionsForConfigurationClass(ConfigurationClass configClass, TrackedConditionEvaluator trackedConditionEvaluator) { //判断是否需要跳过,与之前解析@Configuration判断是否跳过的逻辑是相同的 if (trackedConditionEvaluator.shouldSkip(configClass)) { //如果需要跳过则将相关已经注册的资源移除掉 String beanName = configClass.getBeanName(); if (StringUtils.hasLength(beanName) && this.registry.containsBeanDefinition(beanName)) { this.registry.removeBeanDefinition(beanName); } this.importRegistry.removeImportingClass(configClass.getMetadata().getClassName()); return; } if (configClass.isImported()) { /*注册@Configuration注解的当前类为一个BeanDefinition*/ registerBeanDefinitionForImportedConfigurationClass(configClass); } for (BeanMethod beanMethod : configClass.getBeanMethods()) { /*加载@Bean注解的方法需要生成的BeanDefinition*/ loadBeanDefinitionsForBeanMethod(beanMethod); } /*加载@ImportResource注解配置的资源需要生成的BeanDefinition*/ loadBeanDefinitionsFromImportedResources(configClass.getImportedResources()); //调用自定义的ImportBeanDefinitionRegistrar的registerBeanDefinitions方法注册BeanDefinition loadBeanDefinitionsFromRegistrars(configClass.getImportBeanDefinitionRegistrars());}
ConfigurationClassBeanDefinitionReader:
private void registerBeanDefinitionForImportedConfigurationClass(ConfigurationClass configClass) { AnnotationMetadata metadata = configClass.getMetadata(); AnnotatedGenericBeanDefinition configBeanDef = new AnnotatedGenericBeanDefinition(metadata); //scope属性解析 ScopeMetadata scopeMetadata = scopeMetadataResolver.resolveScopeMetadata(configBeanDef); configBeanDef.setScope(scopeMetadata.getScopeName()); //生成beanName String configBeanName = this.importBeanNameGenerator.generateBeanName(configBeanDef, this.registry); /*通用注解解析*/ AnnotationConfigUtils.processCommonDefinitionAnnotations(configBeanDef, metadata); BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(configBeanDef, configBeanName); definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry); //应用代理模式 this.registry.registerBeanDefinition(definitionHolder.getBeanName(), definitionHolder.getBeanDefinition()); //注册BeanDefinition configClass.setBeanName(configBeanName); if (logger.isDebugEnabled()) { logger.debug("Registered bean definition for imported class '" + configBeanName + "'"); }}
大部分过程我们之前都分析过。
AnnotationConfigUtils:
static void processCommonDefinitionAnnotations(AnnotatedBeanDefinition abd, AnnotatedTypeMetadata metadata) { if (metadata.isAnnotated(Lazy.class.getName())) { //@Lazy注解属性提取和设置 abd.setLazyInit(attributesFor(metadata, Lazy.class).getBoolean("value")); } else if (abd.getMetadata() != metadata && abd.getMetadata().isAnnotated(Lazy.class.getName())) { abd.setLazyInit(attributesFor(abd.getMetadata(), Lazy.class).getBoolean("value")); } if (metadata.isAnnotated(Primary.class.getName())) { //@Primary注解属性提取和设置 abd.setPrimary(true); } if (metadata.isAnnotated(DependsOn.class.getName())) { //@DependsOn注解属性提取和设置 abd.setDependsOn(attributesFor(metadata, DependsOn.class).getStringArray("value")); } if (abd instanceof AbstractBeanDefinition) { AbstractBeanDefinition absBd = (AbstractBeanDefinition) abd; if (metadata.isAnnotated(Role.class.getName())) { //@Role注解属性提取和设置 absBd.setRole(attributesFor(metadata, Role.class).getNumber("value").intValue()); } if (metadata.isAnnotated(Description.class.getName())) { //@Description注解属性提取和设置 absBd.setDescription(attributesFor(metadata, Description.class).getString("value")); } }}
ConfigurationClassBeanDefinitionReader:
private void loadBeanDefinitionsForBeanMethod(BeanMethod beanMethod) { ConfigurationClass configClass = beanMethod.getConfigurationClass(); MethodMetadata metadata = beanMethod.getMetadata(); String methodName = metadata.getMethodName(); //相同的是否需要跳过的判断 if (this.conditionEvaluator.shouldSkip(metadata, ConfigurationPhase.REGISTER_BEAN)) { configClass.skippedBeanMethods.add(methodName); return; } if (configClass.skippedBeanMethods.contains(methodName)) { return; } //@Bean注解属性的提取 AnnotationAttributes bean = AnnotationConfigUtils.attributesFor(metadata, Bean.class); List<String> names = new ArrayList<String>(Arrays.asList(bean.getStringArray("name"))); //name属性 String beanName = (!names.isEmpty() ? names.remove(0) : methodName); for (String alias : names) { this.registry.registerAlias(beanName, alias); //注册别名 } if (isOverriddenByExistingDefinition(beanMethod, beanName)) { return; } ConfigurationClassBeanDefinition beanDef = new ConfigurationClassBeanDefinition(configClass, metadata); beanDef.setResource(configClass.getResource()); beanDef.setSource(this.sourceExtractor.extractSource(metadata, configClass.getResource())); //对@Bean注解的静态方法和普通方法的不同处理 if (metadata.isStatic()) { beanDef.setBeanClassName(configClass.getMetadata().getClassName()); beanDef.setFactoryMethodName(methodName); } else { beanDef.setFactoryBeanName(configClass.getBeanName()); beanDef.setUniqueFactoryMethodName(methodName); } beanDef.setAutowireMode(RootBeanDefinition.AUTOWIRE_CONSTRUCTOR); beanDef.setAttribute(RequiredAnnotationBeanPostProcessor.SKIP_REQUIRED_CHECK_ATTRIBUTE, Boolean.TRUE); AnnotationConfigUtils.processCommonDefinitionAnnotations(beanDef, metadata); //通用注解的解析和设置 Autowire autowire = bean.getEnum("autowire"); //autowire属性 if (autowire.isAutowire()) { beanDef.setAutowireMode(autowire.value()); } String initMethodName = bean.getString("initMethod"); //initMethod属性 if (StringUtils.hasText(initMethodName)) { beanDef.setInitMethodName(initMethodName); } String destroyMethodName = bean.getString("destroyMethod"); //destroyMethod属性 if (destroyMethodName != null) { beanDef.setDestroyMethodName(destroyMethodName); } ScopedProxyMode proxyMode = ScopedProxyMode.NO; //@Scope注解属性提取 AnnotationAttributes attributes = AnnotationConfigUtils.attributesFor(metadata, Scope.class); if (attributes != null) { beanDef.setScope(attributes.getString("value")); //value属性 proxyMode = attributes.getEnum("proxyMode"); //proxyMode属性 if (proxyMode == ScopedProxyMode.DEFAULT) { proxyMode = ScopedProxyMode.NO; } } BeanDefinition beanDefToRegister = beanDef; if (proxyMode != ScopedProxyMode.NO) { //代理模式的应用 BeanDefinitionHolder proxyDef = ScopedProxyCreator.createScopedProxy( new BeanDefinitionHolder(beanDef, beanName), this.registry, proxyMode == ScopedProxyMode.TARGET_CLASS); beanDefToRegister = new ConfigurationClassBeanDefinition( (RootBeanDefinition) proxyDef.getBeanDefinition(), configClass, metadata); } if (logger.isDebugEnabled()) { logger.debug(String.format("Registering bean definition for @Bean method %s.%s()", configClass.getMetadata().getClassName(), beanName)); } this.registry.registerBeanDefinition(beanName, beanDefToRegister); //注册BeanDefinition}
其中大部分过程我们在默认标签解析的文章中分析bean标签的解析时都阐述过,这里不再重复说明。
ConfigurationClassBeanDefinitionReader:
private void loadBeanDefinitionsFromImportedResources( Map<String, Class<? extends BeanDefinitionReader>> importedResources) { Map<Class<?>, BeanDefinitionReader> readerInstanceCache = new HashMap<Class<?>, BeanDefinitionReader>(); for (Map.Entry<String, Class<? extends BeanDefinitionReader>> entry : importedResources.entrySet()) { String resource = entry.getKey(); Class<? extends BeanDefinitionReader> readerClass = entry.getValue(); if (BeanDefinitionReader.class == readerClass) { //根据配置资源的后缀判断使用哪种BeanDefinitionReader if (StringUtils.endsWithIgnoreCase(resource, ".groovy")) { readerClass = GroovyBeanDefinitionReader.class; } else { readerClass = XmlBeanDefinitionReader.class; } } BeanDefinitionReader reader = readerInstanceCache.get(readerClass); if (reader == null) { try { //缓存中没有则进行初始化 reader = readerClass.getConstructor(BeanDefinitionRegistry.class).newInstance(this.registry); if (reader instanceof AbstractBeanDefinitionReader) { AbstractBeanDefinitionReader abdr = ((AbstractBeanDefinitionReader) reader); abdr.setResourceLoader(this.resourceLoader); abdr.setEnvironment(this.environment); } readerInstanceCache.put(readerClass, reader); } catch (Throwable ex) { throw new IllegalStateException( "Could not instantiate BeanDefinitionReader class [" + readerClass.getName() + "]"); } } reader.loadBeanDefinitions(resource); //加载BeanDefinition }}
到这里,整个注解扫描的分析就完成了。
- Spring源码解析之注解的扫描
- spring类扫描注入-----类扫描的注解解析器
- spring中扫描bean的源码解析
- Spring源码研究之注解扫描<context:component-scan/>
- Spring——类扫描的注解解析器
- 初学SpringMVC+Mybatis之Spring基于注解的组件扫描
- SDWebImage源码解析之SDWebImageManager的注解
- SDWebImage源码解析之SDWebImageManager的注解
- SDWebImage源码解析之SDWebImageManager的注解
- SDWebImage源码解析之SDWebImageManager的注解
- SDWebImage源码解析之SDWebImageManager的注解
- SDWebImage源码解析之SDWebImageManager的注解
- spring源码解析 关于注解
- 【第二章:源码解析】Spring的BeanFactory的接口注解
- Spring源码分析【4】-Spring扫描basePackages注解
- Spring各种依赖注入注解的区别(源码解析)
- Spring提取@Transactional事务注解的源码解析
- spring 自定义注解的注册与扫描
- 关于win2008+iis下php程序无法写入…
- 不能比较或排序 text、ntext&…
- 随机数
- win7+IIS+PHP配置
- mybatis 返回主键出错 P…
- Spring源码解析之注解的扫描
- mybatis 批量插入数据mysql和…
- a标签中UUID作为参数传入onclick函…
- 配置spring mvc请求的几种方式
- easyui加载数据两次请求后台的问题…
- shirofilter权限配置说明
- MySQL数据库死锁的解决办法
- 在IntellJIDEA上部署TOMCAT服务器
- The valid characters are defined in RFC 7230and RFC 3986