Spring是一个分层架构,主要包含以下部分
1、Core Container
核心容器,包含Core、Beans、Context和Expression Language(EL表达式)模块。Core和Beans是基础部分,提供IoC(控制反转)和DI(依赖注入),提供对工厂模式的经典实现来消除对程序单例模式的需求,并通过xml的配置和代码解耦
2、Data Access
数据访问相关,包含JDBC、ORM、OXM、JMS 和 Transaction模块
3、Web
4、AOP
5、Test
因为Spring可以使用xml完成容器和Bean的相关配置,先看最基本的获取XmlBeanFactory类型的实例
// XmlBeanFactory 继承 BeanFactory BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("beanFactory.xml"));
bean是Spring中最核心的东西,beans包下的两个核心类
Spring版本5.2.12下BeanFactory接口下继承体系
XmlBeanFactory实现了DefaultListableBeanFactory,在此基础上增加了XmlBeanDefinitionReader类型的成员变量reader
用于对xml配置文件读取
1、先看new ClassPathResource("beanFactory.xml")
的构造,ClassPathResource的getInputStream()方法是利用ClassLoader的getResourceAsStream(path)得到InputStream进而转化为Resource
// package org.springframework.core.io; // public class ClassPathResource extends AbstractFileResolvingResource public InputStream getInputStream() throws IOException { InputStream is; if (this.clazz != null) { is = this.clazz.getResourceAsStream(this.path); } else if (this.classLoader != null) { is = this.classLoader.getResourceAsStream(this.path); } else { is = ClassLoader.getSystemResourceAsStream(this.path); } if (is == null) { throw new FileNotFoundException(this.getDescription() + " cannot be opened because it does not exist"); } else { return is; } }
1、回到XmlBeanFactory的构造方法new XmlBeanFactory(new ClassPathResource("beanFactory.xml"));
/** @deprecated */ // 因为使用的是SpringBoot源码分析,因此已经被标注过时 @Deprecated public class XmlBeanFactory extends DefaultListableBeanFactory { private final XmlBeanDefinitionReader reader; public XmlBeanFactory(Resource resource) throws BeansException { this(resource, (BeanFactory)null); } public XmlBeanFactory(Resource resource, BeanFactory parentBeanFactory) throws BeansException { // 1、调用父类 AbstractAutowireCapableBeanFactory 的构造方法 super(parentBeanFactory); // 2、 创建reader实例 this.reader = new XmlBeanDefinitionReader(this); // 3、开始解析Resource this.reader.loadBeanDefinitions(resource); } }
1.1、调用父类 AbstractAutowireCapableBeanFactory 的构造方法
public AbstractAutowireCapableBeanFactory() { this.instantiationStrategy = new CglibSubclassingInstantiationStrategy(); this.parameterNameDiscoverer = new DefaultParameterNameDiscoverer(); this.allowCircularReferences = true; this.allowRawInjectionDespiteWrapping = false; this.ignoredDependencyTypes = new HashSet(); this.ignoredDependencyInterfaces = new HashSet(); this.currentlyCreatedBean = new NamedThreadLocal("Currently created bean"); this.factoryBeanInstanceCache = new ConcurrentHashMap(); this.factoryMethodCandidateCache = new ConcurrentHashMap(); this.filteredPropertyDescriptorsCache = new ConcurrentHashMap(); // 忽略给定接口的自动转配,Bean、BeanFactory、BeanClassloader可以通过实现下面3个接口的时候进行相应Bean的注入 //当其他Bean的属性包含上面情况的Bean的时候,上面情况的Bean不会因为依赖注入被自动初始化 this.ignoreDependencyInterface(BeanNameAware.class); this.ignoreDependencyInterface(BeanFactoryAware.class); this.ignoreDependencyInterface(BeanClassLoaderAware.class); }
1.2、创建XmlBeanDefinitionReader类型的reader实例
1.3、关键逻辑就在this.reader.loadBeanDefinitions(resource);
进入XmlBeanDefinitionReader先进行加载XML文档和解析Bean前的准备
doLoadBeanDefinitions方法主要做了三件事
// XmlBeanDefinitionReader#doLoadBeanDefinitions() protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource) throws BeanDefinitionStoreException { try { // 1、获取Document Document doc = this.doLoadDocument(inputSource, resource); // 2、调用 registerBeanDefinitions 注册BeanDefinitions int count = this.registerBeanDefinitions(doc, resource); if (this.logger.isDebugEnabled()) { this.logger.debug("Loaded " + count + " bean definitions from " + resource); } return count; } catch (BeanDefinitionStoreException var5) { throw var5; } catch (SAXParseException var6) { throw new XmlBeanDefinitionStoreException(resource.getDescription(), "Line " + var6.getLineNumber() + " in XML document from " + resource + " is invalid", var6); } catch (SAXException var7) { throw new XmlBeanDefinitionStoreException(resource.getDescription(), "XML document from " + resource + " is invalid", var7); } catch (ParserConfigurationException var8) { throw new BeanDefinitionStoreException(resource.getDescription(), "Parser configuration exception parsing XML from " + resource, var8); } catch (IOException var9) { throw new BeanDefinitionStoreException(resource.getDescription(), "IOException parsing XML document from " + resource, var9); } catch (Throwable var10) { throw new BeanDefinitionStoreException(resource.getDescription(), "Unexpected exception parsing XML document from " + resource, var10); } }
// 1、获取Document
// 1、委托DocumentLoader转化Document,实际实现子类是DefaultDocumentLoader // DefaultDocumentLoader#loadDocument() //EntityResolver 作用:提供一个本地查找DTD的方法,避免网络查找。主要还是用作验证 public Document loadDocument(InputSource inputSource, EntityResolver entityResolver, ErrorHandler errorHandler, int validationMode, boolean namespaceAware) throws Exception { DocumentBuilderFactory factory = this.createDocumentBuilderFactory(validationMode, namespaceAware); if (logger.isTraceEnabled()) { logger.trace("Using JAXP provider [" + factory.getClass().getName() + "]"); } DocumentBuilder builder = this.createDocumentBuilder(factory, entityResolver, errorHandler); return builder.parse(inputSource); }
// 2、调用 registerBeanDefinitions 注册BeanDefinitions
// 2、 BeanDefinitionDocumentReader 拿着Document进行BeanDefinitions注册 public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException { BeanDefinitionDocumentReader documentReader = this.createBeanDefinitionDocumentReader(); int countBefore = this.getRegistry().getBeanDefinitionCount(); documentReader.registerBeanDefinitions(doc, this.createReaderContext(resource)); return this.getRegistry().getBeanDefinitionCount() - countBefore; } // 实际调用的是DefaultBeanDefinitionDocumentReader#registerBeanDefinitions() public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) { this.readerContext = readerContext; this.doRegisterBeanDefinitions(doc.getDocumentElement()); } protected void doRegisterBeanDefinitions(Element root) { // 专门处理解析 BeanDefinitionParserDelegate parent = this.delegate; this.delegate = this.createDelegate(this.getReaderContext(), root, parent); if (this.delegate.isDefaultNamespace(root)) { // 处理profile属性,如一个xml可以设置激活dev、prod等配置环境 String profileSpec = root.getAttribute("profile"); if (StringUtils.hasText(profileSpec)) { String[] specifiedProfiles = StringUtils.tokenizeToStringArray(profileSpec, ",; "); if (!this.getReaderContext().getEnvironment().acceptsProfiles(specifiedProfiles)) { if (this.logger.isDebugEnabled()) { this.logger.debug("Skipped XML bean definition file due to specified profiles [" + profileSpec + "] not matching: " + this.getReaderContext().getResource()); } return; } } } // 解析前处理,留给子类实现 this.preProcessXml(root); // 解析 this.parseBeanDefinitions(root, this.delegate); // 解析后处理,留给子类实现 this.postProcessXml(root); this.delegate = parent; }
// 3、解析 parseBeanDefinitions(root, this.delegate);
protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) { // 对beans的处理 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; if (delegate.isDefaultNamespace(ele)) { // 对bean的处理:对于跟标签和子标签是默认命名空间,如<bean> this.parseDefaultElement(ele, delegate); } else { // 对bean的处理:对自定义命名空间的标签解析,如<tx:annotation-driven/> delegate.parseCustomElement(ele); } } } } else { delegate.parseCustomElement(root); } }
下一部分:对XML文件标签的解析