spring-mvc源碼-bean定義加載-非默認標籤解析(context:annotation-config)

接上篇:bean定義加載整體流程:https://blog.csdn.net/matt8/article/details/106352083

看下非默認標籤的解析過程,以<context:annotation-config/>這個標籤爲例。

非默認標籤的解析,是通過org.springframework.beans.factory.xml.BeanDefinitionParserDelegate#parseCustomElement(org.w3c.dom.Element)這個方法實現的,這個方法直接調用的自己的parseCustomElement(ele, null)這個方法,源碼如下:

	public BeanDefinition parseCustomElement(Element ele, BeanDefinition containingBd) {
		//獲取非默認標籤Namespace,這裏是http://www.springframework.org/schema/context
		String namespaceUri = getNamespaceURI(ele);
		//獲取解析非默認標籤的處理器,在每個jar包的META-INF/spring.handlers這個文件裏有命名空間和處理器類的對應關係,通過這種方式,我們也可以自定義標籤
		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));
	}

這裏的處理器拿到的是ContextNamespaceHandler處理器,標籤解析調用的是它的父類的方法org.springframework.beans.factory.xml.NamespaceHandlerSupport#parse,源碼如下:

public BeanDefinition parse(Element element, ParserContext parserContext) {
		return findParserForElement(element, parserContext).parse(element, parserContext);
	}	

這裏會先查找解析器,解析器是在創建處理器對象時初始化進去的,也就是ContextNamespaceHandler處理器的init()方法設置的,這裏的findParserForElement()方法會根據名字拿到對應的解析器,名字就是annotation-config,得到的解析器對象是AnnotationConfigBeanDefinitionParser解析器,最終的解析工作是這個解析器完成的。

看下解析的代碼,org.springframework.context.annotation.AnnotationConfigBeanDefinitionParser#parse方法:

	@Override
	public BeanDefinition parse(Element element, ParserContext parserContext) {
		Object source = parserContext.extractSource(element);

		//這裏將註冊獲取到所有相關BeanPostProcessors的bean定義
		Set<BeanDefinitionHolder> processorDefinitions =
				AnnotationConfigUtils.registerAnnotationConfigProcessors(parserContext.getRegistry(), source);

		// Register component for the surrounding <context:annotation-config> element.
		CompositeComponentDefinition compDefinition = new CompositeComponentDefinition(element.getTagName(), source);
		parserContext.pushContainingComponent(compDefinition);

		// Nest the concrete beans in the surrounding component.
		for (BeanDefinitionHolder processorDefinition : processorDefinitions) {
			parserContext.registerComponent(new BeanComponentDefinition(processorDefinition));
		}

		// Finally register the composite component.
		parserContext.popAndRegisterContainingComponent();

		return null;
	}

主要看下AnnotationConfigUtils.registerAnnotationConfigProcessors()方法,源碼如下:

	public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
			BeanDefinitionRegistry registry, Object source) {

		DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
		if (beanFactory != null) {
			if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
				beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
			}
			if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
				beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
			}
		}

		Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<BeanDefinitionHolder>(4);

		//註冊ConfigurationClassPostProcessor後置處理器,對應 @Configuration
		if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
		}

		//註冊AutowiredAnnotationBeanPostProcessor後置處理器,對應 @AutoWired
		if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
		}

		//註冊RequiredAnnotationBeanPostProcessor後置處理器,對應 @Required
		if (!registry.containsBeanDefinition(REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition(RequiredAnnotationBeanPostProcessor.class);
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
		}

		// spring還支持基於JSR-250的註解,註冊CommonAnnotationBeanPostProcessor後置處理器,其中包括@PostConstruct,@PreDestroy和@Resource註解
		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));
		}

		//JPA中的註解,註冊PersistenceAnnotationBeanPostProcessor後置處理器,對應 @PersistenceContext 這裏是不支持的
		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));
		}

		//註冊EventListenerMethodProcessor後置處理器,對應 @EventListener
		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;
	}

<context:annotation-config/>這個標籤的解析就完成了。

這裏要注意:<context:annotation-config />僅能夠在已經在已經註冊過的bean上面起作用,對於沒有在spring容器中註冊的bean,它並不能執行任何操作。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章