目录
ComponentScanBeanDefinitionParser.parse
代码块10:postProcessBeanDefinition
代码块11:processCommonDefinitionAnnotations
代码块17:registerAnnotationConfigProcessors
Spring IoC源码学习全系列
Spring IoC源码学习:ApplicationContext 刷新前的配置
Spring IoC源码学习:obtainFreshBeanFactory详解
Spring IoC源码学习:parseDefaultElement详解
Spring IoC源码学习:parseCustomElement详解
Spring IoC源码学习:context:component-scan节点详解
Spring IoC源码学习:invokeBeanFactoryPostProcessors详解
Spring IoC源码学习:registerBeanPostProcessors详解
Spring IoC源码学习:finishBeanFactoryInitialization详解
Spring IoC源码学习:createBean详解(上)
Spring IoC源码学习:createBean详解(下)
Spring IoC源码学习:finishRefresh详解
在Spring IoC:parseCustomElement详解中,我们介绍了自定义命名空间节点解析的大部分内容,但是还剩下节点解析的具体过程。本文将以<context:component-scan /> 节点为例子,介绍自定义命名空间 context 的 component-scan 节点的解析过程。
首先,我们回到Spring IoC:parseCustomElement详解中的代码块5:NamespaceHandlerSupport.parse方法,代码如下。
@Override public BeanDefinition parse(Element element, ParserContext parserContext) { // 1.findParserForElement: 给element寻找对应的BeanDefinition解析器 // 2.使用BeanDefinition解析器解析element节点 return findParserForElement(element, parserContext).parse(element, parserContext); }
当 element 为 <context:component-scan /> 节点时,findParserForElement(element, parserContext) 会返回 ComponentScanBeanDefinitionParser,接着执行 ComponentScanBeanDefinitionParser.parse 方法。
ComponentScanBeanDefinitionParser.parse
@Override public BeanDefinition parse(Element element, ParserContext parserContext) { // 1.拿到<context:component-scan>节点的base-package属性值 String basePackage = element.getAttribute(BASE_PACKAGE_ATTRIBUTE); // 2.解析占位符, 例如 ${basePackage} basePackage = parserContext.getReaderContext().getEnvironment().resolvePlaceholders(basePackage); // 3.解析base-package(允许通过 ",; \t\n" 中的任一符号填写多个),例如: com.joonwhee.open.one;com.joonwhee.open.two String[] basePackages = StringUtils.tokenizeToStringArray(basePackage, ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS); // Actually scan for bean definitions and register them. // 4.构建和配置ClassPathBeanDefinitionScanner ClassPathBeanDefinitionScanner scanner = configureScanner(parserContext, element); // 5.使用scanner在指定的basePackages包中执行扫描,返回已注册的bean定义 Set<BeanDefinitionHolder> beanDefinitions = scanner.doScan(basePackages); // 6.组件注册(包括注册一些内部的注解后置处理器、触发注册事件) registerComponents(parserContext.getReaderContext(), beanDefinitions, element); return null; }
4.构建和配置 ClassPathBeanDefinitionScanner,见代码块1详解。
5.使用 scanner 在指定的 basePackages 包中执行扫描,返回已注册的 BeanDefinitionHolder,见代码块5详解。
6.组件注册,见代码块16详解。
protected ClassPathBeanDefinitionScanner configureScanner(ParserContext parserContext, Element element) { // 1.解析use-default-filters属性,默认为true,用于指示是否使用默认的filter 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. // 2.构建ClassPathBeanDefinitionScanner,将bean定义注册委托给scanner类 ClassPathBeanDefinitionScanner scanner = createScanner(parserContext.getReaderContext(), useDefaultFilters); scanner.setBeanDefinitionDefaults(parserContext.getDelegate().getBeanDefinitionDefaults()); scanner.setAutowireCandidatePatterns(parserContext.getDelegate().getAutowireCandidatePatterns()); // 3.解析resource-pattern属性 if (element.hasAttribute(RESOURCE_PATTERN_ATTRIBUTE)) { scanner.setResourcePattern(element.getAttribute(RESOURCE_PATTERN_ATTRIBUTE)); } try { // 4.解析name-generator属性 parseBeanNameGenerator(element, scanner); } catch (Exception ex) { parserContext.getReaderContext().error(ex.getMessage(), parserContext.extractSource(element), ex.getCause()); } try { // 5.解析scope-resolver、scoped-proxy属性 parseScope(element, scanner); } catch (Exception ex) { parserContext.getReaderContext().error(ex.getMessage(), parserContext.extractSource(element), ex.getCause()); } // 6.解析类型过滤器 parseTypeFilters(element, scanner, parserContext); return scanner; }
2.构建 ClassPathBeanDefinitionScanner,见代码块2详解。
6.解析类型过滤器,见代码块4详解。
protected ClassPathBeanDefinitionScanner createScanner(XmlReaderContext readerContext, boolean useDefaultFilters) { return new ClassPathBeanDefinitionScanner(readerContext.getRegistry(), useDefaultFilters, readerContext.getEnvironment(), readerContext.getResourceLoader()); } // ClassPathBeanDefinitionScanner.java public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters, Environment environment, ResourceLoader resourceLoader) { Assert.notNull(registry, "BeanDefinitionRegistry must not be null"); this.registry = registry; if (useDefaultFilters) { // 1.注册默认的filter registerDefaultFilters(); } setEnvironment(environment); setResourceLoader(resourceLoader); }
1.注册默认的 filter,见代码块3详解。
protected void registerDefaultFilters() { // 1.添加@Component注解Filter到includeFilters中 this.includeFilters.add(new AnnotationTypeFilter(Component.class)); ClassLoader cl = ClassPathScanningCandidateComponentProvider.class.getClassLoader(); try { // 2.添加@ManagedBean注解Filter到includeFilters中 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 { // 3.添加@Named注解Filter到includeFilters中,这边会抛ClassNotFoundException 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. } }
这边会尝试添加3个AnnotationTypeFilter 到 includeFilters 中,但是默认情况下,添加 @Named 注解对应的 AnnotationTypeFilter 时会抛异常。因此,执行完该方法,includeFilters 会有两个 AnnotationTypeFilter,分别对应@Component 注解和 @ManagedBean 注解,如下图所示。
protected void parseTypeFilters(Element element, ClassPathBeanDefinitionScanner scanner, ParserContext parserContext) { // Parse exclude and include filter elements. ClassLoader classLoader = scanner.getResourceLoader().getClassLoader(); NodeList nodeList = element.getChildNodes(); // 1.遍历解析element下的所有子节点 for (int i = 0; i < nodeList.getLength(); i++) { Node node = nodeList.item(i); if (node.getNodeType() == Node.ELEMENT_NODE) { // 拿到节点的localName // 例如节点:<context:exclude-filter type="" expression=""/>,localName为:exclude-filter String localName = parserContext.getDelegate().getLocalName(node); try { /** * 例如 * <context:component-scan base-package="com.joonwhee.open"> * <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/> * </context:component-scan> */ // 2.解析include-filter子节点 if (INCLUDE_FILTER_ELEMENT.equals(localName)) { // 2.1 构建TypeFilter TypeFilter typeFilter = createTypeFilter((Element) node, classLoader, parserContext); // 2.2 添加到scanner的includeFilters属性 scanner.addIncludeFilter(typeFilter); } // 3.解析exclude-filter子节点 else if (EXCLUDE_FILTER_ELEMENT.equals(localName)) { // 3.1 构建TypeFilter TypeFilter typeFilter = createTypeFilter((Element) node, classLoader, parserContext); // 3.2 添加到scanner的excludeFilters属性 scanner.addExcludeFilter(typeFilter); } } catch (Exception ex) { parserContext.getReaderContext().error( ex.getMessage(), parserContext.extractSource(element), ex.getCause()); } } } } protected TypeFilter createTypeFilter(Element element, ClassLoader classLoader, ParserContext parserContext) { // 1.获取type、expression String filterType = element.getAttribute(FILTER_TYPE_ATTRIBUTE); String expression = element.getAttribute(FILTER_EXPRESSION_ATTRIBUTE); expression = parserContext.getReaderContext().getEnvironment().resolvePlaceholders(expression); try { // 2.根据filterType,返回对应的TypeFilter,例如annotation返回AnnotationTypeFilter if ("annotation".equals(filterType)) { // 2.1 指定过滤的注解, expression为注解的类全名称, 例如: org.springframework.stereotype.Controller return new AnnotationTypeFilter((Class<Annotation>) classLoader.loadClass(expression)); } else if ("assignable".equals(filterType)) { // 2.2 指定过滤的类或接口, 包括子类和子接口, expression为类全名称 return new AssignableTypeFilter(classLoader.loadClass(expression)); } else if ("aspectj".equals(filterType)) { // 2.3 指定aspectj表达式来过滤类, expression为aspectj表达式字符串 return new AspectJTypeFilter(expression, classLoader); } else if ("regex".equals(filterType)) { // 2.4 通过正则表达式来过滤类, expression为正则表达式字符串 return new RegexPatternTypeFilter(Pattern.compile(expression)); } else if ("custom".equals(filterType)) { // 2.5 用户自定义过滤器类型, expression为自定义过滤器的类全名称 Class<?> filterClass = classLoader.loadClass(expression); // 自定义的过滤器必须实现TypeFilter接口, 否则抛异常 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); } }
举个例子:
我们知道,当我们配置了 component-scan 时,Spring会去扫描 base-package 下所有使用了@Component(包括@Controller、@Repository、@Service)注解的bean。这是因为 use-default-filters 属性默认值为 true,而通过代码块3我们知道,use-default-filters = true 时,includeFilters 会有两个AnnotationTypeFilter,分别对应 @Component 注解和@ManagedBean 注解。
如果我们想排除掉使用了 @Controller 注解的 bean 时,就可以使用exclude-filter 属性,例如以下配置。
<context:component-scan base-package="com.joonwhee.open.demo"> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/> </context:component-scan>
protected Set<BeanDefinitionHolder> doScan(String... basePackages) { Assert.notEmpty(basePackages, "At least one base package must be specified"); Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<BeanDefinitionHolder>(); // 1.遍历basePackages for (String basePackage : basePackages) { // 2.扫描basePackage,将符合要求的bean定义全部找出来(这边符合要求最常见的就是使用Component注解) Set<BeanDefinition> candidates = findCandidateComponents(basePackage); // 3.遍历所有候选的bean定义 for (BeanDefinition candidate : candidates) { // 4.解析@Scope注解, 包括scopeName(默认为singleton,常见的还有prototype), 和proxyMode(默认不使用代理, 可选接口代理/类代理) ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate); candidate.setScope(scopeMetadata.getScopeName()); // 5.使用beanName生成器来生成beanName String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry); if (candidate instanceof AbstractBeanDefinition) { // 6.进一步处理BeanDefinition对象,比如: 此bean是否可以自动装配到其他bean中 postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName); } if (candidate instanceof AnnotatedBeanDefinition) { // 7.处理定义在目标类上的通用注解,包括@Lazy, @Primary, @DependsOn, @Role, @Description AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate); } // 8.检查beanName是否已经注册过,如果注册过,检查是否兼容 if (checkCandidate(beanName, candidate)) { // 9.将当前遍历bean的 bean定义和beanName封装成BeanDefinitionHolder BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName); // 10.根据proxyMode的值(步骤4中解析), 选择是否创建作用域代理 definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry); beanDefinitions.add(definitionHolder); // 11.注册BeanDefinition(注册到beanDefinitionMap、beanDefinitionNames、aliasMap缓存) registerBeanDefinition(definitionHolder, this.registry); } } } return beanDefinitions; }
2.扫描 basePackage,将符合要求的 bean 定义全部找出来,见代码块6详解。
4.解析 @Scope 注解,见代码块9详解。
6.进一步处理 BeanDefinition 对象,见代码块10详解。
7.处理定义在目标类上的通用注解,见代码块11详解。
8.检查 beanName 是否已经注册过,如果注册过,检查是否兼容,见代码块12详解。
10.根据 proxyMode 的值(步骤4中解析了该属性),选择是否创建作用域代理,见代码块13详解。
11.注册 BeanDefinition,见代码块15详解。
public Set<BeanDefinition> findCandidateComponents(String basePackage) { Set<BeanDefinition> candidates = new LinkedHashSet<BeanDefinition>(); try { // 1.根据我们配置的包名,组装成要扫描的通配包路径,例如:com.joonwhee.open 会被组装成: classpath*:com/joonwhee/open/**/*.class String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX + resolveBasePackage(basePackage) + '/' + this.resourcePattern; // 2.根据通配包路径匹配拿到所有匹配的类资源(本项目依赖的jar,如果路径也符合,则会一起扫描进来) Resource[] resources = this.resourcePatternResolver.getResources(packageSearchPath); boolean traceEnabled = logger.isTraceEnabled(); boolean debugEnabled = logger.isDebugEnabled(); // 3.遍历所有匹配的类资源 for (Resource resource : resources) { if (traceEnabled) { logger.trace("Scanning " + resource); } if (resource.isReadable()) { try { // 4.使用metadataReader读取资源,MetadataReader是专门用来访问元数据的类(包括: 类元数据ClassMetadata、注解元数据AnnotationMetadata等) MetadataReader metadataReader = this.metadataReaderFactory.getMetadataReader(resource); // 5.使用过滤器检查给定的类是否为候选类(候选类: 与excludeFilters的所有Filter不匹配,并且与includeFilters的至少一个Filter匹配) if (isCandidateComponent(metadataReader)) { ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader); sbd.setResource(resource); sbd.setSource(resource); // 6.判断sbd是否为候选类(独立的 && (具体的实现类 || (抽象类 && 类中有方法使用@Lookup注解))) if (isCandidateComponent(sbd)) { if (debugEnabled) { logger.debug("Identified candidate component class: " + resource); } // 7.确定是候选类,则添加到candidates 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; }
5.使用过滤器检查给定的类是否为候选类,见代码块7详解。
6.判断 sbd 是否为候选类,步骤5是使用过滤器进行检查,而本方法则是单纯的校验候选者类,见代码块8详解。
protected boolean isCandidateComponent(MetadataReader metadataReader) throws IOException { for (TypeFilter tf : this.excludeFilters) { if (tf.match(metadataReader, this.metadataReaderFactory)) { // 如果metadataReader与excludeFilters中的任意一个匹配,则返回false,表示metadataReader对应的类不是候选者类 return false; } } // includeFilters默认包含: org.springframework.stereotype.Component注解、javax.annotation.ManagedBean注解 for (TypeFilter tf : this.includeFilters) { if (tf.match(metadataReader, this.metadataReaderFactory)) { // 如果metadataReader与includeFilters中的任意一个TypeFilter匹配(如果tf为Component注解:metadataReader对应的类使用了Component则匹配), // 则判断@Conditional注解是否匹配(@Conditional基本不用,此处不深入解析);如果匹配,则返回true,表示metadataReader对应的类为候选者类 return isConditionMatch(metadataReader); } } return false; }
这边的excludeFilters 和 includeFilters 在上面的代码块3、代码块4中已经介绍过。默认情况下excludeFilters 为空,includeFilters 包含:@Component 注解的TypeFilter、@ManagedBean 注解的 TypeFilter。
因此,在正常情况下,使用了 @Component(包括被 @Component 修饰的@Controller、@Repository、@Service)注解的类在这边会返回 true,表示该类是候选者类。
protected boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) { AnnotationMetadata metadata = beanDefinition.getMetadata(); // isIndependent:确定底层类是否是独立的,即它是否是顶级类或嵌套类(静态内部类),它可以独立于封闭类构造。 // isConcrete:返回底层类是表示具体类,即:既不是接口也不是抽象类。 // isAbstract:返回底层类是否标记为抽象。 // hasAnnotatedMethods:确定基础类是否具有使用给定注解(@Lookup)类型进行注解(或元注解)的任何方法。 return (metadata.isIndependent() && (metadata.isConcrete() || (metadata.isAbstract() && metadata.hasAnnotatedMethods(Lookup.class.getName())))); }
正常使用,在前两个条件校验完就会返回 true,不会走到后面两个条件。
@Override public ScopeMetadata resolveScopeMetadata(BeanDefinition definition) { ScopeMetadata metadata = new ScopeMetadata(); if (definition instanceof AnnotatedBeanDefinition) { AnnotatedBeanDefinition annDef = (AnnotatedBeanDefinition) definition; AnnotationAttributes attributes = AnnotationConfigUtils.attributesFor( annDef.getMetadata(), this.scopeAnnotationType); // 如果使用了@Scope注解 if (attributes != null) { // 解析scopeName属性 metadata.setScopeName(attributes.getString("value")); // 解析proxyMode属性 ScopedProxyMode proxyMode = attributes.getEnum("proxyMode"); if (proxyMode == null || proxyMode == ScopedProxyMode.DEFAULT) { proxyMode = this.defaultProxyMode; } metadata.setScopedProxyMode(proxyMode); } } return metadata; }
如果使用了@Scope注解,则解析注解的属性。这边的 defaultProxyMode 取决于代码块1中步骤5的 scope-resolver、scoped-proxy属性,默认为 ScopedProxyMode.NO。可以通过 scoped-proxy 来设置,例如下面配置 defaultProxyMode 的值就为ScopedProxyMode.TARGET_CLASS。
<context:component-scan base-package="com.joonwhee.open.demo" scoped-proxy="targetClass"> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/> </context:component-scan>
代码块10:postProcessBeanDefinition
protected void postProcessBeanDefinition(AbstractBeanDefinition beanDefinition, String beanName) { // 给beanDefinition设置默认值 beanDefinition.applyDefaults(this.beanDefinitionDefaults); if (this.autowireCandidatePatterns != null) { // 设置此bean是否可以自动装配到其他bean中, 默认为true beanDefinition.setAutowireCandidate(PatternMatchUtils.simpleMatch(this.autowireCandidatePatterns, beanName)); } }
代码块11:processCommonDefinitionAnnotations
public static void processCommonDefinitionAnnotations(AnnotatedBeanDefinition abd) { processCommonDefinitionAnnotations(abd, abd.getMetadata()); } static void processCommonDefinitionAnnotations(AnnotatedBeanDefinition abd, AnnotatedTypeMetadata metadata) { // 解析@Lazy注解, 设置是否延迟加载 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")); } // 解析@Primary注解, 自动装配时当出现多个Bean都匹配时,被注解为@Primary的Bean将作为首选者,否则将抛出异常 // (场景较小, 如果可能出现多个匹配者时, 可以使用@Autowired @Qualifier的组合) if (metadata.isAnnotated(Primary.class.getName())) { abd.setPrimary(true); } // 解析@DependOn注解 if (metadata.isAnnotated(DependsOn.class.getName())) { abd.setDependsOn(attributesFor(metadata, DependsOn.class).getStringArray("value")); } if (abd instanceof AbstractBeanDefinition) { // 解析@Role注解 AbstractBeanDefinition absBd = (AbstractBeanDefinition) abd; if (metadata.isAnnotated(Role.class.getName())) { absBd.setRole(attributesFor(metadata, Role.class).getNumber("value").intValue()); } // 解析@Description注解 if (metadata.isAnnotated(Description.class.getName())) { absBd.setDescription(attributesFor(metadata, Description.class).getString("value")); } } }
protected boolean checkCandidate(String beanName, BeanDefinition beanDefinition) throws IllegalStateException { // 1.如果该注册表(beanDefinitionMap缓存)没有包含beanName, 则返回true,代表可以注册该bean定义 if (!this.registry.containsBeanDefinition(beanName)) { return true; } // 2.如果注册表中包含beanName // 2.1拿到注册表中该beanName的BeanDefinition BeanDefinition existingDef = this.registry.getBeanDefinition(beanName); // 2.2拿到原始BeanDefinition(使用了代理的BeanDefinition会有原始BeanDefinition) BeanDefinition originatingDef = existingDef.getOriginatingBeanDefinition(); if (originatingDef != null) { // 2.3如果有原始BeanDefinition, 则使用原始BeanDefinition existingDef = originatingDef; } // 3.检查新BeanDefinition是否与原BeanDefinition兼容,如果兼容则返回false,跳过注册 if (isCompatible(beanDefinition, existingDef)) { return false; } // 4.如果不兼容,则抛异常 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() + "]"); }
static BeanDefinitionHolder applyScopedProxyMode( ScopeMetadata metadata, BeanDefinitionHolder definition, BeanDefinitionRegistry registry) { ScopedProxyMode scopedProxyMode = metadata.getScopedProxyMode(); // 1.如果不需要创建代理,则直接返回bean定义 if (scopedProxyMode.equals(ScopedProxyMode.NO)) { return definition; } // 2.判断是使用基于类的代理还是基于接口的代码, 基于类: 使用CGLIB代理, 基于接口: 使用JDK动态代理 boolean proxyTargetClass = scopedProxyMode.equals(ScopedProxyMode.TARGET_CLASS); // 3.使用相应的代理模式, 创建一个scope代理 return ScopedProxyCreator.createScopedProxy(definition, registry, proxyTargetClass); }
3.使用相应的代理模式,创建一个 scope 代理,见代码块14详解。
public static BeanDefinitionHolder createScopedProxy( BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry, boolean proxyTargetClass) { return ScopedProxyUtils.createScopedProxy(definitionHolder, registry, proxyTargetClass); } public static BeanDefinitionHolder createScopedProxy(BeanDefinitionHolder definition, BeanDefinitionRegistry registry, boolean proxyTargetClass) { // 拿到原始bean的beanName String originalBeanName = definition.getBeanName(); // 拿到原始bean的BeanDefinition BeanDefinition targetDefinition = definition.getBeanDefinition(); // 为原始bean生成了一个新的beanName(加了个前缀: scopedTarget.) String targetBeanName = getTargetBeanName(originalBeanName); // Create a scoped proxy definition for the original bean name, // "hiding" the target bean in an internal target definition. // 使用ScopedProxyFactoryBean作为beanClass创建代理BeanDefinition RootBeanDefinition proxyDefinition = new RootBeanDefinition(ScopedProxyFactoryBean.class); // 将原始bean封装成BeanDefinitionHolder,设置到代理的decoratedDefinition属性 proxyDefinition.setDecoratedDefinition(new BeanDefinitionHolder(targetDefinition, targetBeanName)); // 设置代理的原始BeanDefinition属性值 proxyDefinition.setOriginatingBeanDefinition(targetDefinition); proxyDefinition.setSource(definition.getSource()); proxyDefinition.setRole(targetDefinition.getRole()); proxyDefinition.getPropertyValues().add("targetBeanName", targetBeanName); if (proxyTargetClass) { // 根据类做代理, proxyTargetClass属性默认为true,因此我们不需要在此处设置它 targetDefinition.setAttribute(AutoProxyUtils.PRESERVE_TARGET_CLASS_ATTRIBUTE, Boolean.TRUE); // ScopedProxyFactoryBean's "proxyTargetClass" default is TRUE, so we don't need to set it explicitly here. } else { // 根据接口做代理, 设置proxyTargetClass属性值为false proxyDefinition.getPropertyValues().add("proxyTargetClass", Boolean.FALSE); } // Copy autowire settings from original bean definition. // 从原始bean定义复制autowire设置 proxyDefinition.setAutowireCandidate(targetDefinition.isAutowireCandidate()); proxyDefinition.setPrimary(targetDefinition.isPrimary()); if (targetDefinition instanceof AbstractBeanDefinition) { proxyDefinition.copyQualifiersFrom((AbstractBeanDefinition) targetDefinition); } // The target bean should be ignored in favor of the scoped proxy. // 隐藏原始的bean targetDefinition.setAutowireCandidate(false); targetDefinition.setPrimary(false); // Register the target bean as separate bean in the factory. // 注册原始bean的BeanDefinition registry.registerBeanDefinition(targetBeanName, targetDefinition); // Return the scoped proxy definition as primary bean definition // (potentially an inner bean). // 将代理bean封装成BeanDefinitionHolder对象并返回 return new BeanDefinitionHolder(proxyDefinition, originalBeanName, definition.getAliases()); }
protected void registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) { // 调用BeanDefinitionReaderUtils工具类来完成BeanDefinition的注册 BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, registry); }
调用BeanDefinitionReaderUtils 工具类来完成 BeanDefinition 的注册,该方法在Spring IoC:parseDefaultElement详解中的代码块13已经解析过。
protected void registerComponents( XmlReaderContext readerContext, Set<BeanDefinitionHolder> beanDefinitions, Element element) { Object source = readerContext.extractSource(element); // 1.使用注解的tagName(例如: context:component-scan)和source 构建CompositeComponentDefinition CompositeComponentDefinition compositeDef = new CompositeComponentDefinition(element.getTagName(), source); // 2.将扫描到的所有BeanDefinition添加到compositeDef的nestedComponents属性中 for (BeanDefinitionHolder beanDefHolder : beanDefinitions) { compositeDef.addNestedComponent(new BeanComponentDefinition(beanDefHolder)); } // Register annotation config processors, if necessary. boolean annotationConfig = true; if (element.hasAttribute(ANNOTATION_CONFIG_ATTRIBUTE)) { // 3.获取component-scan标签的annotation-config属性值(默认为true) annotationConfig = Boolean.valueOf(element.getAttribute(ANNOTATION_CONFIG_ATTRIBUTE)); } if (annotationConfig) { // 4.如果annotation-config属性值为true,在给定的注册表中注册所有用于注解的Bean后置处理器 Set<BeanDefinitionHolder> processorDefinitions = AnnotationConfigUtils.registerAnnotationConfigProcessors(readerContext.getRegistry(), source); for (BeanDefinitionHolder processorDefinition : processorDefinitions) { // 5.将注册的注解后置处理器的BeanDefinition添加到compositeDef的nestedComponents属性中 compositeDef.addNestedComponent(new BeanComponentDefinition(processorDefinition)); } } // 6.触发组件注册事件,默认实现为EmptyReaderEventListener(空实现,没有具体操作) readerContext.fireComponentRegistered(compositeDef); }
4.在给定的注册表中注册所有用于注解的bean 后置处理器,见代码块17详解。
代码块17:registerAnnotationConfigProcessors
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors( BeanDefinitionRegistry registry, Object source) { DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry); if (beanFactory != null) { if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) { // 1.设置dependencyComparator属性 beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE); } if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) { // 2.设置autowireCandidateResolver属性(设置自动注入候选对象的解析器,用于判断BeanDefinition是否为候选对象) beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver()); } } Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<BeanDefinitionHolder>(4); // 3.注册内部管理的用于处理@Configuration注解的后置处理器的bean if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) { RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class); def.setSource(source); // 3.1 registerPostProcessor: 注册BeanDefinition到注册表中 beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)); } // 4.注册内部管理的用于处理@Autowired、@Value、@Inject以及@Lookup注解的后置处理器的bean 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)); } // 5.注册内部管理的用于处理@Required注解的后置处理器的bean 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)); } // 6.注册内部管理的用于处理JSR-250注解(例如@Resource, @PostConstruct, @PreDestroy)的后置处理器的bean // 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)); } // 7.注册内部管理的用于处理JPA注解的后置处理器的bean // 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)); } // 8.注册内部管理的用于处理@EventListener注解的后置处理器的bean 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)); } // 9.注册内部管理用于生产ApplicationListener对象的EventListenerFactory对象 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; }
3.1 注册后置处理器的 BeanDefinition 到注册表中,见代码块18详解。
private static BeanDefinitionHolder registerPostProcessor( BeanDefinitionRegistry registry, RootBeanDefinition definition, String beanName) { // 1.设置role definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); // 2.注册BeanDefinition registry.registerBeanDefinition(beanName, definition); // 3.封装成BeanDefinitionHolder并返回 return new BeanDefinitionHolder(definition, beanName); }
2.注册 BeanDefinition,该方法会走到 DefaultListableBeanFactory.registerBeanDefinition 方法,该方法在Spring IoC:parseDefaultElement详解中的代码块14已经解析过。
至此,<context:component-scan>节点解析已经完成,主要做的事情有:
1. 扫描 base-package 目录,将使用了@Component、@Controller、@Repository、@Service注解的 bean 注册到注册表中(其实就是beanDefinitionMap、beanDefinitionNames、aliasMap缓存中),跟之前解析默认命名空间一样,也是在后续创建 bean 时需要使用这些缓存。
2. 添加了几个内部的注解相关的后置处理器:ConfigurationClassPostProcessor、AutowiredAnnotationBeanPostProcessor、RequiredAnnotationBeanPostProcessor等。
同时,本文的结束,也标志着 obtainFreshBeanFactory 方法的详解正式结束。
简单来说,有以下几个主要操作:
1. 根据 web.xml 中 contextConfigLocation 配置的路径,读取 Spring 配置文件,并封装成 Resource。
2. 根据 Resource 加载XML 配置文件,并解析成 Document 对象。
3. 拿到 Document 中的根节点,遍历根节点和所有子节点。
4. 根据命名空间,进行不同的解析,将 bean 节点内容解析成BeanDefinition。
5. 将 BeanDefinition 注册到注册表中(也就是beanDefinitionMap、beanDefinitionNames、aliasMap缓存)。
执行完obtainFreshBeanFactory 方法,我们得到了三个重要的对象:
· 新的 BeanFactory。
· beanDefinitionNames 缓存。
· beanDefinitionMap 缓存。
这三个对象在之后的 IoC 构建过程中会发挥重要的作用。