Spring IOC容器 源码解析系列,建议你们按顺序阅读,欢迎讨论java
(spring源码均为4.1.6.RELEASE版本)node
如今的企业项目中使用spring时,大都不经过在xml中定义bean,由于实际项目下bean的定义繁多且依赖复杂,xml的方式会致使配置及更新困难。目前通常都经过简单的xml和注解综合使用的方式来对bean的定义和依赖进行配置。在这其中,包扫描就成为注解方式必备的xml基本配置。经过扫描包来初步过滤出spring要管理的类,进而深刻地定义和组装bean及其依赖关系。正则表达式
在spring的xml配置中,经过context命名空间下的component-scan标签配置包扫描功能。而后在spring解析xml时调用context:component-scan的回调方法执行,关于context此类自定义命名空间的解析在Spring源码-IOC容器(八)-NamespaceHandler与自定义xml一章已详细讲解过了。咱们直接经过ContextNamespaceHandler
中对component-scan注册的解析器来分析spring包扫描的过程。spring
在ContextNamespaceHandler
的init方法中,注册了各个子标签对应的parser解析器,component-scan对应的为ComponentScanBeanDefinitionParser。express
registerBeanDefinitionParser("component-scan", new ComponentScanBeanDefinitionParser());
ComponentScanBeanDefinitionParser中对应的回调方法即parse方法。此方法定义在接口BeanDefinitionParser中。全部的parser解析器都会实现它来完成自定义的操做。来看下 ComponentScanBeanDefinitionParser的parse方法,结构很清晰。数组
ComponentScanBeanDefinitionParser.java public BeanDefinition parse(Element element, ParserContext parserContext) { // 获取base-packgage属性 String basePackage = element.getAttribute(BASE_PACKAGE_ATTRIBUTE); // 对base-package的值中的${}进行解析并替换 basePackage = parserContext.getReaderContext().getEnvironment().resolvePlaceholders(basePackage); // 解析分隔符 String[] basePackages = StringUtils.tokenizeToStringArray(basePackage, ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS); // 建立classpath扫描器 ClassPathBeanDefinitionScanner scanner = configureScanner(parserContext, element); // 执行扫描操做,返回组装好的BeanDefinition集合 Set<BeanDefinitionHolder> beanDefinitions = scanner.doScan(basePackages); // 根据配置注册相关组件 registerComponents(parserContext.getReaderContext(), beanDefinitions, element); return null; }
在spring-context.xsd中对base-package属性要求是必填,而base-package的值支持${}的配置,仅仅只能解析系统属性,包括System.getProperties()和System.getenv()中的属性。对于经过spring中加载的properties资源是支持不了的(可见https://jira.spring.io/browse/SPR-4351)。而对于分隔符支持仍是比较丰富的,CONFIG_LOCATION_DELIMITERS的定义为app
String CONFIG_LOCATION_DELIMITERS = ",; \t\n";
建立和配置classpath扫描器,经过configureScanner方法返回ClassPathBeanDefinitionScanneride
ComponentScanBeanDefinitionParser.java protected ClassPathBeanDefinitionScanner configureScanner(ParserContext parserContext, Element element) { // 是否使用默认过滤器(@Component注解) boolean useDefaultFilters = true; if (element.hasAttribute(USE_DEFAULT_FILTERS_ATTRIBUTE)) { useDefaultFilters = Boolean.valueOf(element.getAttribute(USE_DEFAULT_FILTERS_ATTRIBUTE)); } // Delegate bean definition registration to scanner class. // 建立scan实例,设置默认过滤器 ClassPathBeanDefinitionScanner scanner = createScanner(parserContext.getReaderContext(), useDefaultFilters); scanner.setResourceLoader(parserContext.getReaderContext().getResourceLoader()); scanner.setEnvironment(parserContext.getReaderContext().getEnvironment()); scanner.setBeanDefinitionDefaults(parserContext.getDelegate().getBeanDefinitionDefaults()); scanner.setAutowireCandidatePatterns(parserContext.getDelegate().getAutowireCandidatePatterns()); // 解析资源正则表达式,匹配类名称 if (element.hasAttribute(RESOURCE_PATTERN_ATTRIBUTE)) { scanner.setResourcePattern(element.getAttribute(RESOURCE_PATTERN_ATTRIBUTE)); } try { // 解析bean名称生成器 parseBeanNameGenerator(element, scanner); } catch (Exception ex) { parserContext.getReaderContext().error(ex.getMessage(), parserContext.extractSource(element), ex.getCause()); } try { // scope-resolver(scope解析器)以及scope-proxy(代理方式,默认为no) parseScope(element, scanner); } catch (Exception ex) { parserContext.getReaderContext().error(ex.getMessage(), parserContext.extractSource(element), ex.getCause()); } // include-filters和exclude-filters解析 parseTypeFilters(element, scanner, parserContext); return scanner; }
对因而否使用默认过滤器(useDefaultFilters),默认设置为true,除非你有什么特别的要求。在createScanner方法中实例化了ClassPathBeanDefinitionScanner,并在构造参数中传入了useDefaultFilters,追溯其构造方法的实现,在父类ClassPathScanningCandidateComponentProvider的构造参数中,注册了默认过滤器。post
public ClassPathScanningCandidateComponentProvider(boolean useDefaultFilters, Environment environment) { if (useDefaultFilters) { registerDefaultFilters(); } Assert.notNull(environment, "Environment must not be null"); this.environment = environment; } protected void registerDefaultFilters() { // @Component注册过滤器 this.includeFilters.add(new AnnotationTypeFilter(Component.class)); ClassLoader cl = ClassPathScanningCandidateComponentProvider.class.getClassLoader(); try { // @ManagedBean过滤器 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) { // JSR-250 1.1 API (as included in Java EE 6) not available - simply skip. } try { // @Named过滤器 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) { // JSR-330 API not available - simply skip. } }
通常状况下都是经过@Component来过滤,而@Repository,@Service,@Controller都是@Component的子类。若是须要格外添加的过滤条件,或者想排除特定的类,能够经过字标签context:include-filter和context:exclude-filter来配置。好比想包含自定义的注解@SelfDefined,同时排除@Controller注解,能够配置以下:ui
<context:component-scan base-package="com.lcifn.spring"> <context:include-filter type="annotation" expression="com.lcifn.SelfDefined"/> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/> </context:component-scan>
源码中的解析过程也即上面的parseTypeFilters方法,对于不一样的type生成不一样的TypeFilter。
ComponentScanBeanDefinitionParser.java protected void parseTypeFilters(Element element, ClassPathBeanDefinitionScanner scanner, ParserContext parserContext) { // Parse exclude and include filter elements. 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()); } } } }
拿到scanner扫描器后,真正执行扫描的操做。
ClassPathBeanDefinitionScanner.java 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) { // 扫描包路径,找到全部候选者 Set<BeanDefinition> candidates = findCandidateComponents(basePackage); for (BeanDefinition candidate : candidates) { // 解析scope属性 ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate); candidate.setScope(scopeMetadata.getScopeName()); // 生成bean名称 String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry); if (candidate instanceof AbstractBeanDefinition) { // 组装BeanDefinition默认属性 postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName); } if (candidate instanceof AnnotatedBeanDefinition) { // 解析类中的注解配置 AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate); } // 校验同已注册的BeanDefinition是否有冲突 if (checkCandidate(beanName, candidate)) { BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName); // scope-proxy设置 definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry); beanDefinitions.add(definitionHolder); // 注册BeanDefinition到容器中 registerBeanDefinition(definitionHolder, this.registry); } } } return beanDefinitions; }
基本步骤就是先经过包路径数组查找到全部的候选者,而后遍历全部的候选者,设置scope属性以及bean名称,并设置BeanDefinition默认属性以及经过注解设置的属性。
根据base-package以及resource-pattern组装出资源匹配表达式来匹配并读取全部的class文件
ClassPathScanningCandidateComponentProvider.findCandidateComponents String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX + resolveBasePackage(basePackage) + "/" + this.resourcePattern; Resource[] resources = this.resourcePatternResolver.getResources(packageSearchPath);
获取class文件的元信息,和全部TypeFilter进行匹配,匹配成功后建立ScannedGenericBeanDefinition,校验class非接口非抽象,便可添加到候选者集合中。
ClassPathScanningCandidateComponentProvider.findCandidateComponents // 获取class文件元信息 MetadataReader metadataReader = this.metadataReaderFactory.getMetadataReader(resource); // 匹配TypeFilter if (isCandidateComponent(metadataReader)) { ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader); sbd.setResource(resource); sbd.setSource(resource); // 校验是否非接口非抽象 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); } } }
在匹配TypeFilter时,既要匹配includeFilter也要排除excludeFilter
ClassPathScanningCandidateComponentProvider.java protected boolean isCandidateComponent(MetadataReader metadataReader) throws IOException { for (TypeFilter tf : this.excludeFilters) { if (tf.match(metadataReader, this.metadataReaderFactory)) { return false; } } for (TypeFilter tf : this.includeFilters) { if (tf.match(metadataReader, this.metadataReaderFactory)) { return isConditionMatch(metadataReader); } } return false; }
ClassPathBeanDefinitionScanner.java protected void postProcessBeanDefinition(AbstractBeanDefinition beanDefinition, String beanName) { // 设置默认属性 beanDefinition.applyDefaults(this.beanDefinitionDefaults); if (this.autowireCandidatePatterns != null) { beanDefinition.setAutowireCandidate(PatternMatchUtils.simpleMatch(this.autowireCandidatePatterns, beanName)); } } public void applyDefaults(BeanDefinitionDefaults defaults) { setLazyInit(defaults.isLazyInit()); // false setAutowireMode(defaults.getAutowireMode()); // AUTOWIRE_NO setDependencyCheck(defaults.getDependencyCheck());// DEPENDENCY_CHECK_NONE setInitMethodName(defaults.getInitMethodName()); // null setEnforceInitMethod(false); setDestroyMethodName(defaults.getDestroyMethodName());// null setEnforceDestroyMethod(false); }
能够经过在类中使用注解进行一些配置,包括@Lazy,@Primary,@DependsOn
AnnotationConfigUtils.java static void processCommonDefinitionAnnotations(AnnotatedBeanDefinition abd, AnnotatedTypeMetadata metadata) { if (metadata.isAnnotated(Lazy.class.getName())) { 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())) { abd.setPrimary(true); } if (metadata.isAnnotated(DependsOn.class.getName())) { abd.setDependsOn(attributesFor(metadata, DependsOn.class).getStringArray("value")); } if (abd instanceof AbstractBeanDefinition) { AbstractBeanDefinition absBd = (AbstractBeanDefinition) abd; if (metadata.isAnnotated(Role.class.getName())) { absBd.setRole(attributesFor(metadata, Role.class).getNumber("value").intValue()); } if (metadata.isAnnotated(Description.class.getName())) { absBd.setDescription(attributesFor(metadata, Description.class).getString("value")); } } }
包扫描以后只是将符合条件的类解析成BeanDefinition注册到容器中,而在bean的实例化过程当中,每每须要依赖注入,依赖检查之类的注解的解析操做,为了不配置的冗杂,在component-scan标签中有一个annotation-config的属性,默认为true,即加载全部常规注解的解析器。这个处理就在ComponentScanBeanDefinitionParser的registerComponents方法中。
// Register annotation config processors, if necessary. boolean annotationConfig = true; if (element.hasAttribute(ANNOTATION_CONFIG_ATTRIBUTE)) { annotationConfig = Boolean.valueOf(element.getAttribute(ANNOTATION_CONFIG_ATTRIBUTE)); } if (annotationConfig) { Set<BeanDefinitionHolder> processorDefinitions = AnnotationConfigUtils.registerAnnotationConfigProcessors(readerContext.getRegistry(), source); for (BeanDefinitionHolder processorDefinition : processorDefinitions) { compositeDef.addNestedComponent(new BeanComponentDefinition(processorDefinition)); } }
核心的代码在AnnotationConfigUtils.registerAnnotationConfigProcessors中
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); // @Configuration注解解析器 if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) { RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class); def.setSource(source); beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)); } // @Autowired注解解析器 if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) { RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class); def.setSource(source); beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)); } // @Required注解解析器 if (!registry.containsBeanDefinition(REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) { RootBeanDefinition def = new RootBeanDefinition(RequiredAnnotationBeanPostProcessor.class); def.setSource(source); beanDefs.add(registerPostProcessor(registry, def, REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME)); } // Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor. if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) { RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class); def.setSource(source); beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)); } // Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor. 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)); } return beanDefs; }
能够看到主要的@Configuration,@Autowired,@Required的解析器,都是BeanFactoryPostProcessor或者BeanPostProcessor的子类,在这里注册到spring容器中。等到bean实例化的过程当中,在适当的时候对bean进行配置或调整。
到此component-scan的解析就结束了,但愿你们能够多看源码,有所收获。