看这篇文章以前能够先了解以前的跟踪流程,https://www.jianshu.com/p/4934233f0eadjava
代码过宽,能够shift + 鼠标滚轮 左右滑动查看node
这篇文章主要跟踪spring配置文件中component-scan标签,查看它是怎样被解析扫描生成对应的beanDefinition。web
在applicationContext.xml中作如下配置:spring
<!-- 启动组件扫描,排除@Controller组件,该组件由SpringMVC配置文件扫描 --> <context:component-scan base-package="cn.mrdear"> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" /> <context:exclude-filter type="annotation" expression="org.springframework.web.bind.annotation.RestController" /> </context:component-scan>
以DefaultBeanDefinitionDocumentReader类中的parseBeanDefinitions方法做为开始,向下跟踪。express
/** * Parse the elements at the root level in the document: * "import", "alias", "bean". * * 解析在文档中根层级的元素:"import", "alias", "bean". */ protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) { //默认名称空间是"http://www.springframework.org/schema/beans" //进入条件 if (delegate.isDefaultNamespace(root)) { //获取根元素下的子Node,注意,Node不必定是子标签,多是回车,多是注释 NodeList nl = root.getChildNodes(); for (int i = 0; i < nl.getLength(); i++) { Node node = nl.item(i); if (node instanceof Element) { //拿到了<beans>下的子标签 Element ele = (Element) node; if (delegate.isDefaultNamespace(ele)) { //若是该标签属于beans的名称空间,则进入这个方法 //xmlns="http://www.springframework.org/schema/beans" parseDefaultElement(ele, delegate); } else { //若是该标签属于其余的名称空间好比:context,aop等 //xmlns:aop="http://www.springframework.org/schema/aop" //xmlns:context="http://www.springframework.org/schema/context" delegate.parseCustomElement(ele); } } } } else { delegate.parseCustomElement(root); } }
对以上方法不太了解的能够先看下这篇文章:api
https://www.jianshu.com/p/a0cfaedf3fc5数组
由于component-scan标签属于context名称空间,因此走这个方法。app
delegate.parseCustomElement(ele);
这个方法的实如今BeanDefinitionParserDelegate类中ide
public BeanDefinition parseCustomElement(Element ele) { return parseCustomElement(ele, null); } //containingBd入参传递为null public BeanDefinition parseCustomElement(Element ele, BeanDefinition containingBd) { //获取标签所属的名称空间 //http://www.springframework.org/schema/context String namespaceUri = getNamespaceURI(ele); //每一个名称空间对应一个处理器,拿到对应context的处理器 NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri); if (handler == null) { error("Unable to locate Spring NamespaceHandler for XML schema namespace [" + namespaceUri + "]", ele); return null; } //进入这个方法 return handler.parse(ele, new ParserContext(this.readerContext, this, containingBd)); }
虽然context对应的处理器是ContextNamespaceHandler,但其实是调用其父类NamespaceHandlerSupport类中的parse方法。post
/** * Parses the supplied {@link Element} by delegating to the {@link BeanDefinitionParser} that is * registered for that {@link Element}. * * 经过委派给BeanDefinitionParser来解析元素,并为该元素注册 */ @Override public BeanDefinition parse(Element element, ParserContext parserContext) { return findParserForElement(element, parserContext).parse(element, parserContext); }
先查看findParserForElement方法,此方法仍是在NamespaceHandlerSupport类中。
/** * Locates the {@link BeanDefinitionParser} from the register implementations using * the local name of the supplied {@link Element}. * * 经过元素的部分名称,去从注册器实现中定位BeanDefinitionParser */ private BeanDefinitionParser findParserForElement(Element element, ParserContext parserContext) { //拿到标签的名称(不包含名称空间) //component-scan String localName = parserContext.getDelegate().getLocalName(element); //parsers是一个HashMap, //在生成处理器的时候,会初始化一系列解析器,每个解析器对应着一个标签名称 //以名称作key,解析器做为value,放入到parsers属性中 //这里能够经过标签名称拿到对应的解析器 BeanDefinitionParser parser = this.parsers.get(localName); if (parser == null) { parserContext.getReaderContext().fatal( "Cannot locate BeanDefinitionParser for element [" + localName + "]", element); } return parser; }
找到解析器后,调用解析器的parse方法。
这里的解析器是ComponentScanBeanDefinitionParser类,进入parse方法查看
/** * 解析指定的Element,而后注册结果BeanDefinition到内嵌在ParserContext里的bean factory中。 */ @Override public BeanDefinition parse(Element element, ParserContext parserContext) { //获取component-scan标签的base-package属性值 //cn.mrdear String basePackage = element.getAttribute(BASE_PACKAGE_ATTRIBUTE); //若是有占位符,则解析全部的占位符 basePackage = parserContext.getReaderContext().getEnvironment().resolvePlaceholders(basePackage); //字符串中有" ,;\n\t"等符号就看作分隔符,分割成数组 String[] basePackages = StringUtils.tokenizeToStringArray(basePackage, ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS); // Actually scan for bean definitions and register them. // 扫描bean definition 并注册它们 // 1.配置扫描器 ClassPathBeanDefinitionScanner scanner = configureScanner(parserContext, element); // 2.利用扫描器扫描包,并注册bean definition Set<BeanDefinitionHolder> beanDefinitions = scanner.doScan(basePackages); // 3. 注册组件 registerComponents(parserContext.getReaderContext(), beanDefinitions, element); return null; }
跟踪标记1的方法
此方法在ComponentScanBeanDefinitionParser类中实现
// 1.配置扫描器 ClassPathBeanDefinitionScanner scanner = configureScanner(parserContext, element); //进入方法 protected ClassPathBeanDefinitionScanner configureScanner(ParserContext parserContext, Element element) { boolean useDefaultFilters = true; //拿到component-scan标签的use-default-filters属性,没有配置则为true if (element.hasAttribute(USE_DEFAULT_FILTERS_ATTRIBUTE)) { useDefaultFilters = Boolean.valueOf(element.getAttribute(USE_DEFAULT_FILTERS_ATTRIBUTE)); } // Delegate bean definition registration to scanner class. // 1.1将bean definition的工厂委派给scanner类 ClassPathBeanDefinitionScanner scanner = createScanner(parserContext.getReaderContext(), useDefaultFilters); //这里将阅读器上下文中拿到的根web应用上下文做为scanner的ResourceLoader, //根web应用上下文默认实现为XmlWebApplicationContext,实现了ResourceLoader接口, //因此能够做为ResourceLoader scanner.setResourceLoader(parserContext.getReaderContext().getResourceLoader()); //初始化scanner时使用默认的StandardEnvironment做为environment, //这里拿到了阅读器上下文中的environment,StandardServletEnvironment //其实阅读器中的environment拿的是XmlWebApplicationContext的environment scanner.setEnvironment(parserContext.getReaderContext().getEnvironment()); //获取代理类的defaults属性中,对标签属性的一些默认设置 scanner.setBeanDefinitionDefaults(parserContext.getDelegate().getBeanDefinitionDefaults()); //这里为null scanner.setAutowireCandidatePatterns(parserContext.getDelegate().getAutowireCandidatePatterns()); //拿到component-scan标签的resource-pattern属性,这里没有设置 if (element.hasAttribute(RESOURCE_PATTERN_ATTRIBUTE)) { scanner.setResourcePattern(element.getAttribute(RESOURCE_PATTERN_ATTRIBUTE)); } try { //1.2解析name-generator属性 parseBeanNameGenerator(element, scanner); } catch (Exception ex) { parserContext.getReaderContext().error(ex.getMessage(), parserContext.extractSource(element), ex.getCause()); } try { //1.3解析Scope parseScope(element, scanner); } catch (Exception ex) { parserContext.getReaderContext().error(ex.getMessage(), parserContext.extractSource(element), ex.getCause()); } //1.4解析类过滤器 parseTypeFilters(element, scanner, parserContext); return scanner; }
跟踪标记1.1的方法
此方法在ComponentScanBeanDefinitionParser类中实现
// 1.1将bean definition的注册委派给scanner类 ClassPathBeanDefinitionScanner scanner = createScanner(parserContext.getReaderContext(), useDefaultFilters); //入参传递了bean工厂,useDefaultFilters为true protected ClassPathBeanDefinitionScanner createScanner(XmlReaderContext readerContext, boolean useDefaultFilters) { return new ClassPathBeanDefinitionScanner(readerContext.getRegistry(), useDefaultFilters); }
看下ClassPathBeanDefinitionScanner类的构造实现
//由于默认的工厂DefaultListableBeanFactory没有实现EnvironmentCapable接口 //因此从新建立了一个environment,与上下文的StandardServletEnvironment不一样, //这个environment是StandardEnvironment类型,在environment初始化的同时,会将 //systemProperties和systemEnvironment读取到environment内部 public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters) { this(registry, useDefaultFilters, getOrCreateEnvironment(registry)); } public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters, Environment environment) { //调用了父类的构造 super(useDefaultFilters, environment); Assert.notNull(registry, "BeanDefinitionRegistry must not be null"); //拿到bean工厂的引用 this.registry = registry; // Determine ResourceLoader to use. // 默认bean工厂没有实现ResourceLoader接口,这里默认使用PathMatchingResourcePatternResolver // 做为ResourceLoader if (this.registry instanceof ResourceLoader) { setResourceLoader((ResourceLoader) this.registry); } }
再进入父类构造中查看初始化了哪些属性
进入ClassPathScanningCandidateComponentProvider类中,查看对应的构造方法
public ClassPathScanningCandidateComponentProvider(boolean useDefaultFilters, Environment environment) { //由于useDefaultFilters设置为了true,因此下面的方法会被调用 if (useDefaultFilters) { registerDefaultFilters(); } Assert.notNull(environment, "Environment must not be null"); //拿到先前新建的StandardEnvironment引用 this.environment = environment; } /** * Register the default filter for {@link Component @Component}. * <p>This will implicitly register all annotations that have the * {@link Component @Component} meta-annotation including the * {@link Repository @Repository}, {@link Service @Service}, and * {@link Controller @Controller} stereotype annotations. * <p>Also supports Java EE 6's {@link javax.annotation.ManagedBean} and * JSR-330's {@link javax.inject.Named} annotations, if available. * * 为@Component注解注册默认的过滤器。 * 隐式的注册全部包含@Component元注解的注解,包括@Repository、@Service、@Controller * 等老旧的注解。 * 也支持Java EE 6的javax.annotation.ManagedBean和JSR-330的javax.inject.Named注解 */ @SuppressWarnings("unchecked") protected void registerDefaultFilters() { //includeFilters是一个LinkedList,存放注解类型过滤器, //只有符合过滤器的注解类型才能生成bean definition //1.1.1了解下AnnotationTypeFilter的构造实现,注解类型为Component this.includeFilters.add(new AnnotationTypeFilter(Component.class)); //拿到该类的类加载器 ClassLoader cl = ClassPathScanningCandidateComponentProvider.class.getClassLoader(); try { //1.1.2查看注解类型为ManagedBean的AnnotationTypeFilter构造实现 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注解同1.1.2, //可是这里没有相关jar包,因此没有javax.inject.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. } }
跟踪标记1.1.1的方法
//1.1.1了解下AnnotationTypeFilter的构造实现 new AnnotationTypeFilter(Component.class) /** * Create a new AnnotationTypeFilter for the given annotation type. * This filter will also match meta-annotations. To disable the * meta-annotation matching, use the constructor that accepts a * '{@code considerMetaAnnotations}' argument. The filter will * not match interfaces. * * 经过给定的注解类型建立一个新的注解类型过滤器 * 这个过滤器还会匹配元注解 * 若是要禁用元注解匹配,可使用接受considerMetaAnnotations参数的构造方法。 * 这个过滤器不会匹配接口 */ public AnnotationTypeFilter(Class<? extends Annotation> annotationType) { this(annotationType, true, false); } /** * 注意上一层调用构造时的入参,默认considerMetaAnnotations为true,considerInterfaces为false * 这说明注解中若是它的元注解匹配过滤器,那么也算是匹配。 * 过滤的时候不考虑是接口的状况 */ public AnnotationTypeFilter(Class<? extends Annotation> annotationType, boolean considerMetaAnnotations, boolean considerInterfaces) { //isAnnotationPresent方法是用来查看annotationType上是否有Inherited注解 //其boolean值赋值给父类AbstractTypeHierarchyTraversingFilter的属性considerInherited中 super(annotationType.isAnnotationPresent(Inherited.class), considerInterfaces); this.annotationType = annotationType; this.considerMetaAnnotations = considerMetaAnnotations; }
跟踪标记1.1.2的方法
//1.1.2查看注解类型为ManagedBean的AnnotationTypeFilter构造实现 new AnnotationTypeFilter( ((Class<? extends Annotation>) ClassUtils.forName("javax.annotation.ManagedBean", cl)), false);
首先经过forName方法,拿到字符串javax.annotation.ManagedBean对应的Class,而后调用AnnotationTypeFilter的构造。
/** * 上一层传参时considerMetaAnnotations为false,说明不用考虑注解上的元注解,这个注解不匹配过滤器就过滤掉 */ public AnnotationTypeFilter(Class<? extends Annotation> annotationType, boolean considerMetaAnnotations) { this(annotationType, considerMetaAnnotations, false); } //considerInterfaces依然为false public AnnotationTypeFilter(Class<? extends Annotation> annotationType, boolean considerMetaAnnotations, boolean considerInterfaces) { //ManagedBean的元注解上依然没有Inherited,因此considerInherited为false super(annotationType.isAnnotationPresent(Inherited.class), considerInterfaces); this.annotationType = annotationType; this.considerMetaAnnotations = considerMetaAnnotations; }
跟踪标记1.2的方法
在ComponentScanBeanDefinitionParser类中实现
//1.2解析name-generator属性 parseBeanNameGenerator(element, scanner); protected void parseBeanNameGenerator(Element element, ClassPathBeanDefinitionScanner scanner) { //component-scan标签的name-generator属性,这里没有设置,跳过 if (element.hasAttribute(NAME_GENERATOR_ATTRIBUTE)) { BeanNameGenerator beanNameGenerator = (BeanNameGenerator) instantiateUserDefinedStrategy( element.getAttribute(NAME_GENERATOR_ATTRIBUTE), BeanNameGenerator.class, scanner.getResourceLoader().getClassLoader()); scanner.setBeanNameGenerator(beanNameGenerator); } }
跟踪标记1.3的方法
在ComponentScanBeanDefinitionParser类中实现
//1.3 解析Scope parseScope(element, scanner); protected void parseScope(Element element, ClassPathBeanDefinitionScanner scanner) { // Register ScopeMetadataResolver if class name provided. // 若是类名被提供,则注册ScopeMetadataResolver // 标签上有无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); } // 标签上有无scoped-proxy属性 if (element.hasAttribute(SCOPED_PROXY_ATTRIBUTE)) { String mode = element.getAttribute(SCOPED_PROXY_ATTRIBUTE); 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'"); } } }
跟踪标记1.4的方法
在ComponentScanBeanDefinitionParser类中实现
//1.4解析类过滤器 parseTypeFilters(element, scanner, parserContext); 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()); } } } }
跟踪createTypeFilter方法
protected TypeFilter createTypeFilter(Element element, ClassLoader classLoader, ParserContext parserContext) { //获取标签上的type属性和expression属性对应的值 String filterType = element.getAttribute(FILTER_TYPE_ATTRIBUTE); String expression = element.getAttribute(FILTER_EXPRESSION_ATTRIBUTE); //expression可能带有占位符,若是有则解析占位符 expression = parserContext.getReaderContext().getEnvironment().resolvePlaceholders(expression); try { //xml文件中type填写的是annotation,因此走这个方法 if ("annotation".equals(filterType)) { //将xml中的"org.springframework.stereotype.Controller"字符串解析为Class //构造已经看过,默认considerMetaAnnotations为true,considerInterfaces为false return new AnnotationTypeFilter((Class<Annotation>) classLoader.loadClass(expression)); } else if ("assignable".equals(filterType)) { return new AssignableTypeFilter(classLoader.loadClass(expression)); } else if ("aspectj".equals(filterType)) { return new AspectJTypeFilter(expression, classLoader); } else if ("regex".equals(filterType)) { return new RegexPatternTypeFilter(Pattern.compile(expression)); } else if ("custom".equals(filterType)) { Class<?> filterClass = classLoader.loadClass(expression); if (!TypeFilter.class.isAssignableFrom(filterClass)) { throw new IllegalArgumentException( "Class is not assignable to [" + TypeFilter.class.getName() + "]: " + expression); } return (TypeFilter) BeanUtils.instantiateClass(filterClass); } else { throw new IllegalArgumentException("Unsupported filter type: " + filterType); } } catch (ClassNotFoundException ex) { throw new FatalBeanException("Type filter class not found: " + expression, ex); } }
最后scanner的includeFilters属性中,默认添加了org.springframework.stereotype.Component的注解过滤器和javax.annotation.ManagedBean的注解过滤器。
scanner的excludeFilters属性中,自定义添加了xml配置文件中的org.springframework.stereotype.Controller注解过滤器和org.springframework.web.bind.annotation.RestController注解过滤器。
跟踪标记2的方法
此方法在ClassPathBeanDefinitionScanner类中实现
// 2.利用扫描器扫描包,并注册bean definition Set<BeanDefinitionHolder> beanDefinitions = scanner.doScan(basePackages); /** * Perform a scan within the specified base packages, * returning the registered bean definitions. * <p>This method does <i>not</i> register an annotation config processor * but rather leaves this up to the caller. * * 扫描指定包,返回被注册的bean definitions * 这个方法不会注册annotation config processor,交由调用者处理 */ protected Set<BeanDefinitionHolder> doScan(String... basePackages) { Assert.notEmpty(basePackages, "At least one base package must be specified"); Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<BeanDefinitionHolder>(); //根据配置,这里就只有一个"cn.mrdear" for (String basePackage : basePackages) { //2.1扫描候选者的class path Set<BeanDefinition> candidates = findCandidateComponents(basePackage); for (BeanDefinition candidate : candidates) { //2.2解析@scope注解 ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate); candidate.setScope(scopeMetadata.getScopeName()); //2.3AnnotatedBeanDefinition的默认名称生成规则 String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry); if (candidate instanceof AbstractBeanDefinition) { //2.4给beanDefinition设置默认值、自动注入的候选者 postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName); } if (candidate instanceof AnnotatedBeanDefinition) { //2.5拿到类上其余的context名称空间的注解,若是有的话,获取其value属性 AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate); } //2.6检查beanName是否正确匹配对应的bean Definition,该名称是否已经被注册 if (checkCandidate(beanName, candidate)) { BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName); //应用Scope代理模式 definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry); beanDefinitions.add(definitionHolder); //注册bean definition registerBeanDefinition(definitionHolder, this.registry); } } } return beanDefinitions; }
跟踪标记2.1的方法
在ClassPathScanningCandidateComponentProvider类中实现
ClassPathScanningCandidateComponentProvider是ClassPathBeanDefinitionScanner的父类
//2.1扫描候选者的class path Set<BeanDefinition> candidates = findCandidateComponents(basePackage); public Set<BeanDefinition> findCandidateComponents(String basePackage) { Set<BeanDefinition> candidates = new LinkedHashSet<BeanDefinition>(); try { //给包名添加上"classpath*:"的前缀和"**/*.class"的后缀 //最后结果:classpath*:cn/mrdear/**/*.class String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX + resolveBasePackage(basePackage) + "/" + this.resourcePattern; //将包下的全部class文件用Resource的方式描述 //Resource--资源描述符 //里面的实现很是大,有兴趣能够本身看看。 //主要是将packageSearchPath分红classpath,包名,后缀名三部分进行处理,又根据有无*或者? //等表达式,处理方式有所不一样 Resource[] resources = this.resourcePatternResolver.getResources(packageSearchPath); boolean traceEnabled = logger.isTraceEnabled(); boolean debugEnabled = logger.isDebugEnabled(); //对每一个class进行处理 for (Resource resource : resources) { if (traceEnabled) { logger.trace("Scanning " + resource); } //是否非目录,可读 if (resource.isReadable()) { try { //这个metadataReader包含class文件中,类上的注解 //方法的注解,所使用注解的元注解等描述 //在获取metadataReader的同时,在CachingMetadataReaderFactory类的 //metadataReaderCache属性中存放了一份。此属性是LinkedHashMap MetadataReader metadataReader = this.metadataReaderFactory.getMetadataReader(resource); //2.1.1判断metadataReader可否经过注解类型过滤器过滤 if (isCandidateComponent(metadataReader)) { //建立bean definition,拿到metadataReader的beanClass //保存metadataReader的annotationMetadata的引用 ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader); //取得资源描述符的引用 sbd.setResource(resource); sbd.setSource(resource); //2.1.2查看类是否具体且独立 if (isCandidateComponent(sbd)) { if (debugEnabled) { //肯定候选组件class logger.debug("Identified candidate component class: " + resource); } candidates.add(sbd); } else { if (debugEnabled) { //被忽略,不是一个具体的顶层class 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) { //扫描类路径时IO异常 throw new BeanDefinitionStoreException("I/O failure during classpath scanning", ex); } //最后返回候选的bean definition return candidates; }
我这里返回的就只有两个类,加了@ControllerAdvice的GlobalException、加了@Service的BookServiceImpl。
其他的要么是接口,要么没被扫描,要么被过滤器过滤了,如下是我项目中全部class:
跟踪标记2.1.1的方法
在ClassPathScanningCandidateComponentProvider类中实现
//2.1.1判断metadataReader可否经过注解类型过滤器过滤 isCandidateComponent(metadataReader) /** * Determine whether the given class does not match any exclude filter * and does match at least one include filter. * * 不匹配任何exclude filter,至少匹配一个include filter. * 才能肯定其为候选人 */ protected boolean isCandidateComponent(MetadataReader metadataReader) throws IOException { for (TypeFilter tf : this.excludeFilters) { //2.1.1.1跟踪match方法 //若是metadataReader中有注解匹配exclude过滤器的注解,则返回false if (tf.match(metadataReader, this.metadataReaderFactory)) { return false; } } for (TypeFilter tf : this.includeFilters) { //若是metadataReader中有注解匹配include过滤器的注解,则进入条件 if (tf.match(metadataReader, this.metadataReaderFactory)) { //2.1.1.2是否有@Conditional注解,进行相关处理 return isConditionMatch(metadataReader); } } return false; }
过滤器中存放的都是AnnotationTypeFilter类型
TypeFilter是其顶层接口
match方法主要是在AbstractTypeHierarchyTraversingFilter抽象类中实现
跟踪标记2.1.1.1的方法
在AbstractTypeHierarchyTraversingFilter类中实现
//2.1.1.1跟踪match方法 tf.match(metadataReader, this.metadataReaderFactory) @Override public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException { // This method optimizes avoiding unnecessary creation of ClassReaders // as well as visiting over those readers. // 此方法作了优化,避免没必要要的ClassReaders建立以及对它们的访问 // matchSelf方法判断metadataReader中相关class的注解有没有包含这个过滤器的注解 // 若是没有,可是过滤器的considerMetaAnnotations属性设置为true, // 那么再判断class全部注解的元注解中,有没有包含这个过滤器的注解 // 有就返回true,进入条件 if (matchSelf(metadataReader)) { return true; } ClassMetadata metadata = metadataReader.getClassMetadata(); // 默认返回false,不进入条件 if (matchClassName(metadata.getClassName())) { return true; } //considerInherited这个属性前面跟踪的过滤器中都为false //和过滤器的注解有关,其元注解包含Inherited, //那么considerInherited属性就为true if (this.considerInherited) { if (metadata.hasSuperClass()) { // Optimization to avoid creating ClassReader for super class. Boolean superClassMatch = matchSuperClass(metadata.getSuperClassName()); if (superClassMatch != null) { if (superClassMatch.booleanValue()) { return true; } } else { // Need to read super class to determine a match... try { if (match(metadata.getSuperClassName(), metadataReaderFactory)) { return true; } } catch (IOException ex) { logger.debug("Could not read super class [" + metadata.getSuperClassName() + "] of type-filtered class [" + metadata.getClassName() + "]"); } } } } //considerInterfaces属性在AnnotationTypeFilter构造器中都默认被设置为false if (this.considerInterfaces) { for (String ifc : metadata.getInterfaceNames()) { // Optimization to avoid creating ClassReader for super class Boolean interfaceMatch = matchInterface(ifc); if (interfaceMatch != null) { if (interfaceMatch.booleanValue()) { return true; } } else { // Need to read interface to determine a match... try { if (match(ifc, metadataReaderFactory)) { return true; } } catch (IOException ex) { logger.debug("Could not read interface [" + ifc + "] for type-filtered class [" + metadata.getClassName() + "]"); } } } } return false; }
跟踪标记2.1.1.2的方法
在ClassPathScanningCandidateComponentProvider类中实现
//2.1.1.2是否有@Conditional注解,进行相关处理 isConditionMatch(metadataReader); /** * Determine whether the given class is a candidate component based on any * {@code @Conditional} annotations. * * 肯定指定类是不是基于任何@Conditional注解的候选组件 */ private boolean isConditionMatch(MetadataReader metadataReader) { if (this.conditionEvaluator == null) { this.conditionEvaluator = new ConditionEvaluator(getRegistry(), getEnvironment(), getResourceLoader()); } //跟踪这个方法 return !this.conditionEvaluator.shouldSkip(metadataReader.getAnnotationMetadata()); }
因而进入ConditionEvaluator的shouldSkip方法
/** * Determine if an item should be skipped based on {@code @Conditional} annotations. * The {@link ConfigurationPhase} will be deduced from the type of item (i.e. a * {@code @Configuration} class will be {@link ConfigurationPhase#PARSE_CONFIGURATION}) * * 根据@Conditional注解肯定一个子项是否应该被跳过 * 从子项的类型能够推导ConfigurationPhase,好比@Configuration class就是 * ConfigurationPhase#PARSE_CONFIGURATION--解析配置 */ public boolean shouldSkip(AnnotatedTypeMetadata metadata) { return shouldSkip(metadata, null); } //这个方法就不跟了,若是要了解condition注解的用法,能够详细了解该方法 public boolean shouldSkip(AnnotatedTypeMetadata metadata, ConfigurationPhase phase) { //类上注解或者注解上的元注解不包含Conditional注解就返回false if (metadata == null || !metadata.isAnnotated(Conditional.class.getName())) { return false; } 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>(); for (String[] conditionClasses : getConditionClasses(metadata)) { for (String conditionClass : conditionClasses) { Condition condition = getCondition(conditionClass, this.context.getClassLoader()); conditions.add(condition); } } AnnotationAwareOrderComparator.sort(conditions); for (Condition condition : conditions) { ConfigurationPhase requiredPhase = null; if (condition instanceof ConfigurationCondition) { requiredPhase = ((ConfigurationCondition) condition).getConfigurationPhase(); } if (requiredPhase == null || requiredPhase == phase) { if (!condition.matches(this.context, metadata)) { return true; } } } return false; }
跟踪标记2.1.2的方法
在ClassPathScanningCandidateComponentProvider类中实现
//2.1.2查看类是否具体且独立 isCandidateComponent(sbd) /** * Determine whether the given bean definition qualifies as candidate. * <p>The default implementation checks whether the class is concrete * (i.e. not abstract and not an interface). Can be overridden in subclasses. * * 肯定bean definition qualifies可否做为候选 * 默认实现会检查class是否具体(不是抽象、不是接口)。能够被子类覆盖 */ protected boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) { //看下这两个判断的含义 return (beanDefinition.getMetadata().isConcrete() && beanDefinition.getMetadata().isIndependent()); } //不能是接口和抽象类 public boolean isConcrete() { return !(this.isInterface || this.isAbstract); } //要么是顶层class,要么是被嵌套的class(静态内部类),可是被嵌套的class必须可以从 //封闭的class中独立构造,才能说明此class是独立的。 public boolean isIndependent() { //没有封闭的class或者是独立的内部类 return (this.enclosingClassName == null || this.independentInnerClass); }
跟踪标记2.2的方法
在AnnotationScopeMetadataResolver类中实现
//2.2解析@scope注解 ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate); /** * Resolve the {@link ScopeMetadata} appropriate to the supplied * bean {@code definition}. * <p>Implementations can of course use any strategy they like to * determine the scope metadata, but some implementations that spring * immediately to mind might be to use source level annotations * present on {@link BeanDefinition#getBeanClassName() the class} of the * supplied {@code definition}, or to use metadata present in the * {@link BeanDefinition#attributeNames()} of the supplied {@code definition}. * * 解析适用于BeanDefinition的ScopeMetadata * 实现固然可使用任何喜欢的策略去肯定scope metadata,可是spring的实现立马 * 想到的是使用source level注解在BeanDefinition对应的class上 * 或者将metadata存放于BeanDefinition的属性中 */ public ScopeMetadata resolveScopeMetadata(BeanDefinition definition) { //默认单例,无代理 ScopeMetadata metadata = new ScopeMetadata(); if (definition instanceof AnnotatedBeanDefinition) { AnnotatedBeanDefinition annDef = (AnnotatedBeanDefinition) definition; //拿到指定类上的@scope注解的全部属性 AnnotationAttributes attributes = AnnotationConfigUtils.attributesFor( annDef.getMetadata(), this.scopeAnnotationType); if (attributes != null) { metadata.setScopeName(attributes.getString("value")); ScopedProxyMode proxyMode = attributes.getEnum("proxyMode"); if (proxyMode == null || proxyMode == ScopedProxyMode.DEFAULT) { proxyMode = this.defaultProxyMode; } metadata.setScopedProxyMode(proxyMode); } } return metadata; }
跟踪标记2.3的方法
在AnnotationBeanNameGenerator类中实现
//2.3AnnotatedBeanDefinition的默认名称生成规则 String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry); public String generateBeanName(BeanDefinition definition, BeanDefinitionRegistry registry) { if (definition instanceof AnnotatedBeanDefinition) { //先进入这个方法查看 String beanName = determineBeanNameFromAnnotation((AnnotatedBeanDefinition) definition); if (StringUtils.hasText(beanName)) { // Explicit bean name found. // 发现明确bean Name return beanName; } } // Fallback: generate a unique default bean name. // 回退:生成一个惟一的默认beanName return buildDefaultBeanName(definition, registry); } /** * Derive a bean name from one of the annotations on the class. * * 从类上的一个注解中,派生出bean name */ protected String determineBeanNameFromAnnotation(AnnotatedBeanDefinition annotatedDef) { AnnotationMetadata amd = annotatedDef.getMetadata(); //嘉定拿的是org.springframework.web.bind.annotation.ControllerAdvice Set<String> types = amd.getAnnotationTypes(); String beanName = null; for (String type : types) { //拿到@ControllerAdvice上的全部的属性 AnnotationAttributes attributes = AnnotationConfigUtils.attributesFor(amd, type); //将@ControllerAdvice注解名,@ControllerAdvice的元注解,@ControllerAdvice上的属性 //当作参数传递 //进入这个方法 if (isStereotypeWithNameValue(type, amd.getMetaAnnotationTypes(type), attributes)) { //获取注解上的value属性对应的值 Object value = attributes.get("value"); if (value instanceof String) { String strVal = (String) value; if (StringUtils.hasLength(strVal)) { if (beanName != null && !strVal.equals(beanName)) { throw new IllegalStateException("Stereotype annotations suggest inconsistent " + "component names: '" + beanName + "' versus '" + strVal + "'"); } //用value属性对应的值做为beanName beanName = strVal; } } } } return beanName; } /** * Check whether the given annotation is a stereotype that is allowed * to suggest a component name through its annotation {@code value()}. * * 检查注解是否是stereotype类型,若是是的话,能够用注解的value()属性,做为组件名称 */ protected boolean isStereotypeWithNameValue(String annotationType, Set<String> metaAnnotationTypes, Map<String, Object> attributes) { //注解是否是stereotype类型,主要看他是否是component注解、ManagedBean注解或者Named注解 //或者注解的元注解包含component注解 boolean isStereotype = annotationType.equals(COMPONENT_ANNOTATION_CLASSNAME) || (metaAnnotationTypes != null && metaAnnotationTypes.contains(COMPONENT_ANNOTATION_CLASSNAME)) || annotationType.equals("javax.annotation.ManagedBean") || annotationType.equals("javax.inject.Named"); //是stereotype类型,且有value属性的注解,返回true return (isStereotype && attributes != null && attributes.containsKey("value")); }
上面看了beanDefinition是AnnotatedBeanDefinition类型状况下,beanName怎样生成。可是若是class上的stereotype注解,没有给value属性赋值,那么又是怎样生成beanName的?
查看其默认的beanName生成方式:
buildDefaultBeanName(definition, registry);
此方法的实现仍是在AnnotationBeanNameGenerator类中:
/** * Derive a default bean name from the given bean definition. * <p>The default implementation delegates to {@link #buildDefaultBeanName(BeanDefinition)}. * * 从给定的bean definition派生一个默认bean Name */ protected String buildDefaultBeanName(BeanDefinition definition, BeanDefinitionRegistry registry) { return buildDefaultBeanName(definition); } /** * Derive a default bean name from the given bean definition. * <p>The default implementation simply builds a decapitalized version * of the short class name: e.g. "mypackage.MyJdbcDao" -> "myJdbcDao". * <p>Note that inner classes will thus have names of the form * "outerClassName.InnerClassName", which because of the period in the * name may be an issue if you are autowiring by name. * * 默认的实现是构建一个首字母小写(像变量同样的命名方式)的简短类名。 * 注意内部类所以会是这样的格式"outerClassName.InnerClassName" * 若是经过名称自动注入,中间的点就可能引起问题 */ protected String buildDefaultBeanName(BeanDefinition definition) { //cn.mrdear.exception.GlobalException => GlobalException String shortClassName = ClassUtils.getShortName(definition.getBeanClassName()); //此方法将字符串首字符大写转小写,可是若是第二个字符也是大写就不进行转换,由于他多是 //这样的格式--> "URL" return Introspector.decapitalize(shortClassName); }
跟踪标记2.4的方法
在ClassPathBeanDefinitionScanner类中实现
//2.4给beanDefinition设置默认值,自动注入的候选者 postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName); /** * Apply further settings to the given bean definition, * beyond the contents retrieved from scanning the component class. * * 除从组件class扫描检索的内容外,应用更多的设置到bean definition */ protected void postProcessBeanDefinition(AbstractBeanDefinition beanDefinition, String beanName) { //扫描器中的Defaults应用到beanDefinition中 beanDefinition.applyDefaults(this.beanDefinitionDefaults); if (this.autowireCandidatePatterns != null) { //设置自动注入候选者 beanDefinition.setAutowireCandidate(PatternMatchUtils.simpleMatch(this.autowireCandidatePatterns, beanName)); } }
跟踪标记2.5的方法
在AnnotationConfigUtils类中实现
//2.5拿到类上其余的context名称空间的注解,若是有的话,获取其value属性 AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate); public static void processCommonDefinitionAnnotations(AnnotatedBeanDefinition abd) { processCommonDefinitionAnnotations(abd, abd.getMetadata()); } static void processCommonDefinitionAnnotations(AnnotatedBeanDefinition abd, AnnotatedTypeMetadata metadata) { //类上是否有Lazy注解,或者注解的元注解上有Lazy注解 if (metadata.isAnnotated(Lazy.class.getName())) { //拿到@Lazy注解上的全部属性,获取其value属性的值 abd.setLazyInit(attributesFor(metadata, Lazy.class).getBoolean("value")); } //metadata不属于abd的状况 else if (abd.getMetadata() != metadata && abd.getMetadata().isAnnotated(Lazy.class.getName())) { abd.setLazyInit(attributesFor(abd.getMetadata(), Lazy.class).getBoolean("value")); } //类上是否有Primary注解,或者注解的元注解上有Primary注解 if (metadata.isAnnotated(Primary.class.getName())) { abd.setPrimary(true); } //类上是否有DependsOn注解,或者注解的元注解上有DependsOn注解 if (metadata.isAnnotated(DependsOn.class.getName())) { //拿到@DependsOn注解上的全部属性,获取其value属性的值 abd.setDependsOn(attributesFor(metadata, DependsOn.class).getStringArray("value")); } if (abd instanceof AbstractBeanDefinition) { AbstractBeanDefinition absBd = (AbstractBeanDefinition) abd; //类上是否有Role注解,或者注解的元注解上有Role注解 if (metadata.isAnnotated(Role.class.getName())) { //拿到@Role注解上的全部属性,获取其value属性的值 absBd.setRole(attributesFor(metadata, Role.class).getNumber("value").intValue()); } //类上是否有Description注解,或者注解的元注解上有Role注解 if (metadata.isAnnotated(Description.class.getName())) { //拿到@Description注解上的全部属性,获取其value属性的值 absBd.setDescription(attributesFor(metadata, Description.class).getString("value")); } } }
跟踪标记2.6的方法
在ClassPathBeanDefinitionScanner类中实现
//2.6检查beanName是否正确匹配对应的bean Definition,该名称是否已经被注册 checkCandidate(beanName, candidate) protected boolean checkCandidate(String beanName, BeanDefinition beanDefinition) throws IllegalStateException { //工厂中没有注册这个beanName,返回true if (!this.registry.containsBeanDefinition(beanName)) { return true; } BeanDefinition existingDef = this.registry.getBeanDefinition(beanName); BeanDefinition originatingDef = existingDef.getOriginatingBeanDefinition(); if (originatingDef != null) { existingDef = originatingDef; } //若是已存在的和入参的beanDefinition可以兼容,就返回false,不然抛出异常 if (isCompatible(beanDefinition, existingDef)) { return false; } throw new ConflictingBeanDefinitionException("Annotation-specified bean name '" + beanName + "' for bean class [" + beanDefinition.getBeanClassName() + "] conflicts with existing, " + "non-compatible bean definition of same name and class [" + existingDef.getBeanClassName() + "]"); }
跟踪标记3的方法
此方法在ComponentScanBeanDefinitionParser类中实现
// 3. 注册组件 registerComponents(parserContext.getReaderContext(), beanDefinitions, element); protected void registerComponents( XmlReaderContext readerContext, Set<BeanDefinitionHolder> beanDefinitions, Element element) { //这里返回的是null Object source = readerContext.extractSource(element); //拿到组合组件定义对象,以完整标签名作为name CompositeComponentDefinition compositeDef = new CompositeComponentDefinition(element.getTagName(), source); for (BeanDefinitionHolder beanDefHolder : beanDefinitions) { //分两部分看 //3.1bean组件定义的构造初始化 //将建立好的BeanComponentDefinition放入到组合组件定义的nestedComponents中 //nestedComponents是一个LinkedList compositeDef.addNestedComponent(new BeanComponentDefinition(beanDefHolder)); } // Register annotation config processors, if necessary. // 若是必要的话,注册注解配置处理器 boolean annotationConfig = true; //拿到component-scan标签的annotation-config属性 if (element.hasAttribute(ANNOTATION_CONFIG_ATTRIBUTE)) { //默认设置为true annotationConfig = Boolean.valueOf(element.getAttribute(ANNOTATION_CONFIG_ATTRIBUTE)); } if (annotationConfig) { //3.2查看怎么注册注解配置处理器 Set<BeanDefinitionHolder> processorDefinitions = AnnotationConfigUtils.registerAnnotationConfigProcessors(readerContext.getRegistry(), source); for (BeanDefinitionHolder processorDefinition : processorDefinitions) { //若是有为被注册的处理器,注册完成后再添加到组合组件定义中 compositeDef.addNestedComponent(new BeanComponentDefinition(processorDefinition)); } } //这里空实现 readerContext.fireComponentRegistered(compositeDef); }
跟踪标记3.1的方法
进入BeanComponentDefinition的构造方法
//3.1bean组件定义的构造初始化 new BeanComponentDefinition(beanDefHolder) public BeanComponentDefinition(BeanDefinitionHolder holder) { //先看父类构造作了什么操做 super(holder); //找到这个class中,属性为注册到工厂中的bean deifiniion或者BeanReference的集合 findInnerBeanDefinitionsAndBeanReferences(holder.getBeanDefinition()); } /** * 其实BeanComponentDefinition就是BeanDefinitionHolder的子类 * * Copy constructor: Create a new BeanDefinitionHolder with the * same contents as the given BeanDefinitionHolder instance. * <p>Note: The wrapped BeanDefinition reference is taken as-is; * it is {@code not} deeply copied. * * 复制构造:利用给定的beanDefinitionHolder实例,建立一个新的BeanDefinitionHolder */ public BeanDefinitionHolder(BeanDefinitionHolder beanDefinitionHolder) { Assert.notNull(beanDefinitionHolder, "BeanDefinitionHolder must not be null"); this.beanDefinition = beanDefinitionHolder.getBeanDefinition(); this.beanName = beanDefinitionHolder.getBeanName(); this.aliases = beanDefinitionHolder.getAliases(); }
而后再了解下findInnerBeanDefinitionsAndBeanReferences方法作了什么事情
private void findInnerBeanDefinitionsAndBeanReferences(BeanDefinition beanDefinition) { List<BeanDefinition> innerBeans = new ArrayList<BeanDefinition>(); List<BeanReference> references = new ArrayList<BeanReference>(); PropertyValues propertyValues = beanDefinition.getPropertyValues(); //拿到类中全部的属性值,若是属性为在bean工厂中注册的bean definition、或者 //有BeanReference--非实体bean只是逻辑上的引用,则放入集合 for (int i = 0; i < propertyValues.getPropertyValues().length; i++) { PropertyValue propertyValue = propertyValues.getPropertyValues()[i]; Object value = propertyValue.getValue(); if (value instanceof BeanDefinitionHolder) { innerBeans.add(((BeanDefinitionHolder) value).getBeanDefinition()); } else if (value instanceof BeanDefinition) { innerBeans.add((BeanDefinition) value); } else if (value instanceof BeanReference) { references.add((BeanReference) value); } } this.innerBeanDefinitions = innerBeans.toArray(new BeanDefinition[innerBeans.size()]); this.beanReferences = references.toArray(new BeanReference[references.size()]); }
跟踪标记3.2的方法
进入AnnotationConfigUtils的构造方法
//3.2查看怎么注册注解配置处理器 Set<BeanDefinitionHolder> processorDefinitions = AnnotationConfigUtils.registerAnnotationConfigProcessors(readerContext.getRegistry(), source); /** * Register all relevant annotation post processors in the given registry. * * 注册全部相关的注解后处理器到指定工厂中 */ public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors( BeanDefinitionRegistry registry, Object source) { DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry); if (beanFactory != null) { //bean工厂的依赖比较器不是AnnotationAwareOrderComparator的实例, //就换成AnnotationAwareOrderComparator if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) { beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE); } //bean工厂的自动注入候选解析器不是ContextAnnotationAutowireCandidateResolver的实例, //就换成ContextAnnotationAutowireCandidateResolver if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) { beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver()); } } Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<BeanDefinitionHolder>(4); //工厂中没有注册internalConfigurationAnnotationProcessor,则注册 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)); } //工厂中没有注册internalAutowiredAnnotationProcessor,则注册 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)); } //工厂中没有注册internalRequiredAnnotationProcessor,则注册 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. // 检查是否支持JSR-250,若是有则添加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. // 检查JPA支持,若是有则添加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)); } //工厂中没有注册internalEventListenerProcessor,则注册 if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) { RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class); def.setSource(source); beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME)); } //工厂中没有注册internalEventListenerFactory,则注册 if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) { RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class); def.setSource(source); beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME)); } return beanDefs; }
到这里也就跟踪完了。
其实还有不少种状况没有分析,只能先把握总体的脉络,遇到具体的状况再作具体分析。
context:component-scan
上的base-package
属性,有占位符的进行解析,并切分为数组形式——————————————————————————————————
Component
。context:exclude-filter
和context:exclude-filter
,根据子标签上的 type 属性建立不一样的类型过滤器。并添加到扫描器的 excludeFilters 属性或 includeFilters 属性中。——————————————————————————————————
base-package
,经过base-package
获取 Resource 对象数组,对符合条件的 Resource 组装成 BeanDefinition ,并将 BeanDefinition 集合返回。条件:不匹配 excludeFilters 中的过滤器,匹配 includeFilters 的过滤器的同时,若是有@Conditional
注解须要知足限制。@Scope
等注解以及元注解,设置属性——————————————————————————————————