上一篇主要是跟踪了IOC容器对bean标签进行解析之后存入Map中的过程,这些bean只是以BeanDefinition为载体单纯的存储起来了,并没有转换成一个个的对象,今天继续进行跟踪,看一看IOC容器是怎样实例化对象的。

  我们都使用过以下代码:

 FileSystemXmlApplicationContext  context=new FileSystemXmlApplicationContext("bean.xml");
User user=context.getBean("user",User.class);

  这样我们就能获取到user对象了,所以,不难想象,这个getBean方法就是实例化对象的入口。接下来我们就以这个方法为切入点,来探究IOC容器中bean的实例化过程。getBean方法是在FileSystemXmlApplicationContext的基类AbstractApplicationContext中定义的,代码如下:

 public <T> T getBean(String name, Class<T> requiredType) throws BeansException {
assertBeanFactoryActive();
return getBeanFactory().getBean(name, requiredType);
}

  里面有很多重载方法,里面有调用了某个beanFactory的getBean方法。AbstractApplicationContext中并没有定义getBeanFactory这个方法,那一定是在FileSystemXmlApplicatio

—ntext的某个父类中定义的,我们再回过头看一下它的UML图:

  经过查找之后,是在AbstractRefreshableApplicationContext中定义的,且这个beanFactory是DefaultListableBeanFactory类型的:

 public abstract class AbstractRefreshableApplicationContext extends AbstractApplicationContext {

     private Boolean allowBeanDefinitionOverriding;

     private Boolean allowCircularReferences;

     /** Bean factory for this context */
private DefaultListableBeanFactory beanFactory; /** Synchronization monitor for the internal BeanFactory */
private final Object beanFactoryMonitor = new Object();

  直接进入DefaultListableBeanFactory中,查看它的getBean方法:

public <T> T getBean(Class<T> requiredType) throws BeansException {
return getBean(requiredType, (Object[]) null);
}
public <T> T getBean(Class<T> requiredType, Object... args) throws BeansException {
NamedBeanHolder<T> namedBean = resolveNamedBean(requiredType, args);
if (namedBean != null) {
return namedBean.getBeanInstance();
}
BeanFactory parent = getParentBeanFactory();
if (parent != null) {
return parent.getBean(requiredType, args);
}
throw new NoSuchBeanDefinitionException(requiredType);
}

  发现里面只有这两个重载方法,其他getBean方法,包括例子中使用的那个重载方法没有看到,我们看一下DefaultListableBeanFactory类的UML图:

  经查找,发现在父类AbstractBeanFactory中定义了其他的getBean方法,如下:

 public Object getBean(String name, Object... args) throws BeansException {
return doGetBean(name, null, args, false);
}
 public <T> T getBean(String name, Class<T> requiredType, Object... args) throws BeansException {
return doGetBean(name, requiredType, args, false);
}

  里面都调用了doGetBean方法,那么进入继续跟踪:

 protected <T> T doGetBean(
final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
throws BeansException {
//将bean的name进行转换,比如将name前面的“&”符去掉,带“&”的name,获取的是beanFactory本身,而不是
//beanFactory生成出来的bean实例
final String beanName = transformedBeanName(name);
Object bean; // Eagerly check singleton cache for manually registered singletons.
//看缓存中是否已经有该bean
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 + "'");
}
}
//如果sharedInstance是FactoryBean类型,则返回它生产的对象,否则,返回它本身
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();
//如果父容器存在,且在当前容器中没有找到该名称的bean的数据
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
//则到父容器中进行处理
// Not found -> check parent.
//将name前加上“&”
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 {
//将数据封装成RootBeanDefinition对象
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
//检查是否为抽象类
checkMergedBeanDefinition(mbd, beanName, args); // Guarantee initialization of beans that the current bean depends on.
//获取当前创建的bean的依赖的bean
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dep : dependsOn) {
if (isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
//为当前bean和它的依赖对象建立映射关系
registerDependentBean(dep, beanName);
try {
//递归调用getBean方法,创建依赖对象,直到没有依赖对象为止
getBean(dep);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
} // Create bean instance.
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
@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<Object>() {
@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.isInstance(bean)) {
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;
}

  可以看到对不同scope域的bean的创建过程,其中会进行递归创建,现在进入createBean方法中,其实现是在AbstractAutowireCapableBeanFactory类中,代码如下:

 protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
if (logger.isDebugEnabled()) {
logger.debug("Creating instance of bean '" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd; // Make sure bean class is actually resolved at this point, and
// clone the bean definition in case of a dynamically resolved Class
// which cannot be stored in the shared merged bean definition.
//判断需要创建的bean是否可以实例化,是否可以通过类装载其进行装载
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
} // Prepare method overrides.
try {
//这里是对overrides属性和look-up属性的处理
mbdToUse.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
} try {
//AOP就是这里操作的,如果配置了postProcessor,则生成一个proxy返回,即代理类
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
}
catch (Throwable ex) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}
//创建bean的方法调用
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isDebugEnabled()) {
logger.debug("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}

  进入doCreateBean方法:

 protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
throws BeanCreationException { // Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
//如果是单例,先把缓存中的同名Bean清除
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);
mbd.resolvedTargetType = beanType; // Allow post-processors to modify the merged bean definition.
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
//使用后置处理器进行处理
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
} // Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
//这里是对单例的循环引用的处理
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isDebugEnabled()) {
logger.debug("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
addSingletonFactory(beanName, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
return getEarlyBeanReference(beanName, mbd, bean);
}
});
} //这里是对bean的初始化,依赖注入往往是在这里进行的,这个exposedObject在初始化完成之后会作为依赖注入完成之后的Bean
// Initialize the bean instance.
Object exposedObject = bean;
try {
//属性的填充
populateBean(beanName, mbd, instanceWrapper);
if (exposedObject != null) {
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
}
catch (Throwable ex) {
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex;
}
else {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
}
} if (earlySingletonExposure) {
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
}
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<String>(dependentBeans.length);
for (String dependentBean : dependentBeans) {
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
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.");
}
}
}
} // Register bean as disposable.
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
} return exposedObject;
}

  这里要说一下,当在创建bean时,IOC会将该bean的名字存一份到singletonsCurrentlyInCreation这个map中,然后每次创建的时候都会到里面进行检查当前bean是否正在被创建。为了避免发生循环引用(A依赖B,B依赖C,C依赖A)引起是循环,在第一次创建bean时,IOC容器会把用于创建这个bean的工厂对象放入singletonFactories这个map中,key是这个正在被创建的bean的名字。这样发生循环依赖的时候,就不再调用getBean方法了,而是直接使用工厂创建一个bean给被依赖的对象。比如第一次创建A时,将A的名称存入了singletonsCurrentlyInCreation这个map中,并且调用addSingletonFactory方法,将创建A的工厂放到singletonFactories中了,然后递归调用getBean创建依赖对象B、C,创建C时,要先创建它的依赖对象A,此时,IOC容器检查到singletonsCurrentlyInCreation中已经有这个A了,说明它已经在创建的过程中,只是还没有完成创建,此时,IOC容器直接就使用这个工厂将A创建出来赋给C了,然后再往回完成B和A的创建。可以看一下addSingletonFactory方法的实现:

 protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(singletonFactory, "Singleton factory must not be null");
synchronized (this.singletonObjects) {
if (!this.singletonObjects.containsKey(beanName)) {
this.singletonFactories.put(beanName, singletonFactory);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}
}
 public Object getSingleton(String beanName) {
return getSingleton(beanName, true);
}
 protected Object getSingleton(String beanName, boolean allowEarlyReference) {
//从缓存中获取该bean的实例,已经填充了属性值的实例
Object singletonObject = this.singletonObjects.get(beanName);
//创建bean时,IOC会在this.singletonsCurrentlyInCreation中存一个该bean的名称,表示正在创建这个bean
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
synchronized (this.singletonObjects) {
//也是从缓存中获取实例,但是这个缓存中的实例是没有经过填充的实例
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
//获取生成该bean的beanFactory
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
//获取这个bean的实例
singletonObject = singletonFactory.getObject();
//将这个还未经填充属性的bean存入新生代缓存中(自己取的名字,类似于JVM)
this.earlySingletonObjects.put(beanName, singletonObject);
//将这个生产bean的工厂移除
this.singletonFactories.remove(beanName);
}
}
}
}
return (singletonObject != NULL_OBJECT ? singletonObject : null);
}

  在进行递归调用getBean方法创建依赖对象之前,getSignal方法是先调用的,前面的代码,doGetBean方法中可以看到,可以多看几遍就能理解。另外,对于原型实例,不允许循环引用。循环引用只针对单例。下一篇跟踪bean的属性的填充。

最新文章

  1. [LeetCode] Range Sum Query 2D - Immutable 二维区域和检索 - 不可变
  2. Flash Builder 调试器无法连接到正在运行的应用程序(57%)
  3. Ajax学习记录
  4. jsp错误解决办法
  5. sort,ksort,asort的区别
  6. Django 查询很经典的
  7. IOS拖动
  8. oralce索引和分区索引的使用
  9. C++ const&amp;的一个特性
  10. 进入MFC讲坛的前言(二)
  11. 实验吧_登陆一下好吗(骚注入)&amp;你真的会PHP吗?(代码审计)
  12. ubuntu16.04 离线安装nginx
  13. ASP.NET MVC]WebAPI应用支持HTTPS的经验总结
  14. 【fetch跨域请求】cors
  15. 阿里的Json解析包FastJson使用
  16. List,Set,Collection,Collections比较
  17. 怎么安装WinXP和Win7双系统
  18. wpgcms---设置应用模板
  19. 第八章&#160;高级搜索树 (xa3)红黑树:插入
  20. datatable表格框架服务器端分页查询设置

热门文章

  1. webpack打包不引入vue、echarts等公共库
  2. delphi 中的函数指针 回调函数(传递函数指针,以及它需要的函数参数)
  3. yii联查
  4. Optimizing concurrent accesses in a directory-based coherency protocol
  5. 的二分图poj2446
  6. WPF 判断值是不是NaN
  7. OpenGL(十) 截屏并保存BMP文件
  8. WPF ListBoxItem模板中添加CheckBox选中问题
  9. Angular使用echarts
  10. [转]更改ejs模板后缀.ejs为.html