博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
SpringIoc
阅读量:4189 次
发布时间:2019-05-26

本文共 96291 字,大约阅读时间需要 320 分钟。

SpringIoc

ClassPathXmlApplicationContext实例化,也意味这SpringIOC 容器启动完成。

new一个ClassPathXmlApplicationContext实例。

ClassPathXmlApplicationContext classPathXmlApplicationContext =                new ClassPathXmlApplicationContext("classpath:spring.xml");

跟进代码,最终会调用ClassPathXmlApplicationContext的如下构造函数。代码如下:

public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, @Nullable ApplicationContext parent) throws BeansException {        super(parent);        this.setConfigLocations(configLocations);        if (refresh) {            this.refresh();        }    }

跟进代码,上面的this.setConfigLocations(configLocations);这个代码最终回调用类PropertyPlaceholderHelper的parseStringValue,源码如下:

protected String parseStringValue(String value, PropertyPlaceholderHelper.PlaceholderResolver placeholderResolver, Set
visitedPlaceholders) { StringBuilder result = new StringBuilder(value); int startIndex = value.indexOf(this.placeholderPrefix); while(startIndex != -1) { int endIndex = this.findPlaceholderEndIndex(result, startIndex); if (endIndex != -1) { String placeholder = result.substring(startIndex + this.placeholderPrefix.length(), endIndex); String originalPlaceholder = placeholder; if (!visitedPlaceholders.add(placeholder)) { throw new IllegalArgumentException("Circular placeholder reference '" + placeholder + "' in property definitions"); } placeholder = this.parseStringValue(placeholder, placeholderResolver, visitedPlaceholders); String propVal = placeholderResolver.resolvePlaceholder(placeholder); if (propVal == null && this.valueSeparator != null) { int separatorIndex = placeholder.indexOf(this.valueSeparator); if (separatorIndex != -1) { String actualPlaceholder = placeholder.substring(0, separatorIndex); String defaultValue = placeholder.substring(separatorIndex + this.valueSeparator.length()); propVal = placeholderResolver.resolvePlaceholder(actualPlaceholder); if (propVal == null) { propVal = defaultValue; } } } if (propVal != null) { propVal = this.parseStringValue(propVal, placeholderResolver, visitedPlaceholders); result.replace(startIndex, endIndex + this.placeholderSuffix.length(), propVal); if (logger.isTraceEnabled()) { logger.trace("Resolved placeholder '" + placeholder + "'"); } startIndex = result.indexOf(this.placeholderPrefix, startIndex + propVal.length()); } else { if (!this.ignoreUnresolvablePlaceholders) { throw new IllegalArgumentException("Could not resolve placeholder '" + placeholder + "' in value \"" + value + "\""); } startIndex = result.indexOf(this.placeholderPrefix, endIndex + this.placeholderSuffix.length()); } visitedPlaceholders.remove(originalPlaceholder); } else { startIndex = -1; } } return result.toString(); }

PropertyPlaceholderHelper的parseStringValue方法主要干什么呢?

将字符串里的占位符内容,用我们配置的properties里的替换。这个是一个单纯的类,没有继承没有实现,而且也没简单,没有依赖Spring框架其他的任何类。个人感觉自己项目中可以拿来模仿用。

跟进代码 最后走到了fresh();

if (refresh) {            this.refresh();       }

默认refresh是true,这个可以自行跟踪代码去认证。接下来看下refresh()改函数。

跟进代码,来到了AbstractApplicationContext的refresh()方法。看如下源码:

public void refresh() throws BeansException, IllegalStateException {        Object var1 = this.startupShutdownMonitor;        synchronized(this.startupShutdownMonitor) {            this.prepareRefresh();            ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();            this.prepareBeanFactory(beanFactory);            try {                this.postProcessBeanFactory(beanFactory);                this.invokeBeanFactoryPostProcessors(beanFactory);                this.registerBeanPostProcessors(beanFactory);                this.initMessageSource();                this.initApplicationEventMulticaster();                this.onRefresh();                this.registerListeners();                this.finishBeanFactoryInitialization(beanFactory);                this.finishRefresh();            } catch (BeansException var9) {                if (this.logger.isWarnEnabled()) {                    this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);                }                this.destroyBeans();                this.cancelRefresh(var9);                throw var9;            } finally {                this.resetCommonCaches();            }        }    }

好想感觉这个方法很简单,其实很负责了,只不过其主干代码比较清晰,因为改方法里面调用了很多其他方法。现在一个一个方法的来分析。

跟进代码 prepareRefresh() 方法, 准备Context的刷新

protected void prepareRefresh() {        this.startupDate = System.currentTimeMillis();        this.closed.set(false);        this.active.set(true);        if (this.logger.isInfoEnabled()) {            this.logger.info("Refreshing " + this);        }        this.initPropertySources();        this.getEnvironment().validateRequiredProperties();        this.earlyApplicationEvents = new LinkedHashSet();    }

prepareRefresh() 主要干了什么呢?

  1. initPropertySources,在应用启动之前替换一些属性占位符,这个方法再Spring的对象中一般都没有实现,应该是用来方便我们后期扩展使用的方法。
  2. validateRequiredProperties,Environment类的方法验证必须的属性是否正确
  3. 初始化事件集合。

跟进 this.getEnvironment().validateRequiredProperties() 是怎样验证属性的正确性。这个方法最终会调用AbstractPropertyResolver.validateRequiredProperties()方法。

public void validateRequiredProperties() {        MissingRequiredPropertiesException ex = new MissingRequiredPropertiesException();        Iterator var2 = this.requiredProperties.iterator();        while(var2.hasNext()) {            String key = (String)var2.next();            if (this.getProperty(key) == null) {                ex.addMissingRequiredProperty(key);            }        }        if (!ex.getMissingRequiredProperties().isEmpty()) {            throw ex;        }    }

AbstractPropertyResolver.validateRequiredProperties() 方法验证必填的属性。如果必填的属性没有填值,那么就会抛出异常。

跟进ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory(); 看看源码

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {        this.refreshBeanFactory();        ConfigurableListableBeanFactory beanFactory = this.getBeanFactory();        if (this.logger.isDebugEnabled()) {            this.logger.debug("Bean factory for " + this.getDisplayName() + ": " + beanFactory);        }        return beanFactory;    }

这个方法看着挺简单,然而是非常负责的,这个方法干了很多事情。我看它的返回值,最后返回了一个beanFactory.

接下来,继续跟进,this.refreshBeanFactory()方法,看看它干了什么,源码如下:它在AbstractApplicationContext里面是一个抽象方法,需要子类去实现。跟踪代码,最后是由AbstractRefreshApplicationContext类实现了,refreshBeanFactory()方法。看看具体源码是怎样处理刷新。

protected final void refreshBeanFactory() throws BeansException {        if (this.hasBeanFactory()) {            this.destroyBeans();            this.closeBeanFactory();        }        try {            DefaultListableBeanFactory beanFactory = this.createBeanFactory();            beanFactory.setSerializationId(this.getId());            this.customizeBeanFactory(beanFactory);            this.loadBeanDefinitions(beanFactory);            Object var2 = this.beanFactoryMonitor;            synchronized(this.beanFactoryMonitor) {                this.beanFactory = beanFactory;            }        } catch (IOException var5) {            throw new ApplicationContextException("I/O error parsing bean definition source for " + this.getDisplayName(), var5);        }    }

refreshBeanFactory() 方法主要干了什么呢?

  1. hasBeanFactory,判断context目前是否持有bean factory,如果有:先执行一个模版方法,销毁这个context管理的所有bean,默认实现销毁所有context中的单例缓存,调用DisposableBean.destroy()和/或特定的"destroy-method";再closeBeanFactory,即设置beanFactory的id为null,beanFactory为null。
  2. 然后,createBeanFactory,为context创建一个internal bean factory。每次refresh()都会被调用,默认实现创建一个以context的getInternalParentBeanFactory()-parent为parent bean factory的org.springframework.beans.factory.support.DefaultListableBeanFactory,子类可以重写此方法来自定义DefaultListableBeanFactory的设置。跟踪源码父bean工厂为NULL。
  3. 为新建的工厂设置一个唯一的系列化值。
  4. 定之化bean工厂,customizeBeanFactory,自定义beanFactory。自定义context的nternal bean factory,每次refresh()都会被调用,默认实现设置了context的setAllowBeanDefinitionOverriding "allowBeanDefinitionOverriding"以及setAllowCircularReferences “allowCircularReferences”,子类可以重写此方法来自定义DefaultListableBeanFactory的设置。
  5. 加载BeanDefinitions.

跟进 this.loadBeanDefinitions(beanFactory); 方法。发现这个方法在AbstractRefreshApplicationContext类里面是一个抽象方法,由他的子类去实现,跟踪定位,发现由AbstractXmlApplicationContext 进行实现的,源码如下:

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));        this.initBeanDefinitionReader(beanDefinitionReader);        this.loadBeanDefinitions(beanDefinitionReader);    }

接下来看看 loadBeanDefinitions(DefaultListableBeanFactory beanFactory) 主要干了什么事情。

  1. 创建一个XmlBeanDefinitionReader,这个类的选择和 AbstractXmlApplicationContext 对应。
  2. 设置当前的environment的对象。
  3. 设置对应的ResourceLoader。 ApplicationContext是ResourceLoader的子类。
  4. 设置 reader的属性validateing,设置是否使用xml验证。缺省是true。
  5. 加载对应的BeanDefinitionReader对象。

接下来跟进this.loadBeanDefinitions(beanDefinitionReader),

protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {        Resource[] configResources = this.getConfigResources();        if (configResources != null) {            reader.loadBeanDefinitions(configResources);        }        String[] configLocations = this.getConfigLocations();        if (configLocations != null) {            reader.loadBeanDefinitions(configLocations);        }    }

loadBeanDefinitions 改方法干了什么?其实这里与ClassPathXmlApplicationContext构造函数有关,构造函数可以通过configLoation来指定加载路径,也可以通过path + Clazz 来指定,也就代码中的ConfigResources;我们这里是选则了第一种方式。因此第一个判断为false,第二个判断为true.

跟进代码 reader.loadBeanDefinitions(configLocations); 现在代码相当于走到了xml文档读取相关的类里面去了。

知道xml的位置,还需要加载,和读取 ,因此涉及到了ResourceLoader 以及XmlBeanDefinitionReader.接下来就看怎样加载和读取xml文件。

跟进代码,最后会调用AbstractBeanDefinitionReader的loadBeanDefinitions(String… locations) 方法,源码如下:

public int loadBeanDefinitions(String... locations) throws BeanDefinitionStoreException {        Assert.notNull(locations, "Location array must not be null");        int counter = 0;        String[] var3 = locations;        int var4 = locations.length;        for(int var5 = 0; var5 < var4; ++var5) {            String location = var3[var5];            counter += this.loadBeanDefinitions(location);        }        return counter;    }

可以看到该方法有调用了this.loadBeanDefinitions(location);注意这个方法和上面方法不一样,这里涉及到方法的重载,区别在于这个方法的型参是字符串,而上面那个方法是字符串数组。这个方法的源码如下:

public int loadBeanDefinitions(String location) throws BeanDefinitionStoreException {        return this.loadBeanDefinitions(location, (Set)null);    }

可以看到改方法继续调用了this.loadBeanDefinitions(location, (Set)null);

继续跟进代码,源码如下:

public int loadBeanDefinitions(String location, @Nullable Set
actualResources) throws BeanDefinitionStoreException { ResourceLoader resourceLoader = this.getResourceLoader(); if (resourceLoader == null) { throw new BeanDefinitionStoreException("Cannot import bean definitions from location [" + location + "]: no ResourceLoader available"); } else { int loadCount; if (!(resourceLoader instanceof ResourcePatternResolver)) { Resource resource = resourceLoader.getResource(location); loadCount = this.loadBeanDefinitions((Resource)resource); if (actualResources != null) { actualResources.add(resource); } if (this.logger.isDebugEnabled()) { this.logger.debug("Loaded " + loadCount + " bean definitions from location [" + location + "]"); } return loadCount; } else { try { Resource[] resources = ((ResourcePatternResolver)resourceLoader).getResources(location); loadCount = this.loadBeanDefinitions(resources); if (actualResources != null) { Resource[] var6 = resources; int var7 = resources.length; for(int var8 = 0; var8 < var7; ++var8) { Resource resource = var6[var8]; actualResources.add(resource); } } if (this.logger.isDebugEnabled()) { this.logger.debug("Loaded " + loadCount + " bean definitions from location pattern [" + location + "]"); } return loadCount; } catch (IOException var10) { throw new BeanDefinitionStoreException("Could not resolve bean definition resource pattern [" + location + "]", var10); } } } }

loadBeanDefinitions(String location, @Nullable Set actualResources) 主要干了那些事呢?

  1. 获取 resourceLoader,这边是 PathMatchingResourcePatternResolver ,没有解析器就抛异常。
  2. 判断 resourceLoader 是否是 ResourcePatternResolver,我们这边是符合的,跟踪代码,我们这个资源加载器的实现类就是ClassPathXmlApplicationContext.
  3. Resource[] resources = ((ResourcePatternResolver)resourceLoader).getResources(location);根据配置文件获取资源对象。
  4. loadCount = this.loadBeanDefinitions((Resource)resource); 继续加载配置文件。

在这里Resource是接口,实际的实现类ClassPathResource,跟踪代码调式,有这些属性

private final String path;    @Nullable    private ClassLoader classLoader;    @Nullable    private Class
clazz;

这些属性的值为path: spring.xml classLoader:AppClassLoader.

跟进代码this.loadBeanDefinitions((Resource)resource);

public int loadBeanDefinitions(Resource... resources) throws BeanDefinitionStoreException {        Assert.notNull(resources, "Resource array must not be null");        int counter = 0;        Resource[] var3 = resources;        int var4 = resources.length;        for(int var5 = 0; var5 < var4; ++var5) {            Resource resource = var3[var5];            counter += this.loadBeanDefinitions((Resource)resource);        }        return counter;    }

继续跟进,this.loadBeanDefinitions((Resource)resource); 也是有细微的去被,一个是数组,一个不是数据。别以为进行循环调用了。看源码,结果是接口定义的方法,是有子类实现,跟踪代码,是由XmlBeanDefinitionReader实现的。这个方法去这个类去找。

public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException {    return this.loadBeanDefinitions(new EncodedResource(resource));}

看到这个方法又调用了this.loadBeanDefinitions(new EncodedResource(resource));

那么我们先看下new EncodedResource(resource)这个代码干了什么事情。看源码

public EncodedResource(Resource resource) {

this(resource, (String)null, (Charset)null);
}

this(resource, (String)null, (Charset)null); 继续看这个代码干了什么?

private EncodedResource(Resource resource, @Nullable String encoding, @Nullable Charset charset) {        Assert.notNull(resource, "Resource must not be null");        this.resource = resource;        this.encoding = encoding;        this.charset = charset;    }

从代码中可以看了其定义了字符编码。

继续跟进this.loadBeanDefinitions(new EncodedResource(resource)); 代码,源码如下:

public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {		Assert.notNull(encodedResource, "EncodedResource must not be null");		if (logger.isInfoEnabled()) {			logger.info("Loading XML bean definitions from " + encodedResource.getResource());		}		Set
currentResources = this.resourcesCurrentlyBeingLoaded.get(); if (currentResources == null) { currentResources = new HashSet<>(4); this.resourcesCurrentlyBeingLoaded.set(currentResources); } if (!currentResources.add(encodedResource)) { throw new BeanDefinitionStoreException( "Detected cyclic loading of " + encodedResource + " - check your import definitions!"); } try { InputStream inputStream = encodedResource.getResource().getInputStream(); try { InputSource inputSource = new InputSource(inputStream); if (encodedResource.getEncoding() != null) { inputSource.setEncoding(encodedResource.getEncoding()); } return doLoadBeanDefinitions(inputSource, encodedResource.getResource()); } finally { inputStream.close(); } } catch (IOException ex) { throw new BeanDefinitionStoreException( "IOException parsing XML document from " + encodedResource.getResource(), ex); } finally { currentResources.remove(encodedResource); if (currentResources.isEmpty()) { this.resourcesCurrentlyBeingLoaded.remove(); } } }

InputStream inputStream = encodedResource.getResource().getInputStream();

跟进代码,看这个代码干了什么,其实根据上面的分析,encodedResource.getResource()获取的是ClassPathResource类,这类在上面已经产生了,基本属性也已经被赋值了,然后该对象又被封装在了EncodeResource里面,现在通过encodedResource.getResource()方法获取出来。就是ClassPathResource对象。

ClassPathResource.getInputStream();现在来看这个方法干了什么。

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(getDescription() + " cannot be opened because it does not exist");		}		return is;	}

这个类加载器是AppClassLoader,通过该类加载来加载xml文件,将其变成二进制流文件。如下所示:

在这里插入图片描述

继续跟进代码,将输入流封装在InputSource里面,并且给InputSource设置编码,该编码是从EncodeSource里面获取的编码。如以下代码所示:

if (encodedResource.getEncoding() != null) {					inputSource.setEncoding(encodedResource.getEncoding());				}

继续跟进代码,接下里代码就会走如下的代码

doLoadBeanDefinitions(inputSource, encodedResource.getResource());

继续跟进 doLoadBeanDefinitions(inputSource, encodedResource.getResource());

这个方法是在XmlBeanDefinitionReader里面

protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)			throws BeanDefinitionStoreException {		try {			Document doc = doLoadDocument(inputSource, resource);			return registerBeanDefinitions(doc, resource);		}		catch (BeanDefinitionStoreException ex) {			throw ex;		}		catch (SAXParseException ex) {			throw new XmlBeanDefinitionStoreException(resource.getDescription(),					"Line " + ex.getLineNumber() + " in XML document from " + resource + " is invalid", ex);		}		catch (SAXException ex) {			throw new XmlBeanDefinitionStoreException(resource.getDescription(),					"XML document from " + resource + " is invalid", ex);		}		catch (ParserConfigurationException ex) {			throw new BeanDefinitionStoreException(resource.getDescription(),					"Parser configuration exception parsing XML from " + resource, ex);		}		catch (IOException ex) {			throw new BeanDefinitionStoreException(resource.getDescription(),					"IOException parsing XML document from " + resource, ex);		}		catch (Throwable ex) {			throw new BeanDefinitionStoreException(resource.getDescription(),					"Unexpected exception parsing XML document from " + resource, ex);		}	}

可以看到上面的代码,只有一重要的代码,Document doc = doLoadDocument(inputSource, resource);

这行代码,把二进制流文件变成了Document对象。

接下来看该代码块具体是怎么做的,源码如下:

protected Document doLoadDocument(InputSource inputSource, Resource resource) throws Exception {

return this.documentLoader.loadDocument(inputSource, getEntityResolver(), this.errorHandler,
getValidationModeForResource(resource), isNamespaceAware());
}

我们可以看到这个代码里面有个documentLoader实例对象。通过这个实例对象的方法,将二进制流变成了Document对象。看原木,原来是一个DocumentLoader加载类,源码如下:

private DocumentLoader documentLoader = new DefaultDocumentLoader();

接下来的调用this.documentLoader.loadDocument(inputSource, getEntityResolver(), this.errorHandler,getValidationModeForResource(resource), isNamespaceAware());

可以看到这个方法真的有很多参数哦,接下来分析一下,getEntityResolver()

看下这个源码:

protected EntityResolver getEntityResolver() {		if (this.entityResolver == null) {			// Determine default EntityResolver to use.			ResourceLoader resourceLoader = getResourceLoader();			if (resourceLoader != null) {				this.entityResolver = new ResourceEntityResolver(resourceLoader);			}			else {				this.entityResolver = new DelegatingEntityResolver(getBeanClassLoader());			}		}		return this.entityResolver;	}

getEntityResolver()最后得到解析器如下图所示,但是后续跟进源码分析,其实EntityResolver早就初始化了,并且EntityResoler其实是一个接口,他的实例化对象是ResourceEntityResolver。

在这里插入图片描述

看下DefaultDocumentLoader里面的loadDocument方法

@Override

public Document loadDocument(InputSource inputSource, EntityResolver entityResolver,
ErrorHandler errorHandler, int validationMode, boolean namespaceAware) throws Exception {

DocumentBuilderFactory factory = createDocumentBuilderFactory(validationMode, namespaceAware);if (logger.isDebugEnabled()) {	logger.debug("Using JAXP provider [" + factory.getClass().getName() + "]");}DocumentBuilder builder = createDocumentBuilder(factory, entityResolver, errorHandler);return builder.parse(inputSource);

}

最后我们看到是通过DocumentBuilder来解析二进制流,变成Document对象。现在不就纠结这个是怎么变成Document的啦。

继续跟进代码,现在需要回到,最初调用获取Document对象的里面如下所示:
protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)			throws BeanDefinitionStoreException {		try {			Document doc = doLoadDocument(inputSource, resource);			return registerBeanDefinitions(doc, resource);		}		catch (BeanDefinitionStoreException ex) {			throw ex;		}		catch (SAXParseException ex) {			throw new XmlBeanDefinitionStoreException(resource.getDescription(),					"Line " + ex.getLineNumber() + " in XML document from " + resource + " is invalid", ex);		}		catch (SAXException ex) {			throw new XmlBeanDefinitionStoreException(resource.getDescription(),					"XML document from " + resource + " is invalid", ex);		}		catch (ParserConfigurationException ex) {			throw new BeanDefinitionStoreException(resource.getDescription(),					"Parser configuration exception parsing XML from " + resource, ex);		}		catch (IOException ex) {			throw new BeanDefinitionStoreException(resource.getDescription(),					"IOException parsing XML document from " + resource, ex);		}		catch (Throwable ex) {			throw new BeanDefinitionStoreException(resource.getDescription(),					"Unexpected exception parsing XML document from " + resource, ex);		}	}

现在看该代码后一般部分return registerBeanDefinitions(doc, resource);开始根据document文件开始解析Document,获取JavaBean的原信息,封装到BeanDefinition中。看源代码。

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

上面的方法还在XmlBeanDefinitioReader中。

对上面的方法进行分析:

  1. 首先获取BeanDefinitionDocumentReader对象。看下面代码
protected BeanDefinitionDocumentReader createBeanDefinitionDocumentReader() {		return BeanDefinitionDocumentReader.class.cast(BeanUtils.instantiateClass(this.documentReaderClass));	}
private Class
documentReaderClass = DefaultBeanDefinitionDocumentReader.class;

2,int countBefore = getRegistry().getBeanDefinitionCount();得到注册前,容器里面bean的数量。

3,documentReader.registerBeanDefinitions(doc, createReaderContext(resource)); 接下来注定分析,进行beanDefinition的注册。
4,return getRegistry().getBeanDefinitionCount() - countBefore;返回容器中BeanDefinition的增加量,例如原来2 ,现在增加量为3,总量为5.

documentReader.registerBeanDefinitions(doc, createReaderContext(resource));接下来看这个源码怎么读取Document对象中的信息,然后封装成BeanDefiniton.并注册。

在调用这个方法之前还得调用createReaderContext(resource)方法,产生XmlReaderContext对象,其实是对resource的封装。

/** * Create the {@link XmlReaderContext} to pass over to the document reader. */public XmlReaderContext createReaderContext(Resource resource) {	return new XmlReaderContext(resource, this.problemReporter, this.eventListener,			this.sourceExtractor, this, getNamespaceHandlerResolver());}

接下来进入主题documentReader.registerBeanDefinitions(doc, createReaderContext(resource));的源码分析。

@Override

public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
this.readerContext = readerContext;
logger.debug(“Loading bean definitions”);
Element root = doc.getDocumentElement();
doRegisterBeanDefinitions(root);
}

从上面的代码我们可以看到,注册方法的实现又被委派出去了。doRegisterBeanDefinitions(root);接下来看下这个方法实现。

protected void doRegisterBeanDefinitions(Element root) {		// Any nested 
elements will cause recursion in this method. In // order to propagate and preserve
default-* attributes correctly, // keep track of the current (parent) delegate, which may be null. Create // the new (child) delegate with a reference to the parent for fallback purposes, // then ultimately reset this.delegate back to its original (parent) reference. // this behavior emulates a stack of delegates without actually necessitating one. BeanDefinitionParserDelegate parent = this.delegate; this.delegate = createDelegate(getReaderContext(), root, parent); if (this.delegate.isDefaultNamespace(root)) { String profileSpec = root.getAttribute(PROFILE_ATTRIBUTE); if (StringUtils.hasText(profileSpec)) { String[] specifiedProfiles = StringUtils.tokenizeToStringArray( profileSpec, BeanDefinitionParserDelegate.MULTI_VALUE_ATTRIBUTE_DELIMITERS); if (!getReaderContext().getEnvironment().acceptsProfiles(specifiedProfiles)) { if (logger.isInfoEnabled()) { logger.info("Skipped XML bean definition file due to specified profiles [" + profileSpec + "] not matching: " + getReaderContext().getResource()); } return; } } } preProcessXml(root); parseBeanDefinitions(root, this.delegate); postProcessXml(root); this.delegate = parent; }

BeanDefinitionParserDelegate parent = this.delegate;this.delegate = createDelegate(getReaderContext(), root, parent);

BeanDefinitionParserDelegate中定义了Spring Bean定义了XML文件的各种元素。

上面的过程主要分为解析前和解析后都可以自定义解析,中间就是解析Document中的bean节点。

preProcessXml(root);parseBeanDefinitions(root, this.delegate);postProcessXml(root);

主要看parseBeanDefinitions(root, this.delegate);方法:

//使用Spring的Bean规则从文档的根元素开始Bean的定义的文档对象的解析protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {//Bean定义的文档使用了Spring默认的xml命名空间	if (delegate.isDefaultNamespace(root)) {	//获取Bean定义的文档对象根元素的所有子节点。		NodeList nl = root.getChildNodes();		for (int i = 0; i < nl.getLength(); i++) {			Node node = nl.item(i);			//获取文档节点是Xml元素节点			if (node instanceof Element) {				Element ele = (Element) node;				//Bean定义的文档元素节点使用的是Spring默认的xml命名空间				if (delegate.isDefaultNamespace(ele)) {				//使用Spring的Bean规则解析元素节点。					parseDefaultElement(ele, delegate);				}				else {				//如果没有使用Spring默认的xml命令空间,则使用用户定义自定义的解析规则解析元素节点。					delegate.parseCustomElement(ele);				}			}		}	}	else {	//文档的根节点没有使用Spring默认的命令空间	//使用自定义的解析规则解析文档的根节点。		delegate.parseCustomElement(root);	}}

接下来解析默认的Spring命令空间解析。 parseDefaultElement(ele, delegate);看源码怎么实现的。

private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {       //如果节点是
导入元素,进入导入解析 if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) { importBeanDefinitionResource(ele); } //如果节点是
别名元素,进行别名解析。 else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) { processAliasRegistration(ele); } //如果节点即不是导入元素也不是别名元素,而是bean元素,则按照普通Spring Bean规则解析 else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) { processBeanDefinition(ele, delegate); } //嵌套的bean,进入循环注入。 else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) { // recurse doRegisterBeanDefinitions(ele); } }

进入import节点导入,看下import导入 importBeanDefinitionResource(ele);的源码

//解析import导入元素,从给定的导入路径加载Bean资源到Spring IOC容器。

protected void importBeanDefinitionResource(Element ele) {
//获取给定的导入元素的location属性
String location = ele.getAttribute(RESOURCE_ATTRIBUTE);
//r如果导入元素的location属性值为空,则没有导入任何资源,直接返回。
if (!StringUtils.hasText(location)) {
getReaderContext().error(“Resource location must not be empty”, ele);
return;
}

// Resolve system properties: e.g. "${user.dir}"	//使用系统变量值解析location属性值	location = getReaderContext().getEnvironment().resolveRequiredPlaceholders(location);	Set
actualResources = new LinkedHashSet<>(4); // Discover whether the location is an absolute or relative URI //标识给定的导入元素的location属性值是否是绝对路径。 boolean absoluteLocation = false; try { absoluteLocation = ResourcePatternUtils.isUrl(location) || ResourceUtils.toURI(location).isAbsolute(); } catch (URISyntaxException ex) { //给定的导入元素的location属性值不是绝对路径 // cannot convert to an URI, considering the location relative // unless it is the well-known Spring prefix "classpath*:" } // Absolute or relative? //给定的导入元素的location属性值是绝对路径 if (absoluteLocation) { try { //使用资源读入器加载给定路径的Bean资源。 int importCount = getReaderContext().getReader().loadBeanDefinitions(location, actualResources); if (logger.isDebugEnabled()) { logger.debug("Imported " + importCount + " bean definitions from URL location [" + location + "]"); } } catch (BeanDefinitionStoreException ex) { getReaderContext().error( "Failed to import bean definitions from URL location [" + location + "]", ele, ex); } } else { // No URL -> considering resource location as relative to the current file. //给定导入元素的location属性值是相对路径 try { int importCount; //将给定导入元素的location封装为相对路径资源 Resource relativeResource = getReaderContext().getResource().createRelative(location); //封装的相对路径资源存在吗 if (relativeResource.exists()) { //使用资源读入器加载Bean资源 importCount = getReaderContext().getReader().loadBeanDefinitions(relativeResource); actualResources.add(relativeResource); } //封装的相对路径不存在 else { //获取Spring Ioc 容器资源读入器的基本路径。 String baseLocation = getReaderContext().getResource().getURL().toString(); //根据spring Ioc 容器资源读入器的基本路径加载给定导入路径的资源。 importCount = getReaderContext().getReader().loadBeanDefinitions( StringUtils.applyRelativePath(baseLocation, location), actualResources); } if (logger.isDebugEnabled()) { logger.debug("Imported " + importCount + " bean definitions from relative location [" + location + "]"); } } catch (IOException ex) { getReaderContext().error("Failed to resolve current resource location", ele, ex); } catch (BeanDefinitionStoreException ex) { getReaderContext().error("Failed to import bean definitions from relative location [" + location + "]", ele, ex); } } Resource[] actResArray = actualResources.toArray(new Resource[0]); //在解析import元素之后,发送容器导入其他资源处理完成事件。 getReaderContext().fireImportProcessed(location, actResArray, extractSource(ele));}

接下来进入 processAliasRegistration(ele); 别名处理,看源码:

解析alias别名元素,为Bean想Spring Ioc 容器注册别名protected void processAliasRegistration(Element ele) {//获取alias别名元素中的name的属性值。		String name = ele.getAttribute(NAME_ATTRIBUTE);		//获取alias别名元素中的alias的属性值。		String alias = ele.getAttribute(ALIAS_ATTRIBUTE);		boolean valid = true;		//alias别名元素中的name的属性值为空。		if (!StringUtils.hasText(name)) {			getReaderContext().error("Name must not be empty", ele);			valid = false;		}		//alias别名元素中的alias的属性值为空。		if (!StringUtils.hasText(alias)) {			getReaderContext().error("Alias must not be empty", ele);			valid = false;		}		if (valid) {			try {			    //想容器的资源读入器注册别名				getReaderContext().getRegistry().registerAlias(name, alias);			}			catch (Exception ex) {				getReaderContext().error("Failed to register alias '" + alias +						"' for bean with name '" + name + "'", ele, ex);			}			//在解析完alias元素之后,发送容器别名处理完成事件			getReaderContext().fireAliasRegistered(name, alias, extractSource(ele));		}	}

继续跟进代码 processBeanDefinition(ele, delegate);看源码

//解析Bean资源文档对象的普通元素protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {//BeanDefinitionHolder是对BeanDefiniton的封装,即Bean定义的封装类		BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);		if (bdHolder != null) {			bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);			try {				// Register the final decorated instance.				//向Spring IOC容器中注册解析得到的Bean定义,这是Bean定义向Ioc容器注册的入口				BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());			}			catch (BeanDefinitionStoreException ex) {				getReaderContext().error("Failed to register bean definition with name '" +						bdHolder.getBeanName() + "'", ele, ex);			}			// Send registration event.			//在完成向Spring ioc 容器注册解析得到的Bean定义之后,发送注册事件。			getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));		}	}

继续跟进BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);代码

//解析Bean元素的入口@Nullablepublic BeanDefinitionHolder parseBeanDefinitionElement(Element ele) {	return parseBeanDefinitionElement(ele, null);}//解析Bean配置信息中的bean元素,这个方法中主要处理bean元素的id,name 和别名属性@Nullable	public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, @Nullable BeanDefinition containingBean) {	//获取Bean配置信息中的id值		String id = ele.getAttribute(ID_ATTRIBUTE);		//获取Bean信息中的name值		String nameAttr = ele.getAttribute(NAME_ATTRIBUTE);		List
aliases = new ArrayList<>(); //获取bean元素中的所有alias属性值 //将bean元素中的所有name值,存放到别名中 if (StringUtils.hasLength(nameAttr)) { String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, MULTI_VALUE_ATTRIBUTE_DELIMITERS); aliases.addAll(Arrays.asList(nameArr)); } String beanName = id; //如果bean元素中没有配置id属性,将别名中的第一值赋值给beanName if (!StringUtils.hasText(beanName) && !aliases.isEmpty()) { beanName = aliases.remove(0); if (logger.isDebugEnabled()) { logger.debug("No XML 'id' specified - using '" + beanName + "' as bean name and " + aliases + " as aliases"); } } //检查bean元素所配置的id或者name的唯一性 //contianBean标识bean元素中是否包含了子bean元素 if (containingBean == null) { //检查bean元素所配置的id,name或者别名是否重复 checkNameUniqueness(beanName, aliases, ele); }// 详细bean元素中的配置的bean定义进行解析 AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean); if (beanDefinition != null) { if (!StringUtils.hasText(beanName)) { try { if (containingBean != null) { //如果bean元素中没有配置id,别名和name,且没有包含子元素,bean元素,//则为解析的Bean生成一个唯一beanName并注册。 beanName = BeanDefinitionReaderUtils.generateBeanName( beanDefinition, this.readerContext.getRegistry(), true); } else { //如果bean元素中没有配置id,别名和name,且包含子元素,bean元素,//则解析的Bean使用别名想Ioc容器注册。 beanName = this.readerContext.generateBeanName(beanDefinition); // Register an alias for the plain bean class name, if still possible, // if the generator returned the class name plus a suffix. // This is expected for Spring 1.2/2.0 backwards compatibility. //spring 1.2/2.0 给别名添加类名后缀。为了向后兼容。 String beanClassName = beanDefinition.getBeanClassName(); if (beanClassName != null && beanName.startsWith(beanClassName) && beanName.length() > beanClassName.length() && !this.readerContext.getRegistry().isBeanNameInUse(beanClassName)) { aliases.add(beanClassName); } } if (logger.isDebugEnabled()) { logger.debug("Neither XML 'id' nor 'name' specified - " + "using generated bean name [" + beanName + "]"); } } catch (Exception ex) { error(ex.getMessage(), ele); return null; } } String[] aliasesArray = StringUtils.toStringArray(aliases); return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray); } //当解析出错返回null. return null; }

AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean); 源码如下:

public AbstractBeanDefinition parseBeanDefinitionElement(Element ele, String beanName, @Nullable BeanDefinition containingBean) {//将当前bean解析入栈,记录解析
的过程,parseState可以通过toString来打印调用栈链 //下面解析property的时候,也同样记录了 this.parseState.push(new BeanEntry(beanName)); String className = null; if (ele.hasAttribute("class")) { className = ele.getAttribute("class").trim(); } String parent = null; if (ele.hasAttribute("parent")) { parent = ele.getAttribute("parent"); } try { //根据类名和父类名创建BeanDefinition AbstractBeanDefinition bd = this.createBeanDefinition(className, parent); //解析DOM中的属性,并存入到AbstractBeanDefinition对象中 this.parseBeanDefinitionAttributes(ele, beanName, containingBean, bd); //设置描述 bd.setDescription(DomUtils.getChildElementValueByTagName(ele, "description")); //对
元素的meta(元信息)属性解析 this.parseMetaElements(ele, bd); //对
元素的lookup-method属性解析 this.parseLookupOverrideSubElements(ele, bd.getMethodOverrides()); //对
元素的replaced-method属性解析 this.parseReplacedMethodSubElements(ele, bd.getMethodOverrides()); //解析
元素的构造方法设置 this.parseConstructorArgElements(ele, bd); //解析
元素的
设置 this.parsePropertyElements(ele, bd); //解析
元素的qualifier属性 this.parseQualifierElements(ele, bd); //为当前解析的Bean设置所需的资源和依赖对象 bd.setResource(this.readerContext.getResource()); bd.setSource(this.extractSource(ele)); AbstractBeanDefinition var7 = bd; return var7; } catch (ClassNotFoundException var13) { this.error("Bean class [" + className + "] not found", ele, var13); } catch (NoClassDefFoundError var14) { this.error("Class that bean class [" + className + "] depends on not found", ele, var14); } catch (Throwable var15) { this.error("Unexpected failure during bean definition parsing", ele, var15); } finally { //记录出栈 this.parseState.pop(); } return null; }

继续跟进代码:AbstractBeanDefinition bd = this.createBeanDefinition(className, parent);

protected AbstractBeanDefinition createBeanDefinition(@Nullable String className, @Nullable String parentName) throws ClassNotFoundException {        return BeanDefinitionReaderUtils.createBeanDefinition(parentName, className, this.readerContext.getBeanClassLoader());    }
public static AbstractBeanDefinition createBeanDefinition(@Nullable String parentName, @Nullable String className, @Nullable ClassLoader classLoader) throws ClassNotFoundException {        GenericBeanDefinition bd = new GenericBeanDefinition();        bd.setParentName(parentName);        if (className != null) {            if (classLoader != null) {                bd.setBeanClass(ClassUtils.forName(className, classLoader));            } else {                bd.setBeanClassName(className);            }        }        return bd;    }

由上述代码发现,实际上创建的AbstractBeanDefinition 的实现为GenericBeanDefinition对象。

继续跟进代码,看怎样解析Bean的其他属性的。parseBeanDefinitionAttributes

public AbstractBeanDefinition parseBeanDefinitionAttributes(Element ele, String beanName, @Nullable BeanDefinition containingBean, AbstractBeanDefinition bd) {//1.x版本的singleton属性已更新到scope中,设置了该属性将报错        if (ele.hasAttribute("singleton")) {            this.error("Old 1.x 'singleton' attribute in use - upgrade to 'scope' declaration", ele);        } else if (ele.hasAttribute("scope")) {        //解析scope的值 singleton 或者 prototype            bd.setScope(ele.getAttribute("scope"));        } else if (containingBean != null) {            bd.setScope(containingBean.getScope());        }//获取并设置abstract属性        if (ele.hasAttribute("abstract")) {            bd.setAbstract("true".equals(ele.getAttribute("abstract")));        }//获取并设置lazy-init属性        String lazyInit = ele.getAttribute("lazy-init");        if ("default".equals(lazyInit)) {            lazyInit = this.defaults.getLazyInit();        }        bd.setLazyInit("true".equals(lazyInit));        //获取并设置autowire属性        String autowire = ele.getAttribute("autowire");        bd.setAutowireMode(this.getAutowireMode(autowire));        String autowireCandidate;        //获取并设置depends-on属性        if (ele.hasAttribute("depends-on")) {            autowireCandidate = ele.getAttribute("depends-on");            bd.setDependsOn(StringUtils.tokenizeToStringArray(autowireCandidate, ",; "));        }//获取并设置autowire-candidate属性        autowireCandidate = ele.getAttribute("autowire-candidate");        String destroyMethodName;        if (!"".equals(autowireCandidate) && !"default".equals(autowireCandidate)) {            bd.setAutowireCandidate("true".equals(autowireCandidate));        } else {            destroyMethodName = this.defaults.getAutowireCandidates();            if (destroyMethodName != null) {                String[] patterns = StringUtils.commaDelimitedListToStringArray(destroyMethodName);                bd.setAutowireCandidate(PatternMatchUtils.simpleMatch(patterns, beanName));            }        }//获取并设置primary属性        if (ele.hasAttribute("primary")) {            bd.setPrimary("true".equals(ele.getAttribute("primary")));        }//获取并设置init-method属性        if (ele.hasAttribute("init-method")) {            destroyMethodName = ele.getAttribute("init-method");            bd.setInitMethodName(destroyMethodName);        } else if (this.defaults.getInitMethod() != null) {            bd.setInitMethodName(this.defaults.getInitMethod());            bd.setEnforceInitMethod(false);        }//获取并设置destroy-method属性        if (ele.hasAttribute("destroy-method")) {            destroyMethodName = ele.getAttribute("destroy-method");            bd.setDestroyMethodName(destroyMethodName);        } else if (this.defaults.getDestroyMethod() != null) {            bd.setDestroyMethodName(this.defaults.getDestroyMethod());            bd.setEnforceDestroyMethod(false);        }//获取并设置factory-method属性        if (ele.hasAttribute("factory-method")) {            bd.setFactoryMethodName(ele.getAttribute("factory-method"));        }//获取并设置factory-bean属性        if (ele.hasAttribute("factory-bean")) {            bd.setFactoryBeanName(ele.getAttribute("factory-bean"));        }        return bd;    }

继续跟进解析构造函数parseConstructorArgElements

public void parseConstructorArgElements(Element beanEle, BeanDefinition bd) {        NodeList nl = beanEle.getChildNodes();        //遍历子节点        for(int i = 0; i < nl.getLength(); ++i) {            Node node = nl.item(i);            //假如节点为constructor-arg节点,则执行构造器元素的解析            if (this.isCandidateElement(node) && this.nodeNameEquals(node, "constructor-arg")) {                this.parseConstructorArgElement((Element)node, bd);            }        }    }
public void parseConstructorArgElement(Element ele, BeanDefinition bd) {//获取index的属性值        String indexAttr = ele.getAttribute("index");        //获取type属性值        String typeAttr = ele.getAttribute("type");        //获取name属性值        String nameAttr = ele.getAttribute("name");        if (StringUtils.hasLength(indexAttr)) {            try {                int index = Integer.parseInt(indexAttr);                if (index < 0) {                    this.error("'index' cannot be lower than 0", ele);                } else {                    try {                    //记录
节点的解析,入栈 this.parseState.push(new ConstructorArgumentEntry(index)); //将构造器依赖的值解析出来 Object value = this.parsePropertyValue(ele, bd, (String)null); //封装构造器参数的值 ValueHolder valueHolder = new ValueHolder(value); //设置类型 if (StringUtils.hasLength(typeAttr)) { valueHolder.setType(typeAttr); } //设置构造器参数变量名 if (StringUtils.hasLength(nameAttr)) { valueHolder.setName(nameAttr); }//资源设置 valueHolder.setSource(this.extractSource(ele)); //假如构造器参数已经注册了值,则报错 if (bd.getConstructorArgumentValues().hasIndexedArgumentValue(index)) { this.error("Ambiguous constructor-arg entries for index " + index, ele); } else { //设置构造器的值 bd.getConstructorArgumentValues().addIndexedArgumentValue(index, valueHolder); } } finally { //出栈 this.parseState.pop(); } } } catch (NumberFormatException var19) { this.error("Attribute 'index' of tag 'constructor-arg' must be an integer", ele); } } else { try { //假如不是通过index设置构造器参数的值 //记录
节点的解析,入栈 this.parseState.push(new ConstructorArgumentEntry()); //将构造器依赖的值解析出来 Object value = this.parsePropertyValue(ele, bd, (String)null); //封装构造器参数的值 ValueHolder valueHolder = new ValueHolder(value); //设置类型 if (StringUtils.hasLength(typeAttr)) { valueHolder.setType(typeAttr); }//设置构造器参数变量名 if (StringUtils.hasLength(nameAttr)) { valueHolder.setName(nameAttr); }//资源设置 valueHolder.setSource(this.extractSource(ele)); //设置构造器的值 bd.getConstructorArgumentValues().addGenericArgumentValue(valueHolder); } finally { //出栈 this.parseState.pop(); } } }

继续跟进解析属性值:parseQualifierElements

public void parsePropertyElements(Element beanEle, BeanDefinition bd) {        NodeList nl = beanEle.getChildNodes();//遍历所有子节点        for(int i = 0; i < nl.getLength(); ++i) {            Node node = nl.item(i);            if (this.isCandidateElement(node) && this.nodeNameEquals(node, "property")) {            //假如是property节点,则开始解析                this.parsePropertyElement((Element)node, bd);            }        }    }
public void parsePropertyElement(Element ele, BeanDefinition bd) {//获取
元素名称 String propertyName = ele.getAttribute("name"); if (!StringUtils.hasLength(propertyName)) { this.error("Tag 'property' must have a 'name' attribute", ele); } else { //解析
的记录,入栈 this.parseState.push(new PropertyEntry(propertyName)); try { if (bd.getPropertyValues().contains(propertyName)) { //如果同个bean中有名称相同property,则直接返回 this.error("Multiple 'property' definitions for property '" + propertyName + "'", ele); return; } //获取property的值 Object val = this.parsePropertyValue(ele, bd, propertyName); //根据property的名称和值创建property实例 PropertyValue pv = new PropertyValue(propertyName, val); //解析元信息元素 this.parseMetaElements(ele, pv); //设置资源 pv.setSource(this.extractSource(ele)); //向BeanDefinition中添加property值,其维护了一个List集合来保存property的值 bd.getPropertyValues().addPropertyValue(pv); } finally { //出栈 this.parseState.pop(); } } }

先举一个property元素的例子

在这里插入图片描述

从上图的property配置文件示例可以看出,property的属性值可以为ref、value两种,而子节点可以为ref、value、list、map等,下面代码将呈现如何解析上述属性或者节点。

继续跟进代码,parsePropertyValue

@Nullable    public Object parsePropertyValue(Element ele, BeanDefinition bd, @Nullable String propertyName) {        String elementName = propertyName != null ? "
element for property '" + propertyName + "'" : "
element"; //要求
节点只能有一个子节点,可以是
等等 NodeList nl = ele.getChildNodes(); Element subElement = null; for(int i = 0; i < nl.getLength(); ++i) { Node node = nl.item(i); if (node instanceof Element && !this.nodeNameEquals(node, "description") && !this.nodeNameEquals(node, "meta")) { //假如存在一个以上节点,则会多次循环,第二次循环subElement的值将不为空,则报错。 if (subElement != null) { this.error(elementName + " must not contain more than one sub-element", ele); } else { //首次循环,subElement为空,为其赋值,假如再进一次循环,将会走上面的分支 subElement = (Element)node; } } } //获取ref属性 boolean hasRefAttribute = ele.hasAttribute("ref"); //获取value属性 boolean hasValueAttribute = ele.hasAttribute("value"); //假如(同时有ref、value属性)或者(有子节点并同时存在ref或value属性)则报错 //意思还是跟上述的要求一样,要求
节点只能有一个子节点 if (hasRefAttribute && hasValueAttribute || (hasRefAttribute || hasValueAttribute) && subElement != null) { this.error(elementName + " is only allowed to contain either 'ref' attribute OR 'value' attribute OR sub-element", ele); }//经过上述验证后,到达此处,已经确保
节点只有一个,其实分为三种情况: //1、ref属性
//2、value属性
//3、子节点
2
if (hasRefAttribute) { //假如有ref属性,则创建并返回ref的值 String refName = ele.getAttribute("ref"); if (!StringUtils.hasText(refName)) { this.error(elementName + " contains empty 'ref' attribute", ele); } RuntimeBeanReference ref = new RuntimeBeanReference(refName); ref.setSource(this.extractSource(ele)); return ref; } else if (hasValueAttribute) { //假如有value属性,则创建并返回value的值 TypedStringValue valueHolder = new TypedStringValue(ele.getAttribute("value")); valueHolder.setSource(this.extractSource(ele)); return valueHolder; } else if (subElement != null) { //假如为子节点的情况,则返回解析的子节点 return this.parsePropertySubElement(subElement, bd); } else { this.error(elementName + " must specify a ref or value", ele); return null; } }

上述代码讲述了对于标签的解析过程,对于的值,分别有三种情况,分别是ref属性、value属性、子节点,其中前面两种比较简单,下面重点的解析子节点的过程:parsePropertySubElement(subElement, bd);

@Nullable    public Object parsePropertySubElement(Element ele, @Nullable BeanDefinition bd) {        return this.parsePropertySubElement(ele, bd, (String)null);    }
@Nullable    public Object parsePropertySubElement(Element ele, @Nullable BeanDefinition bd, @Nullable String defaultValueType) {    //假如
子元素非默认命名空间,则使用用户自定义规则解析 if (!this.isDefaultNamespace((Node)ele)) { return this.parseNestedCustomElement(ele, bd); } else if (this.nodeNameEquals(ele, "bean")) { //假如
子元素为
元素,则递归调用解析BeanDefinition方法 // 下面为配置文件示例: //
//
//
BeanDefinitionHolder nestedBd = this.parseBeanDefinitionElement(ele, bd); if (nestedBd != null) { nestedBd = this.decorateBeanDefinitionIfRequired(ele, nestedBd, bd); } return nestedBd; } else if (this.nodeNameEquals(ele, "ref")) { //假如
子元素为
元素 //配置文件示例: //
//
//
//获取bean属性的值,为ref的引用目标名称 String refName = ele.getAttribute("bean"); boolean toParent = false; if (!StringUtils.hasLength(refName)) { //假如没有指定bean的值,则解析parent的值作为ref的引用目标的名称 refName = ele.getAttribute("parent"); toParent = true; if (!StringUtils.hasLength(refName)) { this.error("'bean' or 'parent' is required for
element", ele); return null; } } if (!StringUtils.hasText(refName)) { this.error("
element contains empty target attribute", ele); return null; } else { //创建并返回bean引用 RuntimeBeanReference ref = new RuntimeBeanReference(refName, toParent); ref.setSource(this.extractSource(ele)); return ref; } } else if (this.nodeNameEquals(ele, "idref")) { //假如
子元素为
元素 //
//
//
//则解析其bean,并创建返回bean引用 return this.parseIdRefElement(ele); } else if (this.nodeNameEquals(ele, "value")) { //假如
子元素为
元素 //
//
tony
//
return this.parseValueElement(ele, defaultValueType); } else if (this.nodeNameEquals(ele, "null")) { //假如
子元素为
元素 //
//
//
//
它是一个特殊的空值。为了保留源位置,我们将其封装在TypedStringValue对象中。 TypedStringValue nullHolder = new TypedStringValue((String)null); nullHolder.setSource(this.extractSource(ele)); return nullHolder; } else if (this.nodeNameEquals(ele, "array")) { //假如
子元素为
元素,解析设置数组的值 //
//
//
tony老师
//
jack老师
//
//
return this.parseArrayElement(ele, bd); } else if (this.nodeNameEquals(ele, "list")) { //假如
子元素为
元素,解析设置list集合的值 //
//
//
tony老师
//
jack老师
//
//
return this.parseListElement(ele, bd); } else if (this.nodeNameEquals(ele, "set")) { //假如
子元素为
元素,解析设置set集合的值 //
//
//
tony老师
//
jack老师
//
//
return this.parseSetElement(ele, bd); } else if (this.nodeNameEquals(ele, "map")) { //假如
子元素为
元素,解析设置map集合的值 //
//
//
//
string
//
//
//
//
//
//
return this.parseMapElement(ele, bd); } else if (this.nodeNameEquals(ele, "props")) { //假如
子元素为
元素,解析设置Properties对象的值 //
//
//
aaa
//
//
return this.parsePropsElement(ele); } else { this.error("Unknown property sub-element: [" + ele.getNodeName() + "]", ele); return null; } }

上述代码事实上,完成了的子元素、、、、、、、、、等的解析。具体的解析过程不再展开,至此结束。可以自己去定位源码。

接下来就是思考,解析后AbstractBeanDefinition 怎样被放到让容器里面,怎样被管理的。

代码还得回归到解析Bean元素的处理中,看如下代码

protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {    BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);    if (bdHolder != null) {        bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);        try {            BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, this.getReaderContext().getRegistry());        } catch (BeanDefinitionStoreException var5) {            this.getReaderContext().error("Failed to register bean definition with name '" + bdHolder.getBeanName() + "'", ele, var5);        }        this.getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));    }}

获取到BeanDefinitionHolder之后,在进一步对这个对象进行装饰后,开始进行注册。即调用如下的代码 BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, this.getReaderContext().getRegistry());

public static void registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) throws BeanDefinitionStoreException {        String beanName = definitionHolder.getBeanName();        registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());        String[] aliases = definitionHolder.getAliases();        if (aliases != null) {            String[] var4 = aliases;            int var5 = aliases.length;            for(int var6 = 0; var6 < var5; ++var6) {                String alias = var4[var6];                registry.registerAlias(beanName, alias);            }        }    }

上诉代码中, registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition()); 应该是注册了,bean的名称和BeanDefinition。继续跟进。这个实现是由DefaultListableBeanFactory实现的。

public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException { //断言beanName和beanDefinition不能为null        Assert.hasText(beanName, "Bean name must not be empty");        Assert.notNull(beanDefinition, "BeanDefinition must not be null");          //beanDefinition如果是AbstractBeanDefinition实例就进行验证,注意AbstractBeanDefinition实现BeanDefinition接口        if (beanDefinition instanceof AbstractBeanDefinition) {            try {             //如果方法重写和静态工厂方法同时存在 抛异常                ((AbstractBeanDefinition)beanDefinition).validate();            } catch (BeanDefinitionValidationException var9) {                throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, "Validation of bean definition failed", var9);            }        }       //首先尝试能不能从缓存中获取BeanDefinition        BeanDefinition oldBeanDefinition = (BeanDefinition)this.beanDefinitionMap.get(beanName);        if (oldBeanDefinition != null) {            if (!this.isAllowBeanDefinitionOverriding()) {                throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, "Cannot register bean definition [" + beanDefinition + "] for bean '" + beanName + "': There is already [" + oldBeanDefinition + "] bound.");            }            if (oldBeanDefinition.getRole() < beanDefinition.getRole()) {                if (this.logger.isWarnEnabled()) {                    this.logger.warn("Overriding user-defined bean definition for bean '" + beanName + "' with a framework-generated bean definition: replacing [" + oldBeanDefinition + "] with [" + beanDefinition + "]");                }            } else if (!beanDefinition.equals(oldBeanDefinition)) {                if (this.logger.isInfoEnabled()) {                    this.logger.info("Overriding bean definition for bean '" + beanName + "' with a different definition: replacing [" + oldBeanDefinition + "] with [" + beanDefinition + "]");                }            } else if (this.logger.isDebugEnabled()) {                this.logger.debug("Overriding bean definition for bean '" + beanName + "' with an equivalent definition: replacing [" + oldBeanDefinition + "] with [" + beanDefinition + "]");            }              //允许覆盖就存到map中ConcurrentHashMap            //ConcurrentHashMap类型 安全 比HashTable效率高 采用分段数组模式 读操作不加锁 写操作分段加锁            this.beanDefinitionMap.put(beanName, beanDefinition);        } else {             //缓存中没有 直接注册            //如果beanDefinition已经被标记为创建(为了解决单例bean的循环依赖问题)            if (this.hasBeanCreationStarted()) {                Map var4 = this.beanDefinitionMap;                synchronized(this.beanDefinitionMap) {                 //加入beanDefinitionMap                    this.beanDefinitionMap.put(beanName, beanDefinition);                    List
updatedDefinitions = new ArrayList(this.beanDefinitionNames.size() + 1); updatedDefinitions.addAll(this.beanDefinitionNames); updatedDefinitions.add(beanName); //将updatedDefinitions赋值给beanDefinitionNames //这段代码加锁可能是为了防止多线程下beanDefinitionNames会出问题,因为beanDefinitionMap本身就是 线程安全的 this.beanDefinitionNames = updatedDefinitions; if (this.manualSingletonNames.contains(beanName)) { Set
updatedSingletons = new LinkedHashSet(this.manualSingletonNames); //移除新注册的beanName updatedSingletons.remove(beanName); this.manualSingletonNames = updatedSingletons; } } } else { this.beanDefinitionMap.put(beanName, beanDefinition); this.beanDefinitionNames.add(beanName); //移除新注册的beanName this.manualSingletonNames.remove(beanName); } this.frozenBeanDefinitionNames = null; } //重置BeanDefinition, //当前注册的bean的定义已经在beanDefinitionMap缓存中存在, //或者其实例已经存在于单例bean的缓存中 if (oldBeanDefinition != null || this.containsSingleton(beanName)) { this.resetBeanDefinition(beanName); } }

至此Ioc还只完成了bean的名称和bean的信息的对应,那么具体的bean实例,在什么时候创建了?

这个时候就要看AbstractApplicationContext的源码中的finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory)方法拉,看源码:

//判断BeanFactory中是否存在名称为“conversionService”且类型为ConversionService的Bean,如果存在则将其注入到beanFactoryprotected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {        if (beanFactory.containsBean("conversionService") && beanFactory.isTypeMatch("conversionService", ConversionService.class)) {            beanFactory.setConversionService((ConversionService)beanFactory.getBean("conversionService", ConversionService.class));        }        if (!beanFactory.hasEmbeddedValueResolver()) {            beanFactory.addEmbeddedValueResolver((strVal) -> {                return this.getEnvironment().resolvePlaceholders(strVal);            });        }        // 得到所有的实现了LoadTimeWeaverAware接口的子类名称,初始化它们        String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);        String[] var3 = weaverAwareNames;        int var4 = weaverAwareNames.length;        for(int var5 = 0; var5 < var4; ++var5) {            String weaverAwareName = var3[var5];            this.getBean(weaverAwareName);        }        // 停止使用临时类加载器        beanFactory.setTempClassLoader((ClassLoader)null);          // 缓存所有的BeanName        beanFactory.freezeConfiguration();       // 初始化所有单例Bean        beanFactory.preInstantiateSingletons();    }
public void preInstantiateSingletons() throws BeansException {        if (this.logger.isDebugEnabled()) {            this.logger.debug("Pre-instantiating singletons in " + this);        }        List
beanNames = new ArrayList(this.beanDefinitionNames); Iterator var2 = beanNames.iterator(); while(true) { String beanName; Object bean; do { while(true) { RootBeanDefinition bd; do { do { do { if (!var2.hasNext()) { var2 = beanNames.iterator(); while(var2.hasNext()) { beanName = (String)var2.next(); //获取单列bean. Object singletonInstance = this.getSingleton(beanName); if (singletonInstance instanceof SmartInitializingSingleton) { SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton)singletonInstance; if (System.getSecurityManager() != null) { AccessController.doPrivileged(() -> { smartSingleton.afterSingletonsInstantiated(); return null; }, this.getAccessControlContext()); } else { smartSingleton.afterSingletonsInstantiated(); } } } return; } beanName = (String)var2.next(); bd = this.getMergedLocalBeanDefinition(beanName); } while(bd.isAbstract()); } while(!bd.isSingleton()); } while(bd.isLazyInit()); if (this.isFactoryBean(beanName)) { bean = this.getBean("&" + beanName); break; } //这里的getBean(beanName) this.getBean(beanName); } } while(!(bean instanceof FactoryBean)); FactoryBean
factory = (FactoryBean)bean; boolean isEagerInit; if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) { SmartFactoryBean var10000 = (SmartFactoryBean)factory; ((SmartFactoryBean)factory).getClass(); isEagerInit = (Boolean)AccessController.doPrivileged(var10000::isEagerInit, this.getAccessControlContext()); } else { isEagerInit = factory instanceof SmartFactoryBean && ((SmartFactoryBean)factory).isEagerInit(); } if (isEagerInit) { this.getBean(beanName); } } }

接下来的getBean(beanName) 就分析到了依赖注入的环节。

在抽象的AbstractBeanFactory里面有如下的代码

public Object getBean(String name) throws BeansException {        return this.doGetBean(name, (Class)null, (Object[])null, false);    }
protected 
T doGetBean(String name, @Nullable Class
requiredType, @Nullable Object[] args, boolean typeCheckOnly) throws BeansException {//首先根据传入的name获取beanName String beanName = this.transformedBeanName(name); //获取缓存或者实例工厂中是否有对应的实例 Object sharedInstance = this.getSingleton(beanName); Object bean; //存在单例且传入的args为null if (sharedInstance != null && args == null) { //分情况打印日志 if (this.logger.isDebugEnabled()) { if (this.isSingletonCurrentlyInCreation(beanName)) { this.logger.debug("Returning eagerly cached instance of singleton bean '" + beanName + "' that is not fully initialized yet - a consequence of a circular reference"); } else { this.logger.debug("Returning cached instance of singleton bean '" + beanName + "'"); } }//返回对应实例 bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, (RootBeanDefinition)null); } else { //单例模式下才会尝试解决循环依赖,原型模式如果当前bean正在创建,则抛出异常 if (this.isPrototypeCurrentlyInCreation(beanName)) { throw new BeanCurrentlyInCreationException(beanName); }//获取parentBeanFactory BeanFactory parentBeanFactory = this.getParentBeanFactory(); // 如果beanDefinitionMap不存在beanName则从parentBeanFactory中寻找 if (parentBeanFactory != null && !this.containsBeanDefinition(beanName)) { String nameToLookup = this.originalBeanName(name); if (parentBeanFactory instanceof AbstractBeanFactory) { //如果parentBeanFactory是AbstractBeanFactory的实现类对象,调用parentBeanFactory中的doGetBean方法 return ((AbstractBeanFactory)parentBeanFactory).doGetBean(nameToLookup, requiredType, args, typeCheckOnly); } if (args != null) { return parentBeanFactory.getBean(nameToLookup, args); } return parentBeanFactory.getBean(nameToLookup, requiredType); }/如果不是做类型检查,则要创建bean,这里进行记录 if (!typeCheckOnly) { this.markBeanAsCreated(beanName); } try { //将加载的GenericBeanDefinition转化为RootBeanDefinition,如果指定的beanName是子Bean则会合并父类属性 RootBeanDefinition mbd = this.getMergedLocalBeanDefinition(beanName); //检测 this.checkMergedBeanDefinition(mbd, beanName, args); //获取依赖,如果存在需要递归实例化 String[] dependsOn = mbd.getDependsOn(); String[] var11; if (dependsOn != null) { var11 = dependsOn; int var12 = dependsOn.length; for(int var13 = 0; var13 < var12; ++var13) { String dep = var11[var13]; if (this.isDependent(beanName, dep)) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'"); } this.registerDependentBean(dep, beanName); try { this.getBean(dep); } catch (NoSuchBeanDefinitionException var24) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "'" + beanName + "' depends on missing bean '" + dep + "'", var24); } } }//实例化依赖bean之后开始实例化mbd本身//单例模式的创建 if (mbd.isSingleton()) { sharedInstance = this.getSingleton(beanName, () -> { try { //返回创建的bean return this.createBean(beanName, mbd, args); } catch (BeansException var5) { this.destroySingleton(beanName); throw var5; } }); //缓存中的bean是bean的原始状态,获取最终想要的bean bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, mbd); //原型创建 } else if (mbd.isPrototype()) { var11 = null; Object prototypeInstance; try { //前置处理 this.beforePrototypeCreation(beanName); //创建bean prototypeInstance = this.createBean(beanName, mbd, args); } finally { //后置处理 this.afterPrototypeCreation(beanName); } bean = this.getObjectForBeanInstance(prototypeInstance, name, beanName, mbd); } else { //获取指定范围的bean String scopeName = mbd.getScope(); Scope scope = (Scope)this.scopes.get(scopeName); if (scope == null) { throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'"); } try { Object scopedInstance = scope.get(beanName, () -> { this.beforePrototypeCreation(beanName); Object var4; try { var4 = this.createBean(beanName, mbd, args); } finally { this.afterPrototypeCreation(beanName); } return var4; }); bean = this.getObjectForBeanInstance(scopedInstance, name, beanName, mbd); } catch (IllegalStateException var23) { throw new BeanCreationException(beanName, "Scope '" + scopeName + "' is not active for the current thread; consider defining a scoped proxy for this bean if you intend to refer to it from a singleton", var23); } } } catch (BeansException var26) { this.cleanupAfterBeanCreationFailure(beanName); throw var26; } }//检查需要的类型是否符合bean的类型 if (requiredType != null && !requiredType.isInstance(bean)) { try { T convertedBean = this.getTypeConverter().convertIfNecessary(bean, requiredType); if (convertedBean == null) { throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass()); } else { return convertedBean; } } catch (TypeMismatchException var25) { if (this.logger.isDebugEnabled()) { this.logger.debug("Failed to convert bean '" + name + "' to required type '" + ClassUtils.getQualifiedName(requiredType) + "'", var25); } throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass()); } } else { return bean; } }

首先,通过transformedBeanName方法获取对应的beanName,因为传入的name可能是别名,可能是beanName等。这个方法的详细逻辑就略过了。获取对应的beanName之后,进入getSingleton方法,这个方法的实现在DefaultSingletonBeanRegistry类中:

@Nullable    protected Object getSingleton(String beanName, boolean allowEarlyReference) {        Object singletonObject = this.singletonObjects.get(beanName);        if (singletonObject == null && this.isSingletonCurrentlyInCreation(beanName)) {            Map var4 = this.singletonObjects;            synchronized(this.singletonObjects) {                singletonObject = this.earlySingletonObjects.get(beanName);                if (singletonObject == null && allowEarlyReference) {                    ObjectFactory
singletonFactory = (ObjectFactory)this.singletonFactories.get(beanName); if (singletonFactory != null) { singletonObject = singletonFactory.getObject(); this.earlySingletonObjects.put(beanName, singletonObject); this.singletonFactories.remove(beanName); } } } } return singletonObject; }

这段代码存在循环依赖的检测以及多处bean的缓存,首先从singletonObjects中获取,获取不到且当前单例正在创建中则从earlySingletonObjects中获取,如果还是获取不到且allowEarlyReference,则尝试获取ObjectFactory,调用其getObject方法。最后无论是否获取到都返回。回到doGetBean方法,如果获取到单例且传入的args为null,则直接调用getObjectForBeanInstance方法:

protected Object getObjectForBeanInstance(Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {//如果指定的name是以&为前缀    if (BeanFactoryUtils.isFactoryDereference(name)) {        if (beanInstance instanceof NullBean) {            return beanInstance;        }                if (!(beanInstance instanceof FactoryBean)) {            throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass());        }    }//执行到这里则表示用户传入的beanName前没有加&,如果用户想要获取factoryBean而不是getObject方法返回的实例则应该加&//如果指定的name不是以&为前缀且beanInstance是FactoryBean的实例    if (beanInstance instanceof FactoryBean && !BeanFactoryUtils.isFactoryDereference(name)) {        Object object = null;        //如果RootBeanDefinition为null,尝试从缓存中获取bean        if (mbd == null) {            object = this.getCachedObjectForFactoryBean(beanName);        }        if (object == null) {        //方法执行到这里则表示beanInstance一定是FactoryBean的实例            FactoryBean
factory = (FactoryBean)beanInstance; //如果存在BeanDefinition则获取尝试 if (mbd == null && this.containsBeanDefinition(beanName)) { mbd = this.getMergedLocalBeanDefinition(beanName); }//判断是用户自定义的还是应用程序定义的 boolean synthetic = mbd != null && mbd.isSynthetic(); //获取实例 object = this.getObjectFromFactoryBean(factory, beanName, !synthetic); }//返回 return object; //如果指定的name不是以&为前缀且beanInstance不是FactoryBean的实例,则直接返回 } else { return beanInstance; }}

这段代码主要是对name不是以&为前缀且beanInstance是FactoryBean的实例进行处理,而这个逻辑主要由FactoryBeanRegistrySupport类的getObjectFromFactoryBean方法处理:

private final Map
factoryBeanObjectCache = new ConcurrentHashMap(16);protected Object getObjectFromFactoryBean(FactoryBean
factory, String beanName, boolean shouldPostProcess) {//如果是FactoryBean是单例且当前存在实例 if (factory.isSingleton() && this.containsSingleton(beanName)) { //加锁 synchronized(this.getSingletonMutex()) { //获取实例 Object object = this.factoryBeanObjectCache.get(beanName); //获取的实例为null if (object == null) { //调用doGetObjectFromFactoryBean获取实例 object = this.doGetObjectFromFactoryBean(factory, beanName); //再次从缓存中获取实例 Object alreadyThere = this.factoryBeanObjectCache.get(beanName); if (alreadyThere != null) { object = alreadyThere; } else { //后处理 if (shouldPostProcess) { if (this.isSingletonCurrentlyInCreation(beanName)) { return object; }//单例创建前处理,主要是对DefaultSingletonBeanRegistry两缓存的维护 this.beforeSingletonCreation(beanName); try { //调用后处理器 object = this.postProcessObjectFromFactoryBean(object, beanName); } catch (Throwable var14) { throw new BeanCreationException(beanName, "Post-processing of FactoryBean's singleton object failed", var14); } finally { //单例创建后处理,主要是对DefaultSingletonBeanRegistry两缓存的维护 this.afterSingletonCreation(beanName); } } if (this.containsSingleton(beanName)) { this.factoryBeanObjectCache.put(beanName, object); } } } return object; } //FactoryBean不为单例或者当前缓存中不存在对应的bean } else { Object object = this.doGetObjectFromFactoryBean(factory, beanName); if (shouldPostProcess) { try { object = this.postProcessObjectFromFactoryBean(object, beanName); } catch (Throwable var17) { throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", var17); } } return object; }}

上面的代码主要是一些逻辑的处理,但是没有真正的获取bean,保证了单例的全局唯一性,以及非单例模式的创建。接下来进入doGetObjectFromFactoryBean方法:

private Object doGetObjectFromFactoryBean(FactoryBean
factory, String beanName) throws BeanCreationException { Object object; try { //是否需要权限验证 if (System.getSecurityManager() != null) { AccessControlContext acc = this.getAccessControlContext(); try { object = AccessController.doPrivileged(factory::getObject, acc); } catch (PrivilegedActionException var6) { throw var6.getException(); } } else { object = factory.getObject(); } } catch (FactoryBeanNotInitializedException var7) { throw new BeanCurrentlyInCreationException(beanName, var7.toString()); } catch (Throwable var8) { throw new BeanCreationException(beanName, "FactoryBean threw exception on object creation", var8); } if (object == null) { if (this.isSingletonCurrentlyInCreation(beanName)) { throw new BeanCurrentlyInCreationException(beanName, "FactoryBean which is currently in creation returned null from getObject"); }//创建NullBean实例 object = new NullBean(); } return object;}

//这个代码的逻辑比较简单,首先是判断需不需要权限,不论是否需要权限都会调factoryBean的getObject()方法,最后是对返回值为null的情况做处理,最后返回object。接下来回到getObjectFromFactoryBean方法,可以看到除了逻辑处理之外,对于单例和非单例的创建都调用了postProcessObjectFromFactoryBean方法:

protected Object postProcessObjectFromFactoryBean(Object object, String beanName) throws BeansException {    return object;}

这里的实现是直接返回object,但是在其子类AbstractAutowireCapableBeanFactory有对postProcessObjectFromFactoryBean的重写:

protected Object postProcessObjectFromFactoryBean(Object object, String beanName) {    return this.applyBeanPostProcessorsAfterInitialization(object, beanName);}public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException {   Object result = existingBean;   Object current;   for(Iterator var4 = this.getBeanPostProcessors().iterator(); var4.hasNext(); result = current) {       BeanPostProcessor processor = (BeanPostProcessor)var4.next();       current = processor.postProcessAfterInitialization(result, beanName);       if (current == null) {           return result;       }   }   return result;}

从代码来看就是对结果的处理,后处理器目前并没有接触或者使用,以后了解了再补充。接下来根据return一步一步返回上一层,回到getObjectFromFactoryBean方法,不论是哪种情况,都会在调用了postProcessObjectFromFactoryBean后进行返回。回到getObjectForBeanInstance方法,其实是根据传入的beanName和实例是否是FactoryBean类型的实例对实例进行处理。再回到doGetBean方法,接下来就是对sharedInstance为null或者args不为null两种情况的处理。跳过parentBeanFactory中获取bean的过程,直接看后面的程序,如果不仅仅是做类型检查的话,需要调用markBeanAsCreated方法对缓存进行维护:

protected void markBeanAsCreated(String beanName) {    if (!this.alreadyCreated.contains(beanName)) {        Map var2 = this.mergedBeanDefinitions;        synchronized(this.mergedBeanDefinitions) {            if (!this.alreadyCreated.contains(beanName)) {                this.clearMergedBeanDefinition(beanName);                this.alreadyCreated.add(beanName);            }        }    }}

首先isDependent以及registerDependentBean方法主要是对循环依赖的维护以及检测。for循环中主要是获取依赖的bean,主要还是调用getBean方法。将所有的依赖bean都创建完成之后才会开始当前bean的创建。首先是单例模式的创建:

sharedInstance = this.getSingleton(beanName, () -> {                        try {                            return this.createBean(beanName, mbd, args);                        } catch (BeansException var5) {                            this.destroySingleton(beanName);                            throw var5;                        }                    });

首先是调用了getSingleton方法传入beanName并且使用lambda表达式传入了一段代码,最后将返回值赋值给sharedInstance。在低版本中也可能是实例化一个接口并实现接口中的方法

private final Map
singletonObjects = new ConcurrentHashMap(256);public Object getSingleton(String beanName, ObjectFactory
singletonFactory) {//断言beanName不能为null Assert.notNull(beanName, "Bean name must not be null"); Map var3 = this.singletonObjects; synchronized(this.singletonObjects) { //现在缓存中获取 Object singletonObject = this.singletonObjects.get(beanName); if (singletonObject == null) { if (this.singletonsCurrentlyInDestruction) { throw new BeanCreationNotAllowedException(beanName, "Singleton bean creation not allowed while singletons of this factory are in destruction (Do not request a bean from a BeanFactory in a destroy method implementation!)"); } if (this.logger.isDebugEnabled()) { this.logger.debug("Creating shared instance of singleton bean '" + beanName + "'"); } this.beforeSingletonCreation(beanName); boolean newSingleton = false; boolean recordSuppressedExceptions = this.suppressedExceptions == null; if (recordSuppressedExceptions) { this.suppressedExceptions = new LinkedHashSet(); } try { singletonObject = singletonFactory.getObject(); newSingleton = true; } catch (IllegalStateException var16) { singletonObject = this.singletonObjects.get(beanName); if (singletonObject == null) { throw var16; } } catch (BeanCreationException var17) { BeanCreationException ex = var17; if (recordSuppressedExceptions) { Iterator var8 = this.suppressedExceptions.iterator(); while(var8.hasNext()) { Exception suppressedException = (Exception)var8.next(); ex.addRelatedCause(suppressedException); } } throw ex; } finally { if (recordSuppressedExceptions) { this.suppressedExceptions = null; } this.afterSingletonCreation(beanName); } if (newSingleton) { this.addSingleton(beanName, singletonObject); } } return singletonObject; }}

beforeSingletonCreation和afterSingletonCreation两个方法是对缓存的维护,还有对发生异常以及创建完后之后的缓存等逻辑,而真正的bean创建则在singletonFactory实例的getObject()方法,这里可以看到其实指正的代码调用其实是通过lambda表达式传入的代码

protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {    if (this.logger.isTraceEnabled()) {        this.logger.trace("Creating instance of bean '" + beanName + "'");    }    RootBeanDefinition mbdToUse = mbd;    //解析并获取Class对象    Class
resolvedClass = this.resolveBeanClass(mbd, beanName, new Class[0]); if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) { mbdToUse = new RootBeanDefinition(mbd); mbdToUse.setBeanClass(resolvedClass); } try { //验证及准备覆盖的方法 mbdToUse.prepareMethodOverrides(); } catch (BeanDefinitionValidationException var9) { throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(), beanName, "Validation of method overrides failed", var9); } Object beanInstance; try { //给BeanPostProcessors返回代理类替换实例的机会 beanInstance = this.resolveBeforeInstantiation(beanName, mbdToUse); //短路操作,如果创建了代理类则直接返回,这里和AOP功能有联系,这里不做分析 if (beanInstance != null) { return beanInstance; } } catch (Throwable var10) { throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "BeanPostProcessor before instantiation of bean failed", var10); } try { //创建bean beanInstance = this.doCreateBean(beanName, mbdToUse, args); if (this.logger.isTraceEnabled()) { this.logger.trace("Finished creating instance of bean '" + beanName + "'"); } return beanInstance; } catch (ImplicitlyAppearedSingletonException | BeanCreationException var7) { throw var7; } catch (Throwable var8) { throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", var8); }}

直接看prepareMethodOverrides方法,在AbstractBeanDefinition类中实现:

public void prepareMethodOverrides() throws BeanDefinitionValidationException {    if (this.hasMethodOverrides()) {        Set
overrides = this.getMethodOverrides().getOverrides(); synchronized(overrides) { Iterator var3 = overrides.iterator(); while(var3.hasNext()) { MethodOverride mo = (MethodOverride)var3.next(); this.prepareMethodOverride(mo); } } }}protected void prepareMethodOverride(MethodOverride mo) throws BeanDefinitionValidationException { int count = ClassUtils.getMethodCountForName(this.getBeanClass(), mo.getMethodName()); if (count == 0) { throw new BeanDefinitionValidationException("Invalid method override: no method with name '" + mo.getMethodName() + "' on class [" + this.getBeanClassName() + "]"); } else { if (count == 1) { //标记方法暂时未被覆盖 mo.setOverloaded(false); } }}

在定义bean的时候有两个属性,lookup-method和replace-method,这里做了部分匹配工作以及方法的存在性验证,对于重载方法还需要参数类型验证,这里并没有完成。接下来进入真正的创建bean的代码doCreateBean方法:

//存储BeanWrapperprivate final ConcurrentMap
factoryBeanInstanceCache;protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException { BeanWrapper instanceWrapper = null; //单例模式 尝试从缓存中获取 if (mbd.isSingleton()) { instanceWrapper = (BeanWrapper)this.factoryBeanInstanceCache.remove(beanName); }//instanceWrapper为null则进行创建 if (instanceWrapper == null) { instanceWrapper = this.createBeanInstance(beanName, mbd, args); }//获取实例及类型 Object bean = instanceWrapper.getWrappedInstance(); Class
beanType = instanceWrapper.getWrappedClass(); if (beanType != NullBean.class) { mbd.resolvedTargetType = beanType; }//匹配后处理器 Object var7 = mbd.postProcessingLock; synchronized(mbd.postProcessingLock) { if (!mbd.postProcessed) { try { this.applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName); } catch (Throwable var17) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Post-processing of merged bean definition failed", var17); }//允许后处理 mbd.postProcessed = true; } }//提前曝光 = 单例 & 允许循环依赖 & 当前单例正在创建中 boolean earlySingletonExposure = mbd.isSingleton() && this.allowCircularReferences && this.isSingletonCurrentlyInCreation(beanName); if (earlySingletonExposure) { if (this.logger.isTraceEnabled()) { this.logger.trace("Eagerly caching bean '" + beanName + "' to allow for resolving potential circular references"); }//在bean初始化完成前将ObjectFactory加入工厂,目的是为了解决循环依赖,通过上面的创建过程结合这里的代码,也就解释清楚了为什么不允许构造函数循环依赖 this.addSingletonFactory(beanName, () -> { //AOP就是在这里动态的织入advice的 return this.getEarlyBeanReference(beanName, mbd, bean); }); } Object exposedObject = bean; try { //属性填充,可能依赖其他bean this.populateBean(beanName, mbd, instanceWrapper); //调用初始化方法 比如init-method 这里生成的才是最终想要的bean exposedObject = this.initializeBean(beanName, exposedObject, mbd); } catch (Throwable var18) { if (var18 instanceof BeanCreationException && beanName.equals(((BeanCreationException)var18).getBeanName())) { throw (BeanCreationException)var18; } throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", var18); } if (earlySingletonExposure) { //earlySingletonReference 检测到依赖则不为null 对缓存的维护 Object earlySingletonReference = this.getSingleton(beanName, false); if (earlySingletonReference != null) { //当exposedObject等于原始的bean,说明不是proxy,则把缓存中的bean赋值给exposedObject if (exposedObject == bean) { exposedObject = earlySingletonReference; //检测其依赖的bean是否初始化完毕 } else if (!this.allowRawInjectionDespiteWrapping && this.hasDependentBean(beanName)) { String[] dependentBeans = this.getDependentBeans(beanName); Set
actualDependentBeans = new LinkedHashSet(dependentBeans.length); String[] var12 = dependentBeans; int var13 = dependentBeans.length; for(int var14 = 0; var14 < var13; ++var14) { String dependentBean = var12[var14]; if (!this.removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) { actualDependentBeans.add(dependentBean); } }//没有则抛出异常,依赖bean应该都创建好了 if (!actualDependentBeans.isEmpty()) { throw new BeanCurrentlyInCreationException(beanName, "Bean with name '" + beanName + "' has been injected into other beans [" + StringUtils.collectionToCommaDelimitedString(actualDependentBeans) + "] in its raw version as part of a circular reference, but has eventually been wrapped. This means that said other beans do not use the final version of the bean. This is often the result of over-eager type matching - consider using 'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example."); } } } } try { //注册需要销毁的bean this.registerDisposableBeanIfNecessary(beanName, bean, mbd); return exposedObject; } catch (BeanDefinitionValidationException var16) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", var16); }}

先进入createBeanInstance方法:

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {//解析Class    Class
beanClass = this.resolveBeanClass(mbd, beanName, new Class[0]); if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Bean class isn't public, and non-public access not allowed: " + beanClass.getName()); } else { //Supplier java提供的用来创造对象的接口 Supplier
instanceSupplier = mbd.getInstanceSupplier(); if (instanceSupplier != null) { return this.obtainFromSupplier(instanceSupplier, beanName); //工厂方法不为空则使用工厂方法 } else if (mbd.getFactoryMethodName() != null) { return this.instantiateUsingFactoryMethod(beanName, mbd, args); } else { //根据构造方法创建 boolean resolved = false; boolean autowireNecessary = false; //无参 if (args == null) { Object var8 = mbd.constructorArgumentLock; synchronized(mbd.constructorArgumentLock) { if (mbd.resolvedConstructorOrFactoryMethod != null) { resolved = true; autowireNecessary = mbd.constructorArgumentsResolved; } } }//带参 //已解析 if (resolved) { //是否使用构造函数注入?构造函数注入:默认函数注入 return autowireNecessary ? this.autowireConstructor(beanName, mbd, (Constructor[])null, (Object[])null) : this.instantiateBean(beanName, mbd); //未解析 } else { //根据需要的参数解析构造函数 Constructor
[] ctors = this.determineConstructorsFromBeanPostProcessors(beanClass, beanName); if (ctors == null && mbd.getResolvedAutowireMode() != 3 && !mbd.hasConstructorArgumentValues() && ObjectUtils.isEmpty(args)) { ctors = mbd.getPreferredConstructors(); return ctors != null ? this.autowireConstructor(beanName, mbd, ctors, (Object[])null) : this.instantiateBean(beanName, mbd); } else { return this.autowireConstructor(beanName, mbd, ctors, args); } } } }}

autowireConstructor方法代码量非常大,但是总体来说做了两件事,确定构造函数,调用实例化策略的instantiateBean方法创建实例并加入到BeanWrapper中。而instantiateBean同样也是调用了实例化策略的instantiateBean方法:

protected BeanWrapper instantiateBean(String beanName, RootBeanDefinition mbd) {try {    Object beanInstance;    if (System.getSecurityManager() != null) {        beanInstance = AccessController.doPrivileged(() -> {            return thisx.getInstantiationStrategy().instantiate(mbd, beanName, this);        }, this.getAccessControlContext());    } else {        beanInstance = this.getInstantiationStrategy().instantiate(mbd, beanName, this);    }    BeanWrapper bw = new BeanWrapperImpl(beanInstance);    this.initBeanWrapper(bw);    return bw;} catch (Throwable var6) {    throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Instantiation of bean failed", var6);}}

首先看实例化策略,也就是getInstantiationStrategy方法,在AbstractAutowireCapableBeanFactory类中:

private InstantiationStrategy instantiationStrategy;//无参构造中的语句this.instantiationStrategy = new CglibSubclassingInstantiationStrategy();public void setInstantiationStrategy(InstantiationStrategy instantiationStrategy) {this.instantiationStrategy = instantiationStrategy;}protected InstantiationStrategy getInstantiationStrategy() {return this.instantiationStrategy;}

显而意见,如果用户不去设置,则默认的就是CglibSubclassingInstantiationStrategy类的实例,而CglibSubclassingInstantiationStrategy则是SimpleInstantiationStrategy类的子类,instantiate也是在SimpleInstantiationStrategy类中实现的:

public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {//如果用户配置了lookup-method或者replace-mathed 则创建代理// 没有则进行反射    if (!bd.hasMethodOverrides()) {        Object var5 = bd.constructorArgumentLock;        Constructor constructorToUse;        //解析并获取构造函数        synchronized(bd.constructorArgumentLock) {            constructorToUse = (Constructor)bd.resolvedConstructorOrFactoryMethod;            if (constructorToUse == null) {                Class
clazz = bd.getBeanClass(); if (clazz.isInterface()) { throw new BeanInstantiationException(clazz, "Specified class is an interface"); } try { if (System.getSecurityManager() != null) { clazz.getClass(); constructorToUse = (Constructor)AccessController.doPrivileged(() -> { return clazz.getDeclaredConstructor(); }); } else { constructorToUse = clazz.getDeclaredConstructor(); } bd.resolvedConstructorOrFactoryMethod = constructorToUse; } catch (Throwable var9) { throw new BeanInstantiationException(clazz, "No default constructor found", var9); } } }//调用BeanUtils的instantiateClass方法 return BeanUtils.instantiateClass(constructorToUse, new Object[0]); } else { //其实是个抛异常的方法,但是子类CglibSubclassingInstantiationStrategy实现了重写 return this.instantiateWithMethodInjection(bd, beanName, owner); }}

反射的具体过程这里就不看了,直接进入CglibSubclassingInstantiationStrategy类重写的instantiateWithMethodInjection方法:

protected Object instantiateWithMethodInjection(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {    return this.instantiateWithMethodInjection(bd, beanName, owner, (Constructor)null);}protected Object instantiateWithMethodInjection(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner, @Nullable Constructor
ctor, Object... args) { return (new CglibSubclassingInstantiationStrategy.CglibSubclassCreator(bd, owner)).instantiate(ctor, args);}public Object instantiate(@Nullable Constructor
ctor, Object... args) {//创建代理类 Class
subclass = this.createEnhancedSubclass(this.beanDefinition); //实例化 Object instance; if (ctor == null) { instance = BeanUtils.instantiateClass(subclass); } else { try { Constructor
enhancedSubclassConstructor = subclass.getConstructor(ctor.getParameterTypes()); instance = enhancedSubclassConstructor.newInstance(args); } catch (Exception var6) { throw new BeanInstantiationException(this.beanDefinition.getBeanClass(), "Failed to invoke constructor for CGLIB enhanced subclass [" + subclass.getName() + "]", var6); } }//设置拦截器增强 Factory factory = (Factory)instance; factory.setCallbacks(new Callback[]{NoOp.INSTANCE, new CglibSubclassingInstantiationStrategy.LookupOverrideMethodInterceptor(this.beanDefinition, this.owner), new CglibSubclassingInstantiationStrategy.ReplaceOverrideMethodInterceptor(this.beanDefinition, this.owner)}); //返回代理实例 return instance;}

上面已经基本讲完了bean的实例化,但是依赖注入还没将,autowire在什么时候被使用了,这个需要看该方法: //属性填充,可能依赖其他bean this.populateBean(beanName, mbd, instanceWrapper);该方法在上面的doCreateBean方法中。

接下来就是分析该方法到底干了什么东东了,this.populateBean(beanName, mbd, instanceWrapper);

转载地址:http://ousoi.baihongyu.com/

你可能感兴趣的文章
.NET Interop: 从IErrorInfo错误对象获得托管代码的异常信息
查看>>
Microsoft Silverlight正式发布
查看>>
国际化编程中Locale相关概念的一些解释
查看>>
PIA (Primary Interop Assembly) & AIA (Alternate Interop Assembly)简介
查看>>
“妖精”团队———阿里巴巴
查看>>
迟到的感谢——2006最有价值博客的候选人(& 个人回顾)
查看>>
第29回 软件质量度量
查看>>
IT 2007预言
查看>>
怎样让.Net2.0的Membership使用已存在的Sql Server2000/2005数据库
查看>>
ASP.NET2.0 文本编辑器FCKeditor使用方法详解
查看>>
常见的 Web 项目转换问题及解决方案
查看>>
VS2005中使用ClickOnce 部署应用程序的升级
查看>>
Visual Studio2005下配置及运行NUnit
查看>>
.Net Remoting配置文件的用法
查看>>
Tomcat性能调整优化
查看>>
利用SQL Server 2005减轻生产服务器优化负荷
查看>>
优化MYSQL服务器
查看>>
Exchange磁盘性能优化
查看>>
Apusic应用服务器的性能调节_JVM优化
查看>>
Apache重负荷服务器应如何优化?
查看>>