spring源码解析(六):refresh()中obtainFreshBeanFactory()(3、parseCustomElement详解)

spring refresh()中obtainFreshBeanFactory()之parseCustomElement详解

本文在代码中模拟解析spring.xml中的<context:component-scan/>,其中spring.xml的配置如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
		http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
		http://www.springframework.org/schema/context 
		http://www.springframework.org/schema/context/spring-context-4.0.xsd">

	<!-- 自动扫描(自动注入),扫描这个包以及它的子包的所有使用注解标注的类 -->
	<context:component-scan base-package="com.chenyl.module.spring.model" />
</beans>  

在web.xml中配置信息如下:

  <!-- 配置 Spring -->
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:spring.xml</param-value>
  </context-param>

  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>

其中com.chenyl.module.spring.model包下:
在这里插入图片描述

Dog类内容如下:

@Component
public class Dog {

    public Dog(){
        System.out.println("Dog constructor...........");
    }

    public void init(){
        System.out.println("Dog init..........");
    }

    public void destroy(){
        System.out.println("Dog destroy..........");
    }
}

就上述例子,让我们探讨一下spring启动过程中parseCustomElement是如何解析<context:component-scan/>节点的。

一、parseBeanDefinitions():解析配置文件spring.xml

详细的流程上文已经说过,本次就直接进入到解析xml的地方:

tomcat启动–>
103 ContextLoaderListener.contextInitialized()–>
260 ContextLoader.initWebApplicationContext()–>
379 ContextLoader.configureAndRefreshWebApplicationContext()–>
516 AbstractApplicationContext.refresh()–>
620 AbstractApplicationContext.obtainFreshBeanFactory()–>
124 AbstractRefreshableApplicationContext.refreshBeanFactory()–>
81 XmlWebApplicationContext.loadBeanDefinitions()–>
121 XmlWebApplicationContext.loadBeanDefinitions()–>
193 AbstractBeanDefinitionReader.loadBeanDefinitions()–>
212 AbstractBeanDefinitionReader.loadBeanDefinitions()–>
183 AbstractBeanDefinitionReader.loadBeanDefinitions()–>
302 XmlBeanDefinitionReader.loadBeanDefinitions()–>
313 XmlBeanDefinitionReader.loadBeanDefinitions()–>
387 XmlBeanDefinitionReader.doLoadBeanDefinitions()–>
504 XmlBeanDefinitionReader.registerBeanDefinitions()–>
94 DefaultBeanDefinitionDocumentReader.registerBeanDefinitions()–>
122 DefaultBeanDefinitionDocumentReader.doRegisterBeanDefinitions()–>
167 DefaultBeanDefinitionDocumentReader.parseBeanDefinitions()

查看parseBeanDefinitions方法的详情:

protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
        //判断是否是默认命名空间
		if (delegate.isDefaultNamespace(root)) {
			NodeList nl = root.getChildNodes();
			for (int i = 0; i < nl.getLength(); i++) {
				Node node = nl.item(i);
				if (node instanceof Element) {
					Element ele = (Element) node;
					//bean、import、alias、beans节点的处理
					if (delegate.isDefaultNamespace(ele)) {
						parseDefaultElement(ele, delegate);
					}
					else {
					//自定义节点的处理,如:<context:component-scan/>、<aop:aspectj-autoproxy/>
						delegate.parseCustomElement(ele);
					}
				}
			}
		}
		else {
		    //自定义命名空间的处理
			delegate.parseCustomElement(root);
		}
	}

二、parseCustomElement():命名空间节点的解析

由上文发现命名空间有默认命名空间和自定义命名空间。
本文使用的是默认命名空间,且节点为<context:component-scan/>
读取节点context

因此进入到parseCustomElement方法中:

@Nullable
	public BeanDefinition parseCustomElement(Element ele, @Nullable BeanDefinition containingBd) {
	    // 1.拿到节点ele的命名空间,例如常见的:
        // <context> 节点对应命名空间: http://www.springframework.org/schema/context
        // <aop> 节点对应命名空间: http://www.springframework.org/schema/aop
		String namespaceUri = getNamespaceURI(ele);
		if (namespaceUri == null) {
			return null;
		}
		// 2.拿到命名空间对应的的handler, 例如:http://www.springframework.org/schema/context 对应 ContextNameSpaceHandler
        // 2.1 getNamespaceHandlerResolver: 拿到namespaceHandlerResolver
        // 2.2 resolve: 使用namespaceHandlerResolver解析namespaceUri, 拿到namespaceUri对应的NamespaceHandler
		NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri);
		if (handler == null) {
			error("Unable to locate Spring NamespaceHandler for XML schema namespace [" + namespaceUri + "]", ele);
			return null;
		}
		// 3.使用拿到的handler解析节点(ParserContext用于存放解析需要的一些上下文信息)
		return handler.parse(ele, new ParserContext(this.readerContext, this, containingBd));
	}

1. resolve()

该方法实现了四件事情:

  1. 获取配置文件中的所有命名空间对应的handler
  2. 根据当前命名空间获取对应handler名称
  3. 根据handler名称反射得到对应handler类
  4. 调用handler初始化方法,并把节点名和对应的解析器注册到缓存中
    
    @Override
	@Nullable
	public NamespaceHandler resolve(String namespaceUri) {
	    //1.获取配置文件中所有命名空间对应的handler
	    //例如:"http://www.springframework.org/schema/aop"->"org.springframework.aop.config.AopNamespaceHandler"
	    //例如:"http://www.springframework.org/schema/context->org.springframework.context.config.ContextNamespaceHandler
		Map<String, Object> handlerMappings = getHandlerMappings();
		
		//2.获取当前namespaceUri对应的handler名称
		//例如:org.springframework.context.config.ContextNamespaceHandler
		Object handlerOrClassName = handlerMappings.get(namespaceUri);
		if (handlerOrClassName == null) {
			return null;
		}
		else if (handlerOrClassName instanceof NamespaceHandler) {
			return (NamespaceHandler) handlerOrClassName;
		}
		else {
			String className = (String) handlerOrClassName;
			try {
			    //3.反射获取handler类
				Class<?> handlerClass = ClassUtils.forName(className, this.classLoader);
				if (!NamespaceHandler.class.isAssignableFrom(handlerClass)) {
					throw new FatalBeanException("Class [" + className + "] for namespace [" + namespaceUri +
							"] does not implement the [" + NamespaceHandler.class.getName() + "] interface");
				}
				//4.初始化NamespaceHandler
				NamespaceHandler namespaceHandler = (NamespaceHandler) BeanUtils.instantiateClass(handlerClass);
				namespaceHandler.init();
				handlerMappings.put(namespaceUri, namespaceHandler);
				return namespaceHandler;
			}
			catch (ClassNotFoundException ex) {
				throw new FatalBeanException("Could not find NamespaceHandler class [" + className +
						"] for namespace [" + namespaceUri + "]", ex);
			}
			catch (LinkageError err) {
				throw new FatalBeanException("Unresolvable class definition for NamespaceHandler class [" +
						className + "] for namespace [" + namespaceUri + "]", err);
			}
		}
	}

1.1、getHandlerMappings():获取配置文件中的所有命名空间对应的handler
private Map<String, Object> getHandlerMappings() {
		Map<String, Object> handlerMappings = this.handlerMappings;
		//1.如果handlerMappings已经加载过,则直接返回
		if (handlerMappings == null) {
			synchronized (this) {
				handlerMappings = this.handlerMappings;
				// 2.如果handlerMappings还没加载过,则进行加载
				if (handlerMappings == null) {
					try {
					    // 2.1 使用给定的类加载器从指定的类路径资源加载所有属性
						Properties mappings =
								PropertiesLoaderUtils.loadAllProperties(this.handlerMappingsLocation, this.classLoader);
						if (logger.isDebugEnabled()) {
							logger.debug("Loaded NamespaceHandler mappings: " + mappings);
						}
						Map<String, Object> mappingsToUse = new ConcurrentHashMap<>(mappings.size());
						// 2.2 将Properties转换成Map, mappings -> handlerMappings
						CollectionUtils.mergePropertiesIntoMap(mappings, mappingsToUse);
						// 2.3 将加载到的所有命名空间映射放到缓存
						handlerMappings = mappingsToUse;
						this.handlerMappings = handlerMappings;
					}
					catch (IOException ex) {
						throw new IllegalStateException(
								"Unable to load NamespaceHandler mappings from location [" + this.handlerMappingsLocation + "]", ex);
					}
				}
			}
		}
		return handlerMappings;
	}


1.2、命名空间不同节点指定不同的BeanDefinition解析器,并添加到缓存中

在resolve中根据namespaceUri反射得到的handler类,点击namespaceHandler.init()方法时,进入到对应handler类中的init()方法中。

我们可以看到有很多个实现类,分别对应了不同的命名空间 Handler,如下图:

image

例如:ContextNamespaceHandler类


public class ContextNamespaceHandler extends NamespaceHandlerSupport {

	@Override
	public void init() {
		registerBeanDefinitionParser("property-placeholder", new PropertyPlaceholderBeanDefinitionParser());
		registerBeanDefinitionParser("property-override", new PropertyOverrideBeanDefinitionParser());
		registerBeanDefinitionParser("annotation-config", new AnnotationConfigBeanDefinitionParser());
		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());
	}

}

例如:AopNamespaceHandler类

public class AopNamespaceHandler extends NamespaceHandlerSupport {
    public AopNamespaceHandler() {
    }

    public void init() {
        this.registerBeanDefinitionParser("config", new ConfigBeanDefinitionParser());
        this.registerBeanDefinitionParser("aspectj-autoproxy", new AspectJAutoProxyBeanDefinitionParser());
        this.registerBeanDefinitionDecorator("scoped-proxy", new ScopedProxyBeanDefinitionDecorator());
        this.registerBeanDefinitionParser("spring-configured", new SpringConfiguredBeanDefinitionParser());
    }
}

例如:CacheNamespaceHandler类

public class CacheNamespaceHandler extends NamespaceHandlerSupport {

	@Override
	public void init() {
		registerBeanDefinitionParser("annotation-driven", new AnnotationDrivenCacheBeanDefinitionParser());
		registerBeanDefinitionParser("advice", new CacheAdviceParser());
	}

}

等等,其的不一一列举。不过常用的还是ContextNamespaceHandler类。

这个方法的作用是把命名空间下的不同节点指定了不同的 BeanDefinition 解析器,并将节点名和对应的解析器注册到缓存中。

    
public abstract class NamespaceHandlerSupport implements NamespaceHandler {
    //节点名和对应的解析器的缓存map
    private final Map<String, BeanDefinitionParser> parsers = new HashMap<>();

	protected final void registerBeanDefinitionParser(String elementName, BeanDefinitionParser parser) {
		this.parsers.put(elementName, parser);
	}
	
}

其中parsers在下文中根据节点名获取对应的解析器时用到。

注册完成后断点调试发现如下图:

image

2. handler.parse():文件扫描器主方法

进入到handler.parse()中:

@Override
	@Nullable
	public BeanDefinition parse(Element element, ParserContext parserContext) {
	    //1.findParserForElement: 给element寻找对应的BeanDefinition解析器
        //2.使用BeanDefinition解析器解析element节点
		BeanDefinitionParser parser = findParserForElement(element, parserContext);
		return (parser != null ? parser.parse(element, parserContext) : null);
	}
	
	
	@Nullable
	private BeanDefinitionParser findParserForElement(Element element, ParserContext parserContext) {
		String localName = parserContext.getDelegate().getLocalName(element);
		//根据localName获取上文中resolve中缓存中的对象
		BeanDefinitionParser parser = this.parsers.get(localName);
		if (parser == null) {
			parserContext.getReaderContext().fatal(
					"Cannot locate BeanDefinitionParser for element [" + localName + "]", element);
		}
		return parser;
	}
2.1、findParserForElement():寻找对应BeanDefinition解析器

上面代码实现了根据节点的名称从this.parsers中获取到BeanDefinitionParser为ComponentScanBeanDefinitionParser对象。

在这里插入图片描述

2.2、parse():解析element节点

因此进入到parser.parse(element, parserContext)中是进入到:

在这里插入图片描述

进入到ComponentScanBeanDefinitionParser中,ComponentScanBeanDefinitionParser:文件扫描解析器

其中parse()方法主要实现了:

  1. 获取base-package包路径
  2. 创建扫描器
  3. 扫描包并注册beanDefinition
@Override
	@Nullable
	public BeanDefinition parse(Element element, ParserContext parserContext) {
	    // BASE_PACKAGE_ATTRIBUTE=“base-package”
	    //获取包的路径
		String basePackage = element.getAttribute(BASE_PACKAGE_ATTRIBUTE);
		basePackage = parserContext.getReaderContext().getEnvironment().resolvePlaceholders(basePackage);
		String[] basePackages = StringUtils.tokenizeToStringArray(basePackage,
				ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);

		// Actually scan for bean definitions and register them.
		//创建扫描器
		ClassPathBeanDefinitionScanner scanner = configureScanner(parserContext, element);
		//扫描包
		Set<BeanDefinitionHolder> beanDefinitions = scanner.doScan(basePackages);
		//注册其他注解组件
		registerComponents(parserContext.getReaderContext(), beanDefinitions, element);

		return null;
	}
2.2.1、获取base-package包路径

其中<context:component-scan/>中可填写的基础属性有:

private static final String BASE_PACKAGE_ATTRIBUTE = "base-package";

private static final String RESOURCE_PATTERN_ATTRIBUTE = "resource-pattern";

private static final String USE_DEFAULT_FILTERS_ATTRIBUTE = "use-default-filters";

private static final String ANNOTATION_CONFIG_ATTRIBUTE = "annotation-config";

private static final String NAME_GENERATOR_ATTRIBUTE = "name-generator";

private static final String SCOPE_RESOLVER_ATTRIBUTE = "scope-resolver";

private static final String SCOPED_PROXY_ATTRIBUTE = "scoped-proxy";

private static final String EXCLUDE_FILTER_ELEMENT = "exclude-filter";

private static final String INCLUDE_FILTER_ELEMENT = "include-filter";

private static final String FILTER_TYPE_ATTRIBUTE = "type";

private static final String FILTER_EXPRESSION_ATTRIBUTE = "expression";

本文中base-package路径为:“com.chenyl.module.spring.model”

2.2.2、configureScanner()创建扫描器
protected ClassPathBeanDefinitionScanner configureScanner(ParserContext parserContext, Element element) {
		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.
		ClassPathBeanDefinitionScanner scanner = createScanner(parserContext.getReaderContext(), useDefaultFilters);
		scanner.setBeanDefinitionDefaults(parserContext.getDelegate().getBeanDefinitionDefaults());
		scanner.setAutowireCandidatePatterns(parserContext.getDelegate().getAutowireCandidatePatterns());

		if (element.hasAttribute(RESOURCE_PATTERN_ATTRIBUTE)) {
			scanner.setResourcePattern(element.getAttribute(RESOURCE_PATTERN_ATTRIBUTE));
		}

		try {
			parseBeanNameGenerator(element, scanner);
		}
		catch (Exception ex) {
			parserContext.getReaderContext().error(ex.getMessage(), parserContext.extractSource(element), ex.getCause());
		}

		try {
			parseScope(element, scanner);
		}
		catch (Exception ex) {
			parserContext.getReaderContext().error(ex.getMessage(), parserContext.extractSource(element), ex.getCause());
		}

		parseTypeFilters(element, scanner, parserContext);

		return scanner;
	}
2.2.3、doScan()扫描包,注册beanDefinition
protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
		Assert.notEmpty(basePackages, "At least one base package must be specified");
		Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<>();
		for (String basePackage : basePackages) {
		    //1.遍历包名,获取到符合规则的类
			Set<BeanDefinition> candidates = findCandidateComponents(basePackage);
			for (BeanDefinition candidate : candidates) {
				ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);
				candidate.setScope(scopeMetadata.getScopeName());
				String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);
				if (candidate instanceof AbstractBeanDefinition) {
					postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);
				}
				if (candidate instanceof AnnotatedBeanDefinition) {
					AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);
				}
				if (checkCandidate(beanName, candidate)) {
					BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
					definitionHolder =
							AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
					beanDefinitions.add(definitionHolder);
					registerBeanDefinition(definitionHolder, this.registry);
				}
			}
		}
		return beanDefinitions;
	}

2.2.3.1、遍历包名,筛选符合条件的类

扫描basePackage路径下的所有类,并获取到符合规则的类存放到Set<BeanDefinition>中。

private Set<BeanDefinition> scanCandidateComponents(String basePackage) {
		Set<BeanDefinition> candidates = new LinkedHashSet<>();
		try {
		    //1.获取包扫描的路径,本文中为:classpath*:com/chenyl/module/spring/model/**/*.class
			String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +
					resolveBasePackage(basePackage) + '/' + this.resourcePattern;
			//2.根据路径获取资源数组,加载搜索路径下的所有class转换成Resource[]
			Resource[] resources = getResourcePatternResolver().getResources(packageSearchPath);
			boolean traceEnabled = logger.isTraceEnabled();
			boolean debugEnabled = logger.isDebugEnabled();
		    //3.遍历Resource
			for (Resource resource : resources) {
		
				if (traceEnabled) {
					logger.trace("Scanning " + resource);
				}
				if (resource.isReadable()) {
					try {
					    //4.读取类的注解信息和类信息,存储到metadataReader中
						MetadataReader metadataReader = getMetadataReaderFactory().getMetadataReader(resource);
						//5.校验该类是否符合扫描规则
						if (isCandidateComponent(metadataReader)) {
						    //6.把符合条件的类转换成BeanDefinition
							ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader);
							sbd.setResource(resource);
							sbd.setSource(resource);
							//如果是实体类 返回true,如果是抽象类,但是抽象方法 被 @Lookup 注解注释返回true 
							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);
								}
							}
						}
					...
			}
		}
		catch (IOException ex) {
			throw new BeanDefinitionStoreException("I/O failure during classpath scanning", ex);
		}
		return candidates;
	}

筛选条件:

	protected boolean isCandidateComponent(MetadataReader metadataReader) throws IOException {
		for (TypeFilter tf : this.excludeFilters) {
			if (tf.match(metadataReader, getMetadataReaderFactory())) {
				return false;
			}
		}
		for (TypeFilter tf : this.includeFilters) {
			if (tf.match(metadataReader, getMetadataReaderFactory())) {
				return isConditionMatch(metadataReader);
			}
		}
		return false;
	}
2.2.3.2、registerBeanDefinition():注册BeanDefinition
public static void registerBeanDefinition(
			BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
			throws BeanDefinitionStoreException {

		// Register bean definition under primary name.
		String beanName = definitionHolder.getBeanName();
		registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());

		// Register aliases for bean name, if any.
		String[] aliases = definitionHolder.getAliases();
		if (aliases != null) {
			for (String alias : aliases) {
				registry.registerAlias(beanName, alias);
			}
		}
	}

此时的beanDefinitionMap中:

在这里插入图片描述

2.2.4、registerComponents():注册其他注解组件
protected void registerComponents(
			XmlReaderContext readerContext, Set<BeanDefinitionHolder> beanDefinitions, Element element) {

		Object source = readerContext.extractSource(element);
		//包装为CompositeComponentDefinition对象,内置多ComponentDefinition对象
		CompositeComponentDefinition compositeDef = new CompositeComponentDefinition(element.getTagName(), source);
        //将已注册的所有beanDefinitionHolder对象放到上述对象中
		for (BeanDefinitionHolder beanDefHolder : beanDefinitions) {
			compositeDef.addNestedComponent(new BeanComponentDefinition(beanDefHolder));
		}

		// Register annotation config processors, if necessary.
		boolean annotationConfig = true;
		//获取annotation-config的属性值,默认为true
		if (element.hasAttribute(ANNOTATION_CONFIG_ATTRIBUTE)) {
			annotationConfig = Boolean.valueOf(element.getAttribute(ANNOTATION_CONFIG_ATTRIBUTE));
		}
		if (annotationConfig) {
		    //注册多个BeanPostProcessor接口,返回的是包含BeanPostProcessor接口的beanDefinitionHolder对象集合
			Set<BeanDefinitionHolder> processorDefinitions =
				AnnotationConfigUtils.registerAnnotationConfigProcessors(readerContext.getRegistry(), source);
			//继续装入CompositeComponentDefinition对象
			for (BeanDefinitionHolder processorDefinition : processorDefinitions) {
				compositeDef.addNestedComponent(new BeanComponentDefinition(processorDefinition));
			}
		}

		readerContext.fireComponentRegistered(compositeDef);
	}

注册其他注解组件,直接查看注册方法:

public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
			BeanDefinitionRegistry registry, @Nullable 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<>(4);

		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));
		}

		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));
		}

		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));
		}

		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));
		}
		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;
	}

该方法主要是注册多个BeanPostProcessor接口实现类,供后续spring调用统一接口进行解析。

注册的都有:

  • org.springframework.context.annotation.internalConfigurationAnnotationProcessor
  • org.springframework.context.event.internalEventListenerFactory
  • org.springframework.context.event.internalEventListenerProcessor
  • org.springframework.context.annotation.internalAutowiredAnnotationProcessor
  • org.springframework.context.annotation.internalCommonAnnotationProcessor
  • org.springframework.context.annotation.internalRequiredAnnotationProcessor

在这里插入图片描述

此处的目的主要是注册多个BeanPostProcessor接口实现类:

  • ConfigurationClassPostProcessor解析@Configuration注解类
  • AutowiredAnnotationBeanPostProcessor解析@Autowired/@Value注解
  • RequiredAnnotationBeanPostProcessor解析@Required注解
  • CommonAnnotationBeanPostProcessor解析@Resource注解
  • PersistenceAnnotationBeanPostProcessor解析JPA注解,持久层
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值