对于解析注解、XML标签的实现类,我们只需要大概了解一下结构,并且知道是什么时候调用的即可; 解析调用流程(1)
ClassPathXmlApplicationContext继承了 AbstractXmlApplicationContext
XmlBeanDefinitionReader是第一个解关卡
public abstract class AbstractXmlApplicationContext extends AbstractRefreshableConfigApplicationContext { protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException { /* XmlBeanDefinitionReader 是专用于解析我们配置文件的解析器 */ XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory); beanDefinitionReader.setEnvironment(this.getEnvironment()); beanDefinitionReader.setResourceLoader(this); beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this)); initBeanDefinitionReader(beanDefinitionReader); loadBeanDefinitions(beanDefinitionReader); } }解析调用流程(2)
AbstractRefreshableApplicationContext是一个集成了很多容器刷新回调的父类 在容器处理流程中调用 其中有一项loadBeanDefinitions在这里被调用了
public abstract class AbstractRefreshableApplicationContext extends AbstractApplicationContext { protected final void refreshBeanFactory() throws BeansException { if (hasBeanFactory()) { destroyBeans(); closeBeanFactory(); } try { DefaultListableBeanFactory beanFactory = createBeanFactory(); beanFactory.setSerializationId(getId()); customizeBeanFactory(beanFactory); loadBeanDefinitions(beanFactory); this.beanFactory = beanFactory; } catch (IOException ex) { throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex); } } }知道了什么时候被调用,我们就来看看XmlBeanDefinitionReader解析后的最终文件最终去往何处
首先利用doLoadDocument将指定文件实例化成内存数据对象Document 然后调用registerBeanDefinitions去解析这个内存对象
protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource) throws BeanDefinitionStoreException { try { Document doc = doLoadDocument(inputSource, resource); int count = registerBeanDefinitions(doc, resource); …… return count; } }BeanDefinitionDocumentReader第二个解析管卡
registerBeanDefinitions,用户可以通过重写createBeanDefinitionDocumentReader自定义解析规则 显然这里是利用默认的读取器:DefaultBeanDefinitionDocumentReader
public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException { BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader(); int countBefore = getRegistry().getBeanDefinitionCount(); documentReader.registerBeanDefinitions(doc, createReaderContext(resource)); return getRegistry().getBeanDefinitionCount() - countBefore; }DefaultBeanDefinitionDocumentReader 根据类型解析
public class DefaultBeanDefinitionDocumentReader{ /* 内置了很多标签的静态变量 */ public static final String NESTED_BEANS_ELEMENT = "beans"; public static final String ALIAS_ELEMENT = "alias"; public static final String NAME_ATTRIBUTE = "name"; public static final String ALIAS_ATTRIBUTE = "alias"; public static final String IMPORT_ELEMENT = "import"; public static final String RESOURCE_ATTRIBUTE = "resource"; public static final String PROFILE_ATTRIBUTE = "profile"; 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); /* 根据node类型决定解析 */ if (node instanceof Element) { Element ele = (Element) node; if (delegate.isDefaultNamespace(ele)) { parseDefaultElement(ele, delegate); } else { delegate.parseCustomElement(ele); } } } } else { delegate.parseCustomElement(root); } } /* 这块显然用了上面的静态变量,根据不同常量解析,我们主要Bean的解析 processBeanDefinition */ private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) { if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) { importBeanDefinitionResource(ele); } else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) { processAliasRegistration(ele); } else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) { processBeanDefinition(ele, delegate); } else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) { // recurse doRegisterBeanDefinitions(ele); } }BeanDefinitionReaderUtils将bean解析信息注入注册中心 这个工具类的作用是将bean的信息注入给注册中心 BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry())
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) { …… BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry()); } } public static void registerBeanDefinition( BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) throws BeanDefinitionStoreException { /* 选择原始名注册bean */ String beanName = definitionHolder.getBeanName(); registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition()); /* 然后用别名注册 */ String[] aliases = definitionHolder.getAliases(); if (aliases != null) { for (String alias : aliases) { registry.registerAlias(beanName, alias); } } } }注册中心的传入
/* AbstractXmlApplicationContext的loadBeanDefinitions 传入了默认的beanFactory,这个beanFactory实现了bean的BeanDefinitionRegistry */ public abstract class AbstractXmlApplicationContext extends AbstractRefreshableConfigApplicationContext { protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException { XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory); beanDefinitionReader.setEnvironment(this.getEnvironment()); beanDefinitionReader.setResourceLoader(this); beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this)); initBeanDefinitionReader(beanDefinitionReader); loadBeanDefinitions(beanDefinitionReader); } } /* 由XmlBeanDefinitionReader实现AbstractBeanDefinitionReader 注册中心实际上是先保存在AbstractBeanDefinitionReader 中 */ public class XmlBeanDefinitionReader extends AbstractBeanDefinitionReader { public XmlBeanDefinitionReader(BeanDefinitionRegistry registry) { super(registry); } } public abstract class AbstractBeanDefinitionReader implements BeanDefinitionReader, EnvironmentCapable { protected AbstractBeanDefinitionReader(BeanDefinitionRegistry registry) { Assert.notNull(registry, "BeanDefinitionRegistry must not be null"); this.registry = registry; if (this.registry instanceof ResourceLoader) { this.resourceLoader = (ResourceLoader) this.registry; } else { this.resourceLoader = new PathMatchingResourcePatternResolver(); } if (this.registry instanceof EnvironmentCapable) { this.environment = ((EnvironmentCapable) this.registry).getEnvironment(); } else { this.environment = new StandardEnvironment(); } } }注册中心的保存
/* 为了调用更加方便,需要对外暴露的数据,全部用context提供访问 所以创建了XmlReaderContext来访问XmlBeanDefinitionReader中的数据 */ public class XmlBeanDefinitionReader extends AbstractBeanDefinitionReader { public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException { BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader(); int countBefore = getRegistry().getBeanDefinitionCount(); documentReader.registerBeanDefinitions(doc, createReaderContext(resource)); return getRegistry().getBeanDefinitionCount() - countBefore; } } /* 比如注册中心就是如此 */ public class XmlReaderContext extends ReaderContext { public XmlReaderContext( Resource resource, ProblemReporter problemReporter, ReaderEventListener eventListener, SourceExtractor sourceExtractor, XmlBeanDefinitionReader reader, NamespaceHandlerResolver namespaceHandlerResolver) { super(resource, problemReporter, eventListener, sourceExtractor); this.reader = reader; this.namespaceHandlerResolver = namespaceHandlerResolver; } public final BeanDefinitionRegistry getRegistry() { return this.reader.getRegistry(); } }Ps:自此我们的XML解析流程告一段落,我们将在后面详细讲解注册中心
在这里类上按CTRL+T
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) { /* @创建了两个解析器 */ AnnotatedBeanDefinitionReader reader = getAnnotatedBeanDefinitionReader(beanFactory); ClassPathBeanDefinitionScanner scanner = getClassPathBeanDefinitionScanner(beanFactory); /* @创建beanNameGenerator ,解析bean名字注解的处理器; 就说依据注解信息或者类的名字作为bean的引用id的一系列封装 */ BeanNameGenerator beanNameGenerator = getBeanNameGenerator(); if (beanNameGenerator != null) { reader.setBeanNameGenerator(beanNameGenerator); scanner.setBeanNameGenerator(beanNameGenerator); beanFactory.registerSingleton(AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR, beanNameGenerator); } /* @创建ScopeMetadataResolver ,解析作用于注解的处理器 */ ScopeMetadataResolver scopeMetadataResolver = getScopeMetadataResolver(); if (scopeMetadataResolver != null) { reader.setScopeMetadataResolver(scopeMetadataResolver); scanner.setScopeMetadataResolver(scopeMetadataResolver); } /* AnnotationConfigApplicationContext的componentClasses构造器模式 */ if (!this.componentClasses.isEmpty()) { if (logger.isDebugEnabled()) { logger.debug("Registering component classes: [" + StringUtils.collectionToCommaDelimitedString(this.componentClasses) + "]"); } reader.register(ClassUtils.toClassArray(this.componentClasses)); } /* AnnotationConfigApplicationContext的basePackages扫包模式 指定路径扫包 */ if (!this.basePackages.isEmpty()) { if (logger.isDebugEnabled()) { logger.debug("Scanning base packages: [" + StringUtils.collectionToCommaDelimitedString(this.basePackages) + "]"); } scanner.scan(StringUtils.toStringArray(this.basePackages)); } /* @扫XML模式 */ String[] configLocations = getConfigLocations(); if (configLocations != null) { for (String configLocation : configLocations) { try { Class<?> clazz = ClassUtils.forName(configLocation, getClassLoader()); if (logger.isTraceEnabled()) { logger.trace("Registering [" + configLocation + "]"); } reader.register(clazz); } catch (ClassNotFoundException ex) { if (logger.isTraceEnabled()) { logger.trace("Could not load class for config location [" + configLocation + "] - trying package scan. " + ex); } int count = scanner.scan(configLocation); if (count == 0 && logger.isDebugEnabled()) { logger.debug("No component classes found for specified class/package [" + configLocation + "]"); } } } } }AnnotatedBeanDefinitionReader实例化,注册一些内置的beanPostProccer
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) { Assert.notNull(registry, "BeanDefinitionRegistry must not be null"); Assert.notNull(environment, "Environment must not be null"); this.registry = registry; this.conditionEvaluator = new ConditionEvaluator(registry, environment, null); AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry); } 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()); } } /* 然后这些需要提交创建的bean先封装成RootBeanDefinition 其中包括 ConfigurationClassPostProcessor AutowiredAnnotationBeanPostProcessor CommonAnnotationBeanPostProcessor EventListenerMethodProcessor DefaultEventListenerFactory …… */ Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8); 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)); } // 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; }XML解析
(1)解析器创建阶段:XmlBeanDefinitionReader、BeanDefinitionDocumentReader是XML解析的两个核心类;在AbstractXmlApplicationContext阶段就创建出来了 (2)解析器解析阶段:AbstractRefreshableApplicationContext是一个刷新的回调集成类,在这里调用reader的loadBeanDefinitions (3)数据保存:为了统一访问XmlBeanDefinitionReader的注册中心等内容,提供了XmlReaderContext来 (4)解析实现:DefaultBeanDefinitionDocumentReader,这个内置了大量标签对应的解析方式,最终数据利用XmlReaderContext找到beanFatory,调用BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry()),将数据集成到了beanFatory的beanDefinitionMap里面;
注解解析
(1)AnnotationConfigApplicationContext有很多的构造器,扫包或者核心配置类、或者configLocation都可以创建ioc的上下文; (2)AnnotationConfig核心在于内置了大量的beanPostProcesser先提交创建成rootBean,在后置处理器中去实现一些ioc必要完成的功能; 这些谜题只能在后续陆续接开