【Spring】源码浅析IOC容器依赖注入

前言:

        本文较长,源码部分已经只查看主枝,如果阅读本文,希望打开idealJ穿透源码阅读更加容易理解。

正文:

一、举例:

写一个简单的ioc依赖注入

1.1、写一个简单的Bean:

public class SpringTest {
    public static void main(String[] args){
        ApplicationContext context = new ClassPathXmlApplicationContext("conf/test-bean.xml");
        TestBean testBean = (TestBean) context.getBean("tBean");
        System.out.println("----------------"+testBean.toString()+"----------------");
    }
}

1.2、Bean模型如下:

public class TestBean {
    private String name;
    private String password;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    @Override
    public String toString() {
        return "TestBean{" +
                "name='" + name + '\'' +
                ", password='" + password + '\'' +
                '}';
    }
}

1.3、xml配置:



       
           
           
       

1.4、结果如下:

TestBean{name='haibo666', password='666pwd'}

二、源码分析总纲:

2.1、根据xml配置生成ApplicationContext实例:

ApplicationContext context = new ClassPathXmlApplicationContext("conf/test-bean.xml");

2.2、根据上面生成的ApplicationContext实例获取/生成需要的Bean实例对象:

TestBean testBean = (TestBean) context.getBean("tBean");

三、ioc依赖注入思路:

依赖注入主要发生在2.1代码位置:流程如下

conf/test-bean.xml个人配置——》生成FactoryBean的定义模版——》通过FactoryBean模版生成实例化对象——》对象注入属性值

四、源码分析(粗略)

先看一个类图ApplicationContext:可以知道ApplicationContext接口继承自BeanFactory:也就是生成ApplicationContext实例就是生成一个BeanFactory对象。

【Spring】源码浅析IOC容器依赖注入_第1张图片

先看2.1的代码:

ApplicationContext context = new ClassPathXmlApplicationContext("conf/test-bean.xml");

跟进代码,查看ClassPathXmlApplicationContext构造方法

public ClassPathXmlApplicationContext(String configLocation) throws BeansException {
		this(new String[] {configLocation}, true, null);
	}
public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)
			throws BeansException {
		super(parent);
		setConfigLocations(configLocations);
		if (refresh) {
			refresh();
		}
	}

备注一:其中setConfigLocations:AbstractRefreshableConfigApplicationContext#configLocations属性赋值。

主要关注第二个方法refresh:这个方法很重要。后称 代码零

public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
			// Prepare this context for refreshing.
			prepareRefresh();

			// Tell the subclass to refresh the internal bean factory.
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

			// Prepare the bean factory for use in this context.
			prepareBeanFactory(beanFactory);

			try {
				// Allows post-processing of the bean factory in context subclasses.
				postProcessBeanFactory(beanFactory);

				// Invoke factory processors registered as beans in the context.
				invokeBeanFactoryPostProcessors(beanFactory);

				// Register bean processors that intercept bean creation.
				registerBeanPostProcessors(beanFactory);

				// Initialize message source for this context.
				initMessageSource();

				// Initialize event multicaster for this context.
				initApplicationEventMulticaster();

				// Initialize other special beans in specific context subclasses.
				onRefresh();

				// Check for listener beans and register them.
				registerListeners();

				// Instantiate all remaining (non-lazy-init) singletons.
				finishBeanFactoryInitialization(beanFactory);

				// Last step: publish corresponding event.
				finishRefresh();
			}

			catch (BeansException ex) {
				略
			}

			finally {
				略
			}
		}
	}

简化版代码零:上述代码简化如下:只剩下2行代码(只读骨架不深究其它)

// Tell the subclass to refresh the internal bean factory.
//1、根据xml生成BeanFactory模版
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Instantiate all remaining (non-lazy-init) singletons.
//2、根据BeanFactory模版生成实例bean对象
finishBeanFactoryInitialization(beanFactory);

五、源码分析(详细):根据xml生成BeanFactory模版

简化版代码零:obtainFreshBeanFactory

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

代码说明:

这个代码比较容易理解。

第2行:生成/刷新BeanFactory模版;

第3行:将返回值指向上面生成的beanFactory模版(主要后续会通过这个beanFactory生成实例)。

所以,我只需要看第2行代码就可以。

第2行代码:refreshBeanFactory

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

第一块代码(if hasBeanFactory判断处):如果以前存在beanFactory就关闭。此处可忽略。

第二块DefaultListableBeanFactory beanFactory = createBeanFactory();创建了一个DefaultListableBeanFactory实例。也就是BeanFactory实例,并未给属性赋值。此处以后代称 代码一

【Spring】源码浅析IOC容器依赖注入_第2张图片

直接看这行代码:loadBeanDefinitions(beanFactory);见名知意:加载Bean的定义,也就是我所说的生成BeanFactory模版。

子类的loadBeanDefinitions:

protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
		// Create a new XmlBeanDefinitionReader for the given BeanFactory.
		XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);

		// Configure the bean definition reader with this context's
		// resource loading environment.
		beanDefinitionReader.setEnvironment(this.getEnvironment());
		beanDefinitionReader.setResourceLoader(this);
		beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));

		// Allow a subclass to provide custom initialization of the reader,
		// then proceed with actually loading the bean definitions.
		initBeanDefinitionReader(beanDefinitionReader);
		loadBeanDefinitions(beanDefinitionReader);
	}

其中生成了一个xmlBeanDefinitionReader:可以理解为新建了一个通过xml生成Bean的模版的输入流实例。

最后一行loadBeanDefinitions:

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

然后经过一系列的同名方法loadBeanDefinitions(后续会分析这一系列同名载入bean模版主要做了些什么)

最终会到达XmlBeanDefinitionReader#loadBeanDefinitions:

public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
		略
		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();
			}
		}
		略
	}

其中这一行代码生成了一个输入流:

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

有人可能会问encodedResource哪来的?

之前一系列的loadBeanDefinitions同名方法中存在这样的转换

从一个加载xml文件而来:主要为以下两个操作;

(1)location---》resource

(2)resource---》EncodedResource:而这个就是上面的encodedResource。

操作(1)部分代码如下

Resource[] resources = ((ResourcePatternResolver) resourceLoader).getResources(location);
				int loadCount = loadBeanDefinitions(resources);

操作(2)部分代码如下

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

回到之前代码:看看对输入流做了什么操作。

InputStream inputStream = encodedResource.getResource().getInputStream();
			try {
				InputSource inputSource = new InputSource(inputStream);
				if (encodedResource.getEncoding() != null) {
					inputSource.setEncoding(encodedResource.getEncoding());
				}
				return doLoadBeanDefinitions(inputSource, encodedResource.getResource());
			}

其中doLoadBeanDefinitions:此处代码非常重要。重要的事说三遍!非常重要!非常重要!非常重要!

此处根据我们自己的xml---》转换成流---》生成了一个Document对象。Document可以理解为一个文档树的根,并提供对文档树的访问。

protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
			throws BeanDefinitionStoreException {
		try {
			Document doc = doLoadDocument(inputSource, resource);
			return registerBeanDefinitions(doc, resource);
		}
		catch (xxException ex) {
			略
		}
	}

registerBeanDefinitions:就是文档树Document对象—》BeanDefinitionDocumentReader :

即将Document的每一个叶子节点都注册为一个Bean模版。

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

跟进此处registerBeanDefinitions:

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

跟进此处doRegisterBeanDefinitions:

protected void doRegisterBeanDefinitions(Element root) {
		略
		preProcessXml(root);
		parseBeanDefinitions(root, this.delegate);
		postProcessXml(root);
		略
	}

跟进此处parseBeanDefinitions:

protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
		if (delegate.isDefaultNamespace(root)) {
			NodeList nl = root.getChildNodes();
			for (int i = 0; i < nl.getLength(); i++) {
				Node node = nl.item(i);
				if (node instanceof Element) {
					Element ele = (Element) node;
					if (delegate.isDefaultNamespace(ele)) {
						parseDefaultElement(ele, delegate);
					}
					else {
						delegate.parseCustomElement(ele);
					}
				}
			}
		}
		else {
			delegate.parseCustomElement(root);
		}
	}

到此我们获得了解析Document的某一个元素的方法:默认标签解析和自定义标签的解析(我们只分析默认标签解析方法)parseDefaultElement:对应四种默认标签import,alias,bean,beans,是否非常熟悉?

private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
		if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {
			importBeanDefinitionResource(ele);
		}
		else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) {
			processAliasRegistration(ele);
		}
		else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {
			processBeanDefinition(ele, delegate);
		}
		else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {
			// recurse
			doRegisterBeanDefinitions(ele);
		}
	}

查看其中最常见最小的bean解析代码processBeanDefinition:

代码二

此处分解成两个操作:

1、解析document的元素element成为一个Bean定义模版BeanDefinitionHolder;

2、将这个Bean定义模版BeanDefinitionHolder注册到BeanDefinitionReaderUtils;

注册到此处BeanDefinitionReaderUtils到底注册到哪了?实际是给DefaultListableBeanFactory的两个属性赋值

先分析第一个操作:1、解析document的元素element成为一个Bean定义模版BeanDefinitionHolder;

protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
		BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
		if (bdHolder != null) {
			bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
			try {
				// Register the final decorated instance.
				BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
			}
			catch (BeanDefinitionStoreException ex) {
				getReaderContext().error("Failed to register bean definition with name '" +
						bdHolder.getBeanName() + "'", ele, ex);
			}
			// Send registration event.
			getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
		}
	}

第2行代码:解析bean的具体代码如下:

public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, BeanDefinition containingBean) {
		String id = ele.getAttribute(ID_ATTRIBUTE);
		String nameAttr = ele.getAttribute(NAME_ATTRIBUTE);
		List aliases = new ArrayList();
		if (StringUtils.hasLength(nameAttr)) {
			String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, MULTI_VALUE_ATTRIBUTE_DELIMITERS);
			aliases.addAll(Arrays.asList(nameArr));
		}
		String beanName = id;
		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");
			}
		}
		if (containingBean == null) {
			checkNameUniqueness(beanName, aliases, ele);
		}
		AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean);
		if (beanDefinition != null) {
			if (!StringUtils.hasText(beanName)) {
				try {
					if (containingBean != null) {
						beanName = BeanDefinitionReaderUtils.generateBeanName(
								beanDefinition, this.readerContext.getRegistry(), true);
					}
					else {
						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.
						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);
		}
		return null;
	}
首先获得id和name属性,然后如果有别名如何处理,如果不是别名,则生成一个bean自定义模版:
AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean);

返回模版对象:

return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray);

再分析第二个操作:2、将这个Bean定义模版BeanDefinitionHolder注册到BeanDefinitionReaderUtils;

用上述代码得到的这个bean的模版对象,注册到BeanDefinitionReaderUtils:

BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
PS:其中registerBeanDefinition究竟注册到哪了呢?继续跟进代码:
public static void registerBeanDefinition(
			BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
			throws BeanDefinitionStoreException {
		// Register bean definition under primary name.
		String beanName = definitionHolder.getBeanName();
		registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
		// Register aliases for bean name, if any.
		String[] aliases = definitionHolder.getAliases();
		if (aliases != null) {
			for (String alias : aliases) {
				registry.registerAlias(beanName, alias);
			}
		}
	}

注册最后到此registerBeanDefinition:

关键代码为以下2行设置属性。将beanName(bean名称)和beanDefinition(bean模版)属性赋值。

这两个值赋值也就是给DefaultListableBeanFactory赋值。饶了一大圈就是为了赋值DefaultListableBeanFactory的这两个属性,回看代码一可知此处DefaultListableBeanFactory的主要赋值已经完成:即根据我们xml文件生成的beanFactory模版已经完成。

public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
			throws BeanDefinitionStoreException {
                        略
				// Still in startup registration phase
				this.beanDefinitionMap.put(beanName, beanDefinition);
				this.beanDefinitionNames.add(beanName);
			略
	}

ok,BeanFactory模版生成,属性配好,留作后用。

六、源码分析(详细):根据BeanFactory模版生成实例bean对象及依赖注入属性值

回到简化版代码零,查看代码零中finishBeanFactoryInitialization:翻译为完成BeanFactory初始化:

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
		// Initialize conversion service for this context.
		if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
				beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
			beanFactory.setConversionService(
					beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
		}
		// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
		String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
		for (String weaverAwareName : weaverAwareNames) {
			getBean(weaverAwareName);
		}
		// Stop using the temporary ClassLoader for type matching.
		beanFactory.setTempClassLoader(null);
		// Allow for caching all bean definition metadata, not expecting further changes.
		beanFactory.freezeConfiguration();
		// Instantiate all remaining (non-lazy-init) singletons.
		beanFactory.preInstantiateSingletons();
	}

跟进最后1行代码beanFactory.preInstantiateSingletons():BeanFactory模版实例化(非懒加载的实例)。

public void preInstantiateSingletons() throws BeansException {
		if (this.logger.isDebugEnabled()) {
			this.logger.debug("Pre-instantiating singletons in " + this);
		}

		// Iterate over a copy to allow for init methods which in turn register new bean definitions.
		// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
		List beanNames = new ArrayList(this.beanDefinitionNames);

		// Trigger initialization of all non-lazy singleton beans...
		for (String beanName : beanNames) {
			RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
			if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
				if (isFactoryBean(beanName)) {
					final FactoryBean factory = (FactoryBean) getBean(FACTORY_BEAN_PREFIX + beanName);
					boolean isEagerInit;
					if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
						isEagerInit = AccessController.doPrivileged(new PrivilegedAction() {
							@Override
							public Boolean run() {
								return ((SmartFactoryBean) factory).isEagerInit();
							}
						}, getAccessControlContext());
					}
					else {
						isEagerInit = (factory instanceof SmartFactoryBean &&
								((SmartFactoryBean) factory).isEagerInit());
					}
					if (isEagerInit) {
						getBean(beanName);
					}
				}
				else {
					getBean(beanName);
				}
			}
		}

		// Trigger post-initialization callback for all applicable beans...
		for (String beanName : beanNames) {
			Object singletonInstance = getSingleton(beanName);
			if (singletonInstance instanceof SmartInitializingSingleton) {
				final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
				if (System.getSecurityManager() != null) {
					AccessController.doPrivileged(new PrivilegedAction() {
						@Override
						public Object run() {
							smartSingleton.afterSingletonsInstantiated();
							return null;
						}
					}, getAccessControlContext());
				}
				else {
					smartSingleton.afterSingletonsInstantiated();
				}
			}
		}
	} 
  

1、DefaultListableBeanFactory#beanDefinitionNames(BeanFactory模版定义源码分析最后已对该属性赋值)获得beanName的列表:List beanNames = new ArrayList(this.beanDefinitionNames);

2、beanName非抽象,是单例模式,不是懒加载---》beanName是factoryBean,则生成factoryBean实例。如果beanName不是factoryBean类型,则执行getBean(beanName);

@Override
public Object getBean(String name) throws BeansException {
		return doGetBean(name, null, null, false);
	}

doGetBean此处代码量有些大,但逻辑还是很清晰:大概意思就是根据不同条件生成Bean对象。

protected  T doGetBean(
			final String name, final Class requiredType, final Object[] args, boolean typeCheckOnly)
			throws BeansException {

		final String beanName = transformedBeanName(name);
		Object bean;

		// Eagerly check singleton cache for manually registered singletons.
		Object sharedInstance = getSingleton(beanName);
		if (sharedInstance != null && args == null) {
			if (logger.isDebugEnabled()) {
				if (isSingletonCurrentlyInCreation(beanName)) {
					logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
							"' that is not fully initialized yet - a consequence of a circular reference");
				}
				else {
					logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
				}
			}
			bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
		}

		else {
			// Fail if we're already creating this bean instance:
			// We're assumably within a circular reference.
			if (isPrototypeCurrentlyInCreation(beanName)) {
				throw new BeanCurrentlyInCreationException(beanName);
			}

			// Check if bean definition exists in this factory.
			BeanFactory parentBeanFactory = getParentBeanFactory();
			if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
				// Not found -> check parent.
				String nameToLookup = originalBeanName(name);
				if (args != null) {
					// Delegation to parent with explicit args.
					return (T) parentBeanFactory.getBean(nameToLookup, args);
				}
				else {
					// No args -> delegate to standard getBean method.
					return parentBeanFactory.getBean(nameToLookup, requiredType);
				}
			}

			if (!typeCheckOnly) {
				markBeanAsCreated(beanName);
			}

			try {
				final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
				checkMergedBeanDefinition(mbd, beanName, args);

				// Guarantee initialization of beans that the current bean depends on.
				String[] dependsOn = mbd.getDependsOn();
				if (dependsOn != null) {
					for (String dependsOnBean : dependsOn) {
						if (isDependent(beanName, dependsOnBean)) {
							throw new BeanCreationException(mbd.getResourceDescription(), beanName,
									"Circular depends-on relationship between '" + beanName + "' and '" + dependsOnBean + "'");
						}
						registerDependentBean(dependsOnBean, beanName);
						getBean(dependsOnBean);
					}
				}

				// Create bean instance.
				if (mbd.isSingleton()) {
					sharedInstance = getSingleton(beanName, new ObjectFactory() {
						@Override
						public Object getObject() throws BeansException {
							try {
								return createBean(beanName, mbd, args);
							}
							catch (BeansException ex) {
								// Explicitly remove instance from singleton cache: It might have been put there
								// eagerly by the creation process, to allow for circular reference resolution.
								// Also remove any beans that received a temporary reference to the bean.
								destroySingleton(beanName);
								throw ex;
							}
						}
					});
					bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
				}

				else if (mbd.isPrototype()) {
					// It's a prototype -> create a new instance.
					Object prototypeInstance = null;
					try {
						beforePrototypeCreation(beanName);
						prototypeInstance = createBean(beanName, mbd, args);
					}
					finally {
						afterPrototypeCreation(beanName);
					}
					bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
				}

				else {
					String scopeName = mbd.getScope();
					final 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, new ObjectFactory() {
							@Override
							public Object getObject() throws BeansException {
								beforePrototypeCreation(beanName);
								try {
									return createBean(beanName, mbd, args);
								}
								finally {
									afterPrototypeCreation(beanName);
								}
							}
						});
						bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
					}
					catch (IllegalStateException ex) {
						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",
								ex);
					}
				}
			}
			catch (BeansException ex) {
				cleanupAfterBeanCreationFailure(beanName);
				throw ex;
			}
		}

		// Check if required type matches the type of the actual bean instance.
		if (requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass())) {
			try {
				return getTypeConverter().convertIfNecessary(bean, requiredType);
			}
			catch (TypeMismatchException ex) {
				if (logger.isDebugEnabled()) {
					logger.debug("Failed to convert bean '" + name + "' to required type [" +
							ClassUtils.getQualifiedName(requiredType) + "]", ex);
				}
				throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
			}
		}
		return (T) bean;
	} 
  

大概流程如下:

1、别名判断final String beanName = transformedBeanName(name);,别名则解析为真实名称。

2、Object sharedInstance = getSingleton(beanName);查看单例对象是否已经被实例化来判断是否需要实例化。如果不需要实例化,则直接从缓存中获取bean对象。

3、需要实例化,则继续。BeanFactory parentBeanFactory = getParentBeanFactory();检查是否存在父工厂类对象存在。存在,则从父类工厂对象获取bean对象。

4、String[] dependsOn = mbd.getDependsOn();检查需要生成bean依赖关系,如果存在依赖,则先生成依赖对象bean。没有,则继续。

5、在DefaultListableBeanFactory#beanDefinitionMap中已经建立了beanName和BeanFactory(此处为RootBeanDefinition)的关系。通过final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);获取到BeanFactory定义模版。

当BeanFactory定义模版mbd是单例模式的时候,直接尝试获取实例化对象。

sharedInstance = getSingleton(beanName, new ObjectFactory() {
						@Override
						public Object getObject() throws BeansException {
							try {
								return createBean(beanName, mbd, args);
							}
							catch (BeansException ex) {
								// Explicitly remove instance from singleton cache: It might have been put there
								// eagerly by the creation process, to allow for circular reference resolution.
								// Also remove any beans that received a temporary reference to the bean.
								destroySingleton(beanName);
								throw ex;
							}
						}
					}); 
  

直接从Object singletonObject = this.singletonObjects.get(beanName);尝试获取实例化对象,如果获取到则直接返回,没获取到,则需要Override的getObject方法中创建Bean实例的方法createBean(beanName, mbd, args);此处已经用到BeanFactroy模版和BeanName生成Bean对象。

6、mdb非单例模式,是原型的时候,其代码判断为mbd.isSingleton():创建BeanFactory模版的实例,代码如prototypeInstance = createBean(beanName, mbd, args);

7、mdb其它类型,调用自动装配工厂产生该bean对象的实例。createBean(beanName, mbd, args)

既然5、6、7步都是调用创建方法:createBean(beanName, mbd, args)根据Beanfactory模型创建bean对象。跟进createBean(beanName, mbd, args)如下:

AbstractAutowireCapableBeanFactory#createBean

@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
		略
		Object beanInstance = doCreateBean(beanName, mbdToUse, args);
		略
		return beanInstance;
	}

跟进doCreateBean方法:一大波代码,简化后如下,

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) {
		// Instantiate the bean.
		BeanWrapper instanceWrapper = null;
		if (mbd.isSingleton()) {
			instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
		}
		if (instanceWrapper == null) {
			instanceWrapper = createBeanInstance(beanName, mbd, args);
		}
		final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
		Class beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);
		略
		// Initialize the bean instance.
		Object exposedObject = bean;
		略
		return exposedObject;
	}

很清晰的直接看到创建Bean对象代码instanceWrapper = createBeanInstance(beanName, mbd, args);只留下主干代码。

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {
		// Make sure bean class is actually resolved at this point.
		Class beanClass = resolveBeanClass(mbd, beanName);
		略
		// Need to determine the constructor...
		Constructor[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
		if (ctors != null ||
				mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
				mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args))  {
			return autowireConstructor(beanName, mbd, ctors, args);
		}

		// No special handling: simply use no-arg constructor.
		return instantiateBean(beanName, mbd);
	}

操作1:如果有构造方法,及构造方法属性值等,则获得构造方法的定义,实例化bean对象并注入属性值。autowireConstructor(beanName, mbd, ctors, args);

操作2:其它,则默认初始化bean。instantiateBean(beanName, mbd);

操作1 具体代码分析:

跟进autowireConstructor到ConstructorResolver#autowireConstructor:

public BeanWrapper autowireConstructor(final String beanName, final RootBeanDefinition mbd,
			Constructor[] chosenCtors, final Object[] explicitArgs) {

		BeanWrapperImpl bw = new BeanWrapperImpl();
		this.beanFactory.initBeanWrapper(bw);

		Constructor constructorToUse = null;
		ArgumentsHolder argsHolderToUse = null;
		Object[] argsToUse = null;
此处略去参数组装代码一大堆
		try {
			Object beanInstance;

			if (System.getSecurityManager() != null) {
				final Constructor ctorToUse = constructorToUse;
				final Object[] argumentsToUse = argsToUse;
				beanInstance = AccessController.doPrivileged(new PrivilegedAction() {
					@Override
					public Object run() {
						return beanFactory.getInstantiationStrategy().instantiate(
								mbd, beanName, beanFactory, ctorToUse, argumentsToUse);
					}
				}, beanFactory.getAccessControlContext());
			}
			else {
				beanInstance = this.beanFactory.getInstantiationStrategy().instantiate(
						mbd, beanName, this.beanFactory, constructorToUse, argsToUse);
			}

			bw.setWrappedInstance(beanInstance);
			return bw;
		}
		catch (Throwable ex) {
			throw new BeanCreationException(mbd.getResourceDescription(), beanName,
					"Bean instantiation via constructor failed", ex);
		}
	} 
  

最终都到这个代码处生成bean对象实例:

beanInstance = this.beanFactory.getInstantiationStrategy().instantiate(
						mbd, beanName, this.beanFactory, constructorToUse, argsToUse);

跟进代码instantiate方法:

此处有两种生成Object的方式先看第一种:BeanFactory定义中,方法覆盖为空的时候——》BeanUtils.instantiateClass(ctor, args) 代称代码三

public Object instantiate(RootBeanDefinition bd, String beanName, BeanFactory owner,
			final Constructor ctor, Object... args) {

		if (bd.getMethodOverrides().isEmpty()) {
			if (System.getSecurityManager() != null) {
				// use own privileged to change accessibility (when security is on)
				AccessController.doPrivileged(new PrivilegedAction() {
					@Override
					public Object run() {
						ReflectionUtils.makeAccessible(ctor);
						return null;
					}
				});
			}
			return BeanUtils.instantiateClass(ctor, args);
		}
		else {
			return instantiateWithMethodInjection(bd, beanName, owner, ctor, args);
		}
	} 
  

跟进instantiateClass方法代码:看到构造方法的newInstance,其中构造方法的参数为args。

public static  T instantiateClass(Constructor ctor, Object... args) throws BeanInstantiationException {
		Assert.notNull(ctor, "Constructor must not be null");
		try {
			ReflectionUtils.makeAccessible(ctor);
			return ctor.newInstance(args);
		}
		catch (XXException ex) {
			略
		}
	}

操作2具体代码分析:

跟进instantiateBean方法:

protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
		try {
			Object beanInstance;
			final BeanFactory parent = this;
			if (System.getSecurityManager() != null) {
				beanInstance = AccessController.doPrivileged(new PrivilegedAction() {
					@Override
					public Object run() {
						return getInstantiationStrategy().instantiate(mbd, beanName, parent);
					}
				}, getAccessControlContext());
			}
			else {
				beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
			}
			BeanWrapper bw = new BeanWrapperImpl(beanInstance);
			initBeanWrapper(bw);
			return bw;
		}
		catch (Throwable ex) {
			throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
		}
	} 
  

两分支都最终进入同一个初始化代码块,跟进getInstantiationStrategy().instantiate(mbd, beanName, parent)代码:

此处有两种生成Object的方式先看第一种:BeanFactory定义中,方法覆盖为空的时候——》BeanUtils.instantiateClass(ctor, args)

@Override
public Object instantiate(RootBeanDefinition bd, String beanName, BeanFactory owner) {
		// Don't override the class with CGLIB if no overrides.
		if (bd.getMethodOverrides().isEmpty()) {
			Constructor constructorToUse;
			synchronized (bd.constructorArgumentLock) {
				constructorToUse = (Constructor) bd.resolvedConstructorOrFactoryMethod;
				if (constructorToUse == null) {
					final Class clazz = bd.getBeanClass();
					if (clazz.isInterface()) {
						throw new BeanInstantiationException(clazz, "Specified class is an interface");
					}
					try {
						if (System.getSecurityManager() != null) {
							constructorToUse = AccessController.doPrivileged(new PrivilegedExceptionAction>() {
								@Override
								public Constructor run() throws Exception {
									return clazz.getDeclaredConstructor((Class[]) null);
								}
							});
						}
						else {
							constructorToUse =	clazz.getDeclaredConstructor((Class[]) null);
						}
						bd.resolvedConstructorOrFactoryMethod = constructorToUse;
					}
					catch (Exception ex) {
						throw new BeanInstantiationException(clazz, "No default constructor found", ex);
					}
				}
			}
			return BeanUtils.instantiateClass(constructorToUse);
		}
		else {
			// Must generate CGLIB subclass.
			return instantiateWithMethodInjection(bd, beanName, owner);
		}
	}

同构造方法的初始化bean,最后也是调用BeanUtils.instantiateClass(constructorToUse)。

上面两次提到“BeanFactory定义中,方法覆盖为空的时候——》BeanUtils.instantiateClass(ctor, args) ”,回到代码三,现在看另一个分支,当方法覆盖不为空的时候,执行instantiateWithMethodInjection(bd, beanName, owner, ctor, args):

@Override
protected Object instantiateWithMethodInjection(RootBeanDefinition bd, String beanName, BeanFactory owner,
			Constructor ctor, Object... args) {

		// Must generate CGLIB subclass...
		return new CglibSubclassCreator(bd, owner).instantiate(ctor, args);
	}

跟进instantiate代理的这个方法:方法很简单,也是在构造方法时注入的args属性。

public Object instantiate(Constructor ctor, Object... args) {
			Class subclass = createEnhancedSubclass(this.beanDefinition);
			Object instance;
			if (ctor == null) {
				instance = BeanUtils.instantiate(subclass);
			}
			else {
				try {
					Constructor enhancedSubclassConstructor = subclass.getConstructor(ctor.getParameterTypes());
					instance = enhancedSubclassConstructor.newInstance(args);
				}
				catch (Exception ex) {
					throw new BeanInstantiationException(this.beanDefinition.getBeanClass(),
							"Failed to invoke constructor for CGLIB enhanced subclass [" + subclass.getName() + "]", ex);
				}
			}
			// SPR-10785: set callbacks directly on the instance instead of in the
			// enhanced class (via the Enhancer) in order to avoid memory leaks.
			Factory factory = (Factory) instance;
			factory.setCallbacks(new Callback[] {NoOp.INSTANCE,
					new LookupOverrideMethodInterceptor(this.beanDefinition, this.owner),
					new ReplaceOverrideMethodInterceptor(this.beanDefinition, this.owner)});
			return instance;
		}
本文完,感谢阅读,望指正。





















你可能感兴趣的:(源码,spring,java)