看到一篇好文章http://www.jianshu.com/p/524748c83dde,所以自己也跟着走了一遍。
实例
首先创建一个maven项目,引入spring的几个jar包
application.xml
HelloWorld
测试类
IOC容器初始化过程
根据上面的例子去理解IoC容器初始化过程:
初始化总过程:
- 资源定位(确定工厂创建和bean的配置文件)
- 资源装载(在文件系统路径上对IOC配置文件、bean配置进行加载)
- 资源解析(解析bean配置,解析xml元素)
- 生成bean(根据DOM资源解析成bean)
- 在IoC容器中注册(交给IoC容器管理,还有依赖注入的权限)
资源定位
ApplicationContext ac = new ClassPathXmlApplicationContext("application.xml");
首先跟进去看看这段代码
继续走
public void refresh() throws BeansException, IllegalStateException {
Object var1 = this.startupShutdownMonitor;
synchronized(this.startupShutdownMonitor) {
//调用容器准备刷新的方法,获取 容器的当时时间,同时给容器设置同步标识
this.prepareRefresh();
//告诉子类启动refreshBeanFactory()方法,Bean定义资源文件的载入从子类的refreshBeanFactory()方法启动
//并获取beanFactory
ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
//为BeanFactory配置容器特性,例如类加载器、事件处理器等
this.prepareBeanFactory(beanFactory);
try {
//为容器的某些子类指定特殊的BeanPost事件处理器
this.postProcessBeanFactory(beanFactory);
//调用所有注册的BeanFactoryPostProcessor的Bean
this.invokeBeanFactoryPostProcessors(beanFactory);
//为BeanFactory注册BeanPost事件处理器.
//BeanPostProcessor是Bean后置处理器,用于监听容器触发的事件
this.registerBeanPostProcessors(beanFactory);
//初始化信息源,和国际化相关.
this.initMessageSource();
//初始化容器事件传播器.
this.initApplicationEventMulticaster();
//调用子类的某些特殊Bean初始化方法
this.onRefresh();
//为事件传播器注册事件监听器.
this.registerListeners();
//初始化所有剩余的单态Bean.
this.finishBeanFactoryInitialization(beanFactory);
//初始化容器的生命周期事件处理器,并发布容器的生命周期事件
this.finishRefresh();
} catch (BeansException var9) {
if(this.logger.isWarnEnabled()) {
this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
}
//销毁以创建的单态Bean
this.destroyBeans();
//取消refresh操作,重置容器的同步标识.
this.cancelRefresh(var9);
throw var9;
} finally {
this.resetCommonCaches();
}
}
}
看 this.obtainFreshBeanFactory();
//关闭前面所有 bean 工厂,为新的上下文环境初始化一个新的 bean 工厂。
//这里需要子类(这里是AbstractRefreshableApplicationContext)来 协助完成资源位置定义 ,bean 载入和向 IOC 容器注册的过程
容器真正调用的是其子类AbstractRefreshableApplicationContext实现的 refreshBeanFactory()方法
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
this.refreshBeanFactory();//子类实现,调用子类的实现
ConfigurableListableBeanFactory beanFactory = this.getBeanFactory();
if(this.logger.isDebugEnabled()) {
this.logger.debug("Bean factory for " + this.getDisplayName() + ": " + beanFactory);
}
return beanFactory;
}
继续看this.refreshBeanFactory();
//交给子类AbstractRefreshableApplicationContext
//在这个方法中,先判断BeanFactory是否存在,如果存在则先销毁beans并关闭beanFactory,
//接着创建DefaultListableBeanFactory,并调用loadBeanDefinitions(beanFactory)装载bean
protected final void refreshBeanFactory() throws BeansException {
if(this.hasBeanFactory()) {
this.destroyBeans();
this.closeBeanFactory();
}
try {
//创建IoC容器
DefaultListableBeanFactory ex = this.createBeanFactory();
ex.setSerializationId(this.getId());
//对IoC容器进行定制化,如设置启动参数,开启注解的自动装配等
this.customizeBeanFactory(ex);
//调用载入Bean定义的方法,主要这里使用了一个委派模式,
//在当前类中只定义了抽象的loadBeanDefinitions方法,具体的实现调用子类容器
this.loadBeanDefinitions(ex);
Object var2 = this.beanFactoryMonitor;
synchronized(this.beanFactoryMonitor) {
this.beanFactory = ex;
}
} catch (IOException var5) {
throw new ApplicationContextException("I/O error parsing bean definition source for " + this.getDisplayName(), var5);
}
}
总结:资源定位做的就是:确定工厂位置,执行工厂初始化并刷新,建立好bean资源加载路径。等待bean资源装载。
资源装载
设置工厂配置,刷新容器之后,还要把bean配置给资源加载器。用this.loadBeanDefinitions(beanFactory);去解析。而解析交给子类去实现了。
有下面几种情况
进入AbstractXmlApplicationContext
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
//从beanfactory拿到reader
// 这里使用XMLBeanDefinitionReader来载入bean定义信息的XML文件
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
//这里配置reader的环境,其中ResourceLoader是我们用来定位bean定义信息资源位置的
///因为上下文本身实现了ResourceLoader接口,所以可以直接把上下文作为ResourceLoader传递给XmlBeanDefinitionReader。容器本身也是一个资源加载器
beanDefinitionReader.setEnvironment(this.getEnvironment());
beanDefinitionReader.setResourceLoader(this);
beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
//当Bean读取器读取Bean定义的Xml资源文件时,启用Xml的校验机制
this.initBeanDefinitionReader(beanDefinitionReader);
//这里转到定义好的XmlBeanDefinitionReader中对载入bean信息进行处理
this.loadBeanDefinitions(beanDefinitionReader);
}
AbstractXmlApplicationContext职责为:对applicationContext.xml的解析操作,就是解析工厂的那个xml
AbstractBeanDefinitionReader职责为:从指定的资源加载bean定义,真正实现在其子类,这里是做了些兼容性错误处理。
XmlBeanDefinitionReader是AbstractBeanDefinitionReader的子类,而且是一个真正的实现类 ,是实现BeanDefinitionReader接口的loadBeanDefinitions(Resource var1) 等方法的关键解析类。职责为:读取并真正解析 xml 文件。
AbstractRefreshableApplicationContext中只定义了抽象的loadBeanDefinitions方法,容器真正调用的是其子类AbstractXmlApplicationContext对该方法的实现。(全局搜索SHIFT)
进去this.loadBeanDefinitions(beanDefinitionReader);
由于我们用的是application.xml方式,configResource是null,所以走了getConfigLocation()
走下去进入了AbstractBeanDefinitionReader
public int loadBeanDefinitions(String location, Set<Resource> actualResources) throws BeanDefinitionStoreException {
ResourceLoader resourceLoader = this.getResourceLoader();
if (resourceLoader == null) {//如果没有找到我们需要的ResourceLoader,直接抛出异常
throw new BeanDefinitionStoreException("Cannot import bean definitions from location [" + location + "]: no ResourceLoader available");
} else {
int loadCount;
if (!(resourceLoader instanceof ResourcePatternResolver)) {
// 这里处理我们在定义位置时使用的各种pattern,需要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 {
// 这里通过ResourceLoader来完成位置定位
Resource[] resources = ((ResourcePatternResolver)resourceLoader).getResources(location);
// 这里已经把一个位置定义转化为Resource接口,可以供XmlBeanDefinitionReader来使用了
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);
}
}
}
}
AbstractBeanDefinitionReader的loadBeanDefinitions方法源码分析可以看出该方法做了以下两件事:
(1)首先,调用资源加载器的获取资源方法resourceLoader.getResource(location),获取到要加载的资源。
(2)其次,真正执行加载功能是其子类XmlBeanDefinitionReader实现的loadBeanDefinitions方法。
此时调用的是DefaultResourceLoader中的getSource()方法定位Resource。
然后我们再仔细看下各个类想拿到资源加载器就是通过getResourceLoader,拿到AbstractBeanDefinitionReader类定义的resourceLoader。这样的话,我们可通过此方式在工程spring下的任何地方拿到资源加载器,“随处加载”了。
public interface ResourceLoader {
String CLASSPATH_URL_PREFIX = "classpath:";
Resource getResource(String var1);
ClassLoader getClassLoader();
}
总结:资源加载就是根据之前确定好的bean资源配置路径,拿到资源、拿到加载器,并把bean配置丢进XmlBeanDefinitionReader。等待Bean资源解析。
Bean资源解析
刚刚提到的XmlBeanDefinitionReader就是真正解析xml的类。
//这里是载入XML形式Bean定义资源文件方法
public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
Assert.notNull(encodedResource, "EncodedResource must not be null");
if(this.logger.isInfoEnabled()) {
this.logger.info("Loading XML bean definitions from " + encodedResource.getResource());
}
//获取当前的线程变量,它是用于保存处理的resource的
Set<EncodedResource> currentResources = (Set)this.resourcesCurrentlyBeingLoaded.get();
if(currentResources == null) {
currentResources = new HashSet(4);
this.resourcesCurrentlyBeingLoaded.set(currentResources);//保存当前的resource
}
if(!((Set)currentResources).add(encodedResource)) {
throw new BeanDefinitionStoreException("Detected cyclic loading of " + encodedResource + " - check your import definitions!");
} else {
int var5;
try {
//将资源文件转为InputStream的IO流
InputStream inputStream = encodedResource.getResource().getInputStream();
try {
//从InputStream中得到XML的解析源
InputSource inputSource = new InputSource(inputStream);
if(encodedResource.getEncoding() != null) {
inputSource.setEncoding(encodedResource.getEncoding());
}
//这里是具体的读取过程
var5 = this.doLoadBeanDefinitions(inputSource, encodedResource.getResource());
} finally {
//关闭从Resource中得到的IO流
inputStream.close();
}
} catch (IOException var15) {
throw new BeanDefinitionStoreException("IOException parsing XML document from " + encodedResource.getResource(), var15);
} finally {
((Set)currentResources).remove(encodedResource);
if(((Set)currentResources).isEmpty()) {
this.resourcesCurrentlyBeingLoaded.remove();
}
}
return var5;
}
}
//从特定XML文件中实际载入Bean定义资源的方法 ,就是转成dom对象后交给这里去进一步处理从而转换出bean
protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource) throws BeanDefinitionStoreException {
try {
//将XML文件转换为DOM对象,解析过程由documentLoader实现
Document doc = this.doLoadDocument(inputSource, resource);
//这里是启动对Bean定义解析的详细过程,该解析过程会用到Spring的Bean配置规则
return this.registerBeanDefinitions(doc, resource);
} catch (BeanDefinitionStoreException var4) {
throw var4;
}。。。
}
}
进入 this.doLoadDocument(inputSource, resource);
走下去有个DocumentLoader接口,进入它的实现类DefaultDocumentLoader
public Document loadDocument(InputSource inputSource, EntityResolver entityResolver, ErrorHandler errorHandler, int validationMode, boolean namespaceAware) throws Exception {
//创建文件解析器工厂
DocumentBuilderFactory factory = this.createDocumentBuilderFactory(validationMode, namespaceAware);
if (logger.isDebugEnabled()) {
logger.debug("Using JAXP provider [" + factory.getClass().getName() + "]");
}
//创建文档解析器
DocumentBuilder builder = this.createDocumentBuilder(factory, entityResolver, errorHandler);
//解析Spring的Bean定义资源
return builder.parse(inputSource);
}
//调用了Javaee的JAXP标准,根据定位的Bean定义资源文件,加载读入并转换成为Document对象过程完成
protected DocumentBuilderFactory createDocumentBuilderFactory(int validationMode, boolean namespaceAware) throws ParserConfigurationException {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(namespaceAware);
if (validationMode != 0) {
factory.setValidating(true);
if (validationMode == 3) {
factory.setNamespaceAware(true);
try {
factory.setAttribute("http://java.sun.com/xml/jaxp/properties/schemaLanguage", "http://www.w3.org/2001/XMLSchema");
} catch (IllegalArgumentException var6) {
。。。
pcex.initCause(var6);
throw pcex;
}
}
}
return factory;
}
总结:Bean资源解析就是,先通过 XML解析器讲Bean定义资源文件转换得到Document对象,但是这堆Document对象没有按照spring的Bean规则的,所以不可直接转换成bean对象。然后完成XML解析变成Document对象后,就调用spring的解析方法按照Spring的Bean规则去对Document进行解析,生成Bean对象。
生成bean
在XmlBeanDefinitionReader中有一个oLoadBeanDefinitions方法里面的
return this.registerBeanDefinitions(doc, resource);进去
//按照Spring的Bean语义要求 将Bean 定 义 资源解析并转换为容器内部数据结构
public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
//得到BeanDefinitionDocumentReader来对xml格式的BeanDefinition解析
BeanDefinitionDocumentReader documentReader = this.createBeanDefinitionDocumentReader();
//读取环境的配置设置
documentReader.setEnvironment(this.getEnvironment());
//获得容器中注册的Bean数量
int countBefore = this.getRegistry().getBeanDefinitionCount();
//解析过程入口,这里使用了委派模式,BeanDefinitionDocumentReader只是个接口,//具体的解析实现过程有实现类DefaultBeanDefinitionDocumentReader完成
documentReader.registerBeanDefinitions(doc, this.createReaderContext(resource));
//统计解析的Bean数量
return this.getRegistry().getBeanDefinitionCount() - countBefore;
}
//在此方法真正去转化document对象成为bean
protected BeanDefinitionDocumentReader createBeanDefinitionDocumentReader() {
return (BeanDefinitionDocumentReader)BeanDefinitionDocumentReader.class.cast(BeanUtils.instantiateClass(this.documentReaderClass));
}
跟着documentReader.registerBeanDefinitions(doc, this.createReaderContext(resource));
进去是一个BeanDefinitionDocumentReader接口,然后去它的实现类DefaultBeanDefinitionDocumentReader
public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
this.readerContext = readerContext;
this.logger.debug("Loading bean definitions");
Element root = doc.getDocumentElement();
this.doRegisterBeanDefinitions(root);
}
在这个类进行详细的document元素解析成我们平常工程用的bean。
在IoC容器中注册
在类DefaultBeanDefinitionDocumentReader生成bean后必然会丢给IoC容器去注册,交给它管理。
根据标签去选择bean元素生成法
private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
if (delegate.nodeNameEquals(ele, "import")) {
this.importBeanDefinitionResource(ele);
} else if (delegate.nodeNameEquals(ele, "alias")) {
this.processAliasRegistration(ele);
//走这里
} else if (delegate.nodeNameEquals(ele, "bean")) {
this.processBeanDefinition(ele, delegate);
} else if (delegate.nodeNameEquals(ele, "beans")) {
this.doRegisterBeanDefinitions(ele);
}
}
//进入解析和注册分发啦
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));
}
}
跟着走进入BeanDefinitionReaderUtils
public static void registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) throws BeanDefinitionStoreException {
//得到需要 注册 的 bean名字
String beanName = definitionHolder.getBeanName();
//开始注册。锁定registerBeanDefinition方法
registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
// 别名也是可以 通过IOC容器和bean联系起来的进行注册
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());点进接口BeanDefinitionRegistry。找到BeanDefinitionRegistry的实现类DefaultListableBeanFactory。
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException {
//一堆验证beanDefinition的正确性
。。。
//先看看在容器里是不是已经有了同名的bean,如果有抛出异常。
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 + "]");
}
this.beanDefinitionMap.put(beanName, beanDefinition);
} else {
if (this.hasBeanCreationStarted()) {
Map var4 = this.beanDefinitionMap;
synchronized(this.beanDefinitionMap) {
this.beanDefinitionMap.put(beanName, beanDefinition);
List<String> updatedDefinitions = new ArrayList(this.beanDefinitionNames.size() + 1);
updatedDefinitions.addAll(this.beanDefinitionNames);
updatedDefinitions.add(beanName);
this.beanDefinitionNames = updatedDefinitions;
if (this.manualSingletonNames.contains(beanName)) {
Set<String> updatedSingletons = new LinkedHashSet(this.manualSingletonNames);
updatedSingletons.remove(beanName);
this.manualSingletonNames = updatedSingletons;
}
}
} else {
//这里把bean的名字和Bean定义联系起来放到一个HashMap中去,IOC容器通过这个Map来维护容器里的Bean定义信息。
this.beanDefinitionMap.put(beanName, beanDefinition);
//没重复就把bean的名字加到IOC容器中去
this.beanDefinitionNames.add(beanName);
this.manualSingletonNames.remove(beanName);
}
this.frozenBeanDefinitionNames = null;
}
if (oldBeanDefinition != null || this.containsSingleton(beanName)) {
this.resetBeanDefinition(beanName);
}
}
总结:在IoC容器中注册就是把beandefinition丢给工厂用hashmap存好
总结IOC容器初始化流程
- 通过setConfigLocations载入spring配置文件。
- 初始化容器入口通过refresh方法,进入AbstractApplicationContext实现的refresh方法
- 然后通过obtainFreshBeanFactory方法进入子类AbstractRefreshableApplicationContext实现的refreshBeanFactory刷新一个容器工厂
- 在此创建了DefaultListableBeanFactory类,并调用loadBeanDefinitions(beanFactory)装载bean定义
- 接着以AbstractRefreshableApplicationContext为中心回到此类,进入其子类AbstractXmlApplicationContext实现的loadBeanDefinitions方法。对applicationContext.xml的解析操作,就是解析工厂的那个xml
- 再接着通过AbstractXmlApplicationContext的loadBeanDefinitions进入到AbstractBeanDefinitionReader类的loadBeanDefinitions。通过获取资源方法resourceLoader.getResource(location),获取到要加载的资源。再真正执行加载功能是其子类XmlBeanDefinitionReader实现的loadBeanDefinitions方法
- 接着进入XmlBeanDefinitionReader中的loadBeanDefinitions。(XmlBeanDefinitionReader通过调用其父类中调用的DefaultResourceLoader的getResource方法获取要加载的资源)DocumentLoader将Bean定义资源转换成Document对象
- doLoadBeanDefinitions中进入DefaultBeanDefinitionDocumentReader类的registerBeanDefinitions 解析 Document对象
- 解析完后,调用DefaultListableBeanFactory类中使用一个HashMap的集合对象存放IoC容器中注册解析的BeanDefinition
IoC容器依赖注入过程
Spring把loadBean和依赖注入分成两个基本的过程,一个是在启动容器的时候完成,建立起一系列 BeanDefinition,这些定义里面同时都包含了对bean依赖关系的描述,不过这里并没有对bean进行实例化,真正实例化的时候是在客户通过容器使用这些bean的时候 - 也就是getbean的时候。这个时候IOC容器根据需要会建立起一系列bean的实例和完成依赖注入。
BeanFactory接口定义了Spring IoC容器的基本功能规范,是Spring IoC容器所应遵守的最底层和最基本的编程规范。BeanFactory接口中定义了几个getBean方法,就是用户向IoC容器索取管理的Bean的方法,
从实例代码的getBean进入,到最后是上图的BeanFactory,然后进入它的实现类AbstractBeanFactory
protected <T> T doGetBean(String name, Class<T> requiredType, final Object[] args, boolean typeCheckOnly) throws BeansException {
//根据指定的名称获取被管理Bean的名称,剥离指定名称中对容器的相关依赖
//如果指定的是别名,将别名转换为规范的Bean名称
final String beanName = this.transformedBeanName(name);
//先从缓存中取是否已经有被创建过的单态类型的Bean,对于单态模式的Bean整
//个IoC容器中只创建一次,不需要重复创建
Object sharedInstance = this.getSingleton(beanName);
Object bean;
if (sharedInstance != null && args == null) {
if (this.logger.isDebugEnabled()) {
//如果指定名称的Bean在容器中已有单态模式的Bean被创建,直接返回
//已经创建的Bean
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的实例对象,主要是完成FactoryBean的相关处理
//注意:BeanFactory是管理容器中Bean的工厂,而FactoryBean是创建创建对象的工厂Bean,两者之间有区别
bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, (RootBeanDefinition)null);
} else {
//缓存没有正在创建的单态模式Bean
//缓存中已经有已经创建的原型模式Bean,但是由于循环引用的问题导致实
//例化对象失败
if (this.isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
//对IoC容器中是否存在指定名称的BeanDefinition进行检查,首先检查是否
//能在当前的BeanFactory中获取的所需要的Bean,如果不能则委托当前容器
//的父级容器去查找,如果还是找不到则沿着容器的继承体系向父级容器查找
BeanFactory parentBeanFactory = this.getParentBeanFactory();
//当前容器的父级容器存在,且当前容器中不存在指定名称的Bean
if (parentBeanFactory != null && !this.containsBeanDefinition(beanName)) {
String nameToLookup = this.originalBeanName(name);
if (args != null) {
//解析指定Bean名称的原始名称
return parentBeanFactory.getBean(nameToLookup, args);
}
//委派父级容器根据指定名称和类型查找
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
//创建的Bean是否需要进行类型验证,一般不需要
if (!typeCheckOnly) {
//向容器标记指定的Bean已经被创建
this.markBeanAsCreated(beanName);
}
try {
//根据指定Bean名称获取其父级的Bean定义,主要解决Bean继承时子类
//合并父类公共属性问题
final RootBeanDefinition mbd = this.getMergedLocalBeanDefinition(beanName);
this.checkMergedBeanDefinition(mbd, beanName, args);
//获取当前Bean所有依赖Bean的名称
String[] dependsOn = mbd.getDependsOn();
String[] var11;
//如果当前Bean有依赖Bean
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 + "'");
}
//把被依赖Bean注册给当前依赖的Bean
this.registerDependentBean(dep, beanName);
//递归调用getBean方法,获取当前Bean的依赖Bean
this.getBean(dep);
}
}
//创建单态模式Bean的实例对象
if (mbd.isSingleton()) {
//这里使用了一个匿名内部类,创建Bean实例对象,并且注册给所依赖的对象
sharedInstance = this.getSingleton(beanName, new ObjectFactory<Object>() {
public Object getObject() throws BeansException {
try {
//创建一个指定Bean实例对象,如果有父级继承,则合并子//类和父类的定义
return AbstractBeanFactory.this.createBean(beanName, mbd, args);
} catch (BeansException var2) {
//显式地从容器单态模式Bean缓存中清除实例对象
AbstractBeanFactory.this.destroySingleton(beanName);
throw var2;
}
}
});
//获取给定Bean的实例对象
bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
//IoC容器创建原型模式Bean实例对象
} else if (mbd.isPrototype()) {
var11 = null;
//原型模式(Prototype)是每次都会创建一个新的对象
Object prototypeInstance;
try {
//回调beforePrototypeCreation方法,默认的功能是注册当前创//建的原型对象
this.beforePrototypeCreation(beanName);
//创建指定Bean对象实例
prototypeInstance = this.createBean(beanName, mbd, args);
} finally {
//回调afterPrototypeCreation方法,默认的功能告诉IoC容器指//定Bean的原型对象不再创建了
this.afterPrototypeCreation(beanName);
}
//获取给定Bean的实例对象
bean = this.getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
} else {
//要创建的Bean既不是单态模式,也不是原型模式,则根据Bean定义资源中
//配置的生命周期范围,选择实例化Bean的合适方法,这种在Web应用程序中
//比较常用,如:request、session、application等生命周期
String scopeName = mbd.getScope();
Scope scope = (Scope)this.scopes.get(scopeName);
//Bean定义资源中没有配置生命周期范围,则Bean定义不合法
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
}
try {
//这里又使用了一个匿名内部类,获取一个指定生命周期范围的实例
Object scopedInstance = scope.get(beanName, new ObjectFactory<Object>() {
public Object getObject() throws BeansException {
AbstractBeanFactory.this.beforePrototypeCreation(beanName);
Object var1;
try {
var1 = AbstractBeanFactory.this.createBean(beanName, mbd, args);
} finally {
AbstractBeanFactory.this.afterPrototypeCreation(beanName);
}
return var1;
}
});
//获取给定Bean的实例对象
bean = this.getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
} catch (IllegalStateException var21) {
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", var21);
}
}
} catch (BeansException var23) {
this.cleanupAfterBeanCreationFailure(beanName);
throw var23;
}
}
//对创建的Bean实例对象进行类型检查
if (requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass())) {
try {
return this.getTypeConverter().convertIfNecessary(bean, requiredType);
} catch (TypeMismatchException var22) {
if (this.logger.isDebugEnabled()) {
this.logger.debug("Failed to convert bean '" + name + "' to required type '" + ClassUtils.getQualifiedName(requiredType) + "'", var22);
}
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
} else {
return bean;
}
}
上面,我们可以清楚的看见在创建实例是做了判断
如果Bean定义的单态模式(Singleton),则容器在创建之前先从缓存中查找,以确保整个容器中只存在一个实例对象
如果Bean定义的是原型模式(Prototype),则容器每次都会创建一个新的实例对象。
两者都不是,则根据Bean定义资源中配置的生命周期范围,选择实例化Bean的合适方法,这种在Web应用程序中 比较常用,如:request、session、application等生命周期
上面的源码只是定义了根据Bean定义的模式,采取的不同创建Bean实例对象的策略,具体的Bean实例对象的创建过程由实现了ObejctFactory接口的匿名内部类的createBean方法完成,ObejctFactory使用委派模式,具体的Bean实例创建过程交由其实现类AbstractAutowireCapableBeanFactory完成,我们继续分析AbstractAutowireCapableBeanFactory的createBean方法的源码,理解其创建Bean实例的具体实现过程。
//创建Bean实 例对象
protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
if (this.logger.isDebugEnabled()) {
this.logger.debug("Creating instance of bean '" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd;
//判断需要创建的Bean是否可以实例化,即是否可以通过当前的类加载器加载
Class<?> resolvedClass = this.resolveBeanClass(mbd, beanName, new Class[0]);
//校验和准备Bean中的方法覆盖
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
try {
mbdToUse.prepareMethodOverrides();
} catch (BeanDefinitionValidationException var7) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(), beanName, "Validation of method overrides failed", var7);
}
Object beanInstance;
try {
//如果Bean配置了初始化前和初始化后的处理器,则试图返回一个需要创建Bean的代理对象
beanInstance = this.resolveBeforeInstantiation(beanName, mbdToUse);
if (beanInstance != null) {
return beanInstance;
}
} catch (Throwable var8) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "BeanPostProcessor before instantiation of bean failed", var8);
}
//真正创建Bean的入口
beanInstance = this.doCreateBean(beanName, mbdToUse, args);
if (this.logger.isDebugEnabled()) {
this.logger.debug("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
进入doCreateBean
//真正创建bean的方法
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, Object[] args) {
//封装被创建的Bean对象
BeanWrapper instanceWrapper = null;
if(mbd.isSingleton()) {//单态模式的Bean,先从容器中缓存中获取同名Bean
instanceWrapper = (BeanWrapper)this.factoryBeanInstanceCache.remove(beanName);
}
//容器没有的话
if(instanceWrapper == null) {
//创建实例对象
instanceWrapper = this.createBeanInstance(beanName, mbd, args);
}
final Object bean = instanceWrapper != null?instanceWrapper.getWrappedInstance():null;
//获取实例化对象的类型
Class<?> beanType = instanceWrapper != null?instanceWrapper.getWrappedClass():null;
Object var7 = mbd.postProcessingLock;
//调用PostProcessor后置处理器
synchronized(mbd.postProcessingLock) {
if(!mbd.postProcessed) {
this.applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
mbd.postProcessed = true;
}
}
//向容器中缓存单态模式的Bean对象,以防循环引用
boolean earlySingletonExposure = mbd.isSingleton() && this.allowCircularReferences && this.isSingletonCurrentlyInCreation(beanName);
if(earlySingletonExposure) {
if(this.logger.isDebugEnabled()) {
this.logger.debug("Eagerly caching bean '" + beanName + "' to allow for resolving potential circular references");
}
//这里是一个匿名内部类,为了防止循环引用,尽早持有对象的引用
this.addSingletonFactory(beanName, new ObjectFactory<Object>() {
public Object getObject() throws BeansException {
return AbstractAutowireCapableBeanFactory.this.getEarlyBeanReference(beanName, mbd, bean);
}
});
}
//Bean对象的初始化,依赖注入在此触发
//这个exposedObject在初始化完成之后返回作为依赖注入完成后的Bean
Object exposedObject = bean;
try {
//将Bean实例对象封装,并且Bean定义中配置的属性值赋值给实例对象
this.populateBean(beanName, mbd, instanceWrapper);
if(exposedObject != null) {
//初始化Bean对象
exposedObject = this.initializeBean(beanName, exposedObject, mbd);
}
} catch (Throwable var17) {
。。。
}
if(earlySingletonExposure) {
//获取指定名称的已注册的单态模式Bean对象
Object earlySingletonReference = this.getSingleton(beanName, false);
if(earlySingletonReference != null) {
//根据名称获取的以注册的Bean和正在实例化的Bean是同一个
if(exposedObject == bean) {
//当前实例化的Bean初始化完成
exposedObject = earlySingletonReference;
} else if(!this.allowRawInjectionDespiteWrapping && this.hasDependentBean(beanName)) {//当前Bean依赖其他Bean,并且当发生循环引用时不允许新创建实例对象
String[] dependentBeans = this.getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet(dependentBeans.length);
String[] var12 = dependentBeans;//用来暂存当前bean
int var13 = dependentBeans.length;
//获取当前Bean所依赖的其他Bean
for(int var14 = 0; var14 < var13; ++var14) {
String dependentBean = var12[var14];
//对依赖Bean进行类型检查
if(!this.removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
if(!actualDependentBeans.isEmpty()) {
。。。
}
}
}
}
//注册完成依赖注入的Bean
try {
this.registerDisposableBeanIfNecessary(beanName, bean, mbd);
return exposedObject;
} catch (BeanDefinitionValidationException var16) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", var16);
}
}
除了判断和校验之外,真正实现的是
createBeanInstance:生成Bean所包含的Java对象实例。
populateBean :对Bean属性的依赖注入进行处理。
进入createBeanInstance方法
//创建Bean的实例对象
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {
//检查确认Bean是可实例化的
Class<?> beanClass = this.resolveBeanClass(mbd, beanName, new Class[0]);
//使用工厂方法对Bean进行实例化
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 if (mbd.getFactoryMethodName() != null) {
//调用工厂方法实例化
return this.instantiateUsingFactoryMethod(beanName, mbd, args);
} else {//使用容器的自动装配方法进行实例化
boolean resolved = false;
boolean autowireNecessary = false;
if (args == null) {
Object var7 = mbd.constructorArgumentLock;
synchronized(mbd.constructorArgumentLock) {
if (mbd.resolvedConstructorOrFactoryMethod != null) {
resolved = true;
//决定是否使用自动装配的构造器
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}
//autowireConstructor构造器方法配置了自动装配属性,使用容器的自动装配实例化,容器的自动装配是根据参数类型匹配Bean的构造方法
if (resolved) {
//根据标记位autowireNecessary而决定采用无参构造器还是自动装配构造器
return autowireNecessary ? this.autowireConstructor(beanName, mbd, (Constructor[])null, (Object[])null) : this.instantiateBean(beanName, mbd);
} else {
//使用Bean的构造方法进行实例化
Constructor<?>[] ctors = this.determineConstructorsFromBeanPostProcessors(beanClass, beanName);
//根据是否有参数还是已经配置了自动装配模式,去选择构造器,无参构造器还是自动装配构造器。
return ctors == null && mbd.getResolvedAutowireMode() != 3 && !mbd.hasConstructorArgumentValues() && ObjectUtils.isEmpty(args) ? this.instantiateBean(beanName, mbd) : this.autowireConstructor(beanName, mbd, ctors, args);
}
}
}
进入无参构造器instantiateBean
//使用默认的无参构造方法实例化Bean对象
protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
try {
Object beanInstance;
//获取系统的安全管理接口,JDK标准的安全管理API
if(System.getSecurityManager() != null) {
//这里是一个匿名内置类,根据实例化策略创建实例对象
beanInstance = AccessController.doPrivileged(new PrivilegedAction<Object>() {
public Object run() {
return AbstractAutowireCapableBeanFactory.this.getInstantiationStrategy().instantiate(mbd, beanName, AbstractAutowireCapableBeanFactory.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);
}
}
我们都看到了,无论什么调用什么构造器,返回的都是统一的BeanWrapper。
BeanWrapper相当于一个代理器,Spring通过BeanWrapper完成Bean属性的填充工作。在Bean实例被InstantiationStrategy创建出来之后,容器主控程序将Bean实例通过BeanWrapper包装起来。
BeanWrapper还有两个顶级类接口,分别是PropertyAccessor和PropertyEditorRegistry。
PropertyAccessor接口定义了各种访问Bean属性的方法,如setPropertyValue(String,Object),setPropertyValues(PropertyValues pvs)等,而PropertyEditorRegistry是属性编辑器的注册表。
所以BeanWrapper实现类BeanWrapperImpl具有了三重身份:
- 1)Bean包裹器;
- 2)属性访问器;
- 3)属性编辑器注册表。
在注入过程中:
createBean开始调用populateBean方法.
首先进行自动装配模式的处理,也就是说对BeanDefiniton中定义自动装配模式的属性进行调整.比如定义了AUTOWIRE_BY_NAME的属性会相应找到匹配该命名的bean.
并且将该被检索到的bean实例值给property,当然这里也肯定通过getBean方法来获取这个需要自动装配的bean实例,并且在BeanWrapper中包装
再看看populateBean:对Bean的属性依赖注入的处理,分为两个部分属性值解析和注入。
//将Bean属性设置到生成的实例对象上
protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
//获取容器在解析Bean定义资源时为BeanDefiniton中设置的属性值
PropertyValues pvs = mbd.getPropertyValues();
//实例对象为null
if(bw == null) {
//属性值不为空
if(!((PropertyValues)pvs).isEmpty()) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
}
} else {
//在设置属性之前调用Bean的PostProcessor后置处理器
boolean continueWithPropertyPopulation = true;
if(!mbd.isSynthetic() && this.hasInstantiationAwareBeanPostProcessors()) {
Iterator var6 = this.getBeanPostProcessors().iterator();
while(var6.hasNext()) {
BeanPostProcessor bp = (BeanPostProcessor)var6.next();
if(bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor)bp;
if(!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
continueWithPropertyPopulation = false;
break;
}
}
}
}
//依赖注入开始,首先处理autowire自动装配的注入
if(continueWithPropertyPopulation) {
if(mbd.getResolvedAutowireMode() == 1 || mbd.getResolvedAutowireMode() == 2) {
MutablePropertyValues newPvs = new MutablePropertyValues((PropertyValues)pvs);
//对autowire自动装配的处理,根据Bean名称自动装配注入
if(mbd.getResolvedAutowireMode() == 1) {
this.autowireByName(beanName, mbd, bw, newPvs);
}
//根据Bean类型自动装配注入
if(mbd.getResolvedAutowireMode() == 2) {
this.autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
//检查容器是否持有用于处理单态模式Bean关闭时的后置处理器
boolean hasInstAwareBpps = this.hasInstantiationAwareBeanPostProcessors();
//Bean实例对象没有依赖,即没有继承基类
boolean needsDepCheck = mbd.getDependencyCheck() != 0;
if(hasInstAwareBpps || needsDepCheck) {
//从实例对象中提取属性描述符
PropertyDescriptor[] filteredPds = this.filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
if(hasInstAwareBpps) {
Iterator var9 = this.getBeanPostProcessors().iterator();
while(var9.hasNext()) {
BeanPostProcessor bp = (BeanPostProcessor)var9.next();
if(bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor)bp;
//使用BeanPostProcessor处理器处理属性值
pvs = ibp.postProcessPropertyValues((PropertyValues)pvs, filteredPds, bw.getWrappedInstance(), beanName);
if(pvs == null) {
return;
}
}
}
}
if(needsDepCheck) {
//为要设置的属性进行依赖检查
this.checkDependencies(beanName, mbd, filteredPds, (PropertyValues)pvs);
}
}
//对属性进行注入 ,解析并注入依赖属性的过程 就在这个方法里面
/*
属性转换也有两情况:
1.属性值类型不需要转换时,不需要解析属性值,直接准备进行依赖注入。
2.属性值需要进行类型转换时,如对其他对象的引用等,首先需要解析属性值,然后对解析后的属性值进行依赖注入。
*/
this.applyPropertyValues(beanName, mbd, bw, (PropertyValues)pvs);
}
}
}
然后进入applyPropertyValues
//解析并注入依赖属性的过程
protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
if(pvs != null && !pvs.isEmpty()) {
//封装属性值
MutablePropertyValues mpvs = null;
if(System.getSecurityManager() != null && bw instanceof BeanWrapperImpl) {
//设置安全上下文,JDK安全机制
((BeanWrapperImpl)bw).setSecurityContext(this.getAccessControlContext());
}
List original;
if(pvs instanceof MutablePropertyValues) {
mpvs = (MutablePropertyValues)pvs;
//属性值已经转换
if(mpvs.isConverted()) {
try {
//为实例化对象设置属性值 ,依赖注入真真正正地实现在此!!!!!
bw.setPropertyValues(mpvs);
return;
} catch (BeansException var18) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Error setting property values", var18);
}
}
//获取属性值对象的原始类型值
original = mpvs.getPropertyValueList();
} else {
original = Arrays.asList(pvs.getPropertyValues());
}
//获取用户自定义的类型转换
TypeConverter converter = this.getCustomTypeConverter();
if(converter == null) {
converter = bw;
}
//创建一个Bean定义属性值解析器,将Bean定义中的属性值解析为Bean实例对象
//的实际值
BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, (TypeConverter)converter);
//为属性的解析值创建一个拷贝,将拷贝的数据注入到实例对象中
List<PropertyValue> deepCopy = new ArrayList(original.size());
boolean resolveNecessary = false;
Iterator var11 = original.iterator();//用迭代器去遍历
while(true) {
while(var11.hasNext()) {
PropertyValue pv = (PropertyValue)var11.next();
//属性值不需要转换
if(pv.isConverted()) {
deepCopy.add(pv);
} else {//属性值需要转换
String propertyName = pv.getName();
//原始的属性值,即转换之前的属性值
Object originalValue = pv.getValue();
//转换属性值,例如将引用转换为IoC容器中实例化对象引用 !!!!! 对属性值的解析!!
Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
//转换之后的属性值
Object convertedValue = resolvedValue;
//属性值是否可以转换
boolean convertible = bw.isWritableProperty(propertyName) && !PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);
if(convertible) {
//使用用户自定义的类型转换器转换属性值
convertedValue = this.convertForProperty(resolvedValue, propertyName, bw, (TypeConverter)converter);
}
//存储转换后的属性值,避免每次属性注入时的转换工作
if(resolvedValue == originalValue) {
if(convertible) {
//设置属性转换之后的值
pv.setConvertedValue(convertedValue);
}
deepCopy.add(pv);
}
//属性是可转换的,且属性原始值是字符串类型,且属性的原始类型值不是
//动态生成的字符串,且属性的原始值不是集合或者数组类型
else if(convertible && originalValue instanceof TypedStringValue && !((TypedStringValue)originalValue).isDynamic() && !(convertedValue instanceof Collection) && !ObjectUtils.isArray(convertedValue)) {
pv.setConvertedValue(convertedValue);
deepCopy.add(pv);
} else {
resolveNecessary = true;
//重新封装属性的值
deepCopy.add(new PropertyValue(pv, convertedValue));
}
}
}
if(mpvs != null && !resolveNecessary) {
//标记属性值已经转换过
mpvs.setConverted();
}
//进行属性依赖注入 ,依赖注入的真真正正实现依赖的注入方法在此!!!
try {
bw.setPropertyValues(new MutablePropertyValues(deepCopy));
return;
} catch (BeansException var19) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Error setting property values", var19);
}
}
}
}
总结applyPropertyValues方法(完成属性转换):
属性值类型不需要转换时,不需要解析属性值,直接准备进行依赖注入。
属性值需要进行类型转换时,如对其他对象的引用等,首先需要解析属性值,然后对解析后的属性值进行依赖注入。
当容器在对属性进行依赖注入时,如果发现属性值需要进行类型转换,如属性值是容器中另一个Bean实例对象的引用,则容器首先需要根据属性值解析出所引用的对象,然后才能将该引用对象注入到目标实例对象的属性上去,对属性进行解析的由resolveValueIfNecessary方法实现。可知:创建与注入是个递归的过程
空间限制,都简写了
进入BeanDefinitionValueResolver类的resolveValueIfNecessary方法。
解析引用类型是BeanDefinitionValueResolver类的resolveReference方法
刚刚的AbstractAutowireCapableBeanFactory类中applyPropertyValues方法分发了一个方法实现对属性值的依赖注入setPropertyValues。
找到AbstractPropertyAccessor类中的抽象方法setPropertyValue
很复杂的一个解析方法:将属性的值注入到Bean实例对象中情况如下:
- 对于集合类型的属性,将其属性值解析为目标类型的集合后直接赋值给属性
- 对于非集合类型的属性,大量使用了JDK的反射和内省机制,通过属性的getter方法(reader method)获取指定属性注入以前的值,同时调用属性的setter方法(writer method)为属性设置注入后的值。
DI总结:
- DefaultListableBeanFactory父类AbstractBeanFactory根据Bean的状态定义(单例、存在、原型)进行构造方法分发。分发到AbstractAutowireCapableBeanFactory类的createBean方法
- createBean方法负责Bean实例要求状态判断以及再度分发到doCreateBean实现创建实例(再次配置判断)。并在doCreateBean再度分发去createBeanInstance去Bean所包含的Java对象实例以及去populateBean 方法对Bean属性的依赖注入进行处理(以此为责任分发中心)。
- 在createBeanInstance方法中真正地根据之前的配置判断设置选择真正合适的构造器(自动装配、无参构造器);
- 在populateBean 方法中真正地将Bean属性设置到生成的实例对象上 ,但在过程中注入依赖属性的是在applyPropertyValues方法(完成属性转换),调用BeanDefinitionValueResolver类调用resolveValueIfNecessary方法对属性值的解析,属性的真正注入实现在BeanWrapperImpl类。
这还是站在巨人的肩膀上写的,自己都跟不下去。