SpringMVC 源代码深度解析 IOC容器(Bean实例化和依赖注入)

   SpringMVC最核心的IOC的控制反转,动态的向某个对象提供它所需要的其他对象,例如:对象A时,需要对象B时,这时不像以前我们之前要在A对象里实例化B对象,这时B对象的实例化由IOC容器会主动创建一个对象B然后注入到对象A里,提供使用。我们项目开发中,最经常用到,那怎么实现实例Bean并依赖注入呢?我们今天带着这些问题来通过SpringMVC源代码进行深入的解析。这篇介绍不对注解实例化和注入进行讲解,这个放在后面在介绍。

    我们平常写的一个类,并依赖调用了类的某个方法,这时需要依赖那个类已经实例化,这样才能调用,这些都是交给IOC控制反转,这是我们写的一个类,代码如下

  1. package cn.test.service.impl;  
  2.   
  3. import cn.test.service.TestService2;  
  4.   
  5. public class TestServiceImpl2 implements TestService2{  
  6.   
  7. }  
package cn.test.service.impl;

import cn.test.service.TestService2;

public class TestServiceImpl2 implements TestService2{

}

      

  1. package cn.test.service.impl;  
  2.   
  3. import cn.test.service.TestService;  
  4. import cn.test.service.TestService2;  
  5.   
  6. public class TestServiceImpl implements TestService{  
  7.       
  8.       
  9.     private TestServiceImpl(){  
  10.         System.out.println("xx");  
  11.     }  
  12.   
  13.     private TestService2 testService2;  
  14.   
  15.     public TestService2 getTestService2() {  
  16.         return testService2;  
  17.     }  
  18.   
  19.     public void setTestService2(TestService2 testService2) {  
  20.         this.testService2 = testService2;  
  21.     }  
  22.       
  23. }  
package cn.test.service.impl;

import cn.test.service.TestService;
import cn.test.service.TestService2;

public class TestServiceImpl implements TestService{
	
	
	private TestServiceImpl(){
		System.out.println("xx");
	}

	private TestService2 testService2;

	public TestService2 getTestService2() {
		return testService2;
	}

	public void setTestService2(TestService2 testService2) {
		this.testService2 = testService2;
	}
	
}

在配置文件配置了对应的Bean

  1. <span style="font-size:18px;">   <bean id="testService" class="cn.test.service.impl.TestServiceImpl" >  
  2.      <property name="testService2" ref="testService2"></property>  
  3.    </bean>  
  4.      
  5.    <bean id="testService2" class="cn.test.service.impl.TestServiceImpl2" ></bean></span>  
<span style="font-size:18px;">   <bean id="testService" class="cn.test.service.impl.TestServiceImpl" >
     <property name="testService2" ref="testService2"></property>
   </bean>
   
   <bean id="testService2" class="cn.test.service.impl.TestServiceImpl2" ></bean></span>
  那SpringMVC 怎么实现实例 B ean并依赖注入?我们带着上面实现的代码来解析。

   首先我们先回到refresh这个方法,上一篇Bean解析和注册大家应该还记得吧,里面有postProcessBeanFactory这个方法,就是实例化bean的,我们带着好奇心来分析了解。当Bean定义资源被载入IoC容器之后,容器将Bean定义资源解析为容器内部的数据结构,然后BeanDefinition注册到容器中,AbstractApplicationContext类中的finishBeanFactoryInitialization方法对配置了属性的Bean进行初始化过程,源码如下:

      

  1. protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {  
  2.         // CONVERSION_SERVICE_BEAN_NAME为转换服务(ConversionService)    
  3.         if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&  
  4.                 beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {  
  5.             beanFactory.setConversionService(  
  6.                     beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));  
  7.         }  
  8.   
  9.         // Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.  
  10.         String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.classfalsefalse);  
  11.         for (String weaverAwareName : weaverAwareNames) {  
  12.             getBean(weaverAwareName);  
  13.         }  
  14.   
  15.         // Stop using the temporary ClassLoader for type matching.  
  16.         beanFactory.setTempClassLoader(null);  
  17.   
  18.         // Allow for caching all bean definition metadata, not expecting further changes.  
  19.         beanFactory.freezeConfiguration();  
  20.   
  21.         // 对bean进行实例化  
  22.         <span style="color:#ff0000;">beanFactory.preInstantiateSingletons();</span>  
  23.     }  
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
		// CONVERSION_SERVICE_BEAN_NAME为转换服务(ConversionService)  
		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();

		// 对bean进行实例化
		<span style="color:#ff0000;">beanFactory.preInstantiateSingletons();</span>
	}

preInstantiateSingletons由对bean进行实例化由子类DefaultListableBeanFactory来实现的。源代码:

  

  1. public void preInstantiateSingletons() throws BeansException {  
  2.         if (this.logger.isInfoEnabled()) {  
  3.             this.logger.info("Pre-instantiating singletons in " + this);  
  4.         }  
  5.         List<String> beanNames;  
  6.         synchronized (this.beanDefinitionMap) {  
  7.             // Iterate over a copy to allow for init methods which in turn register new bean definitions.  
  8.             // While this may not be part of the regular factory bootstrap, it does otherwise work fine.  
  9.             beanNames = new ArrayList<String>(this.beanDefinitionNames);  
  10.         }  
  11.         for (String beanName : beanNames) {  
  12.             RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);  
  13.             if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {  
  14.                 if (isFactoryBean(beanName)) {  
  15.                     final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);  
  16.                     boolean isEagerInit;  
  17.                     if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {  
  18.                         isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {  
  19.                             public Boolean run() {  
  20.                                 return ((SmartFactoryBean<?>) factory).isEagerInit();  
  21.                             }  
  22.                         }, getAccessControlContext());  
  23.                     }  
  24.                     else {  
  25.                         isEagerInit = (factory instanceof SmartFactoryBean &&  
  26.                                 ((SmartFactoryBean<?>) factory).isEagerInit());  
  27.                     }  
  28.                     if (isEagerInit) {  
  29.                         getBean(beanName);  
  30.                     }  
  31.                 }  
  32.                 else {  
  33.                     <span style="color:#cc0000;">getBean(beanName);</span>  
  34.                 }  
  35.             }  
  36.         }  
  37.     }  
public void preInstantiateSingletons() throws BeansException {
		if (this.logger.isInfoEnabled()) {
			this.logger.info("Pre-instantiating singletons in " + this);
		}
		List<String> beanNames;
		synchronized (this.beanDefinitionMap) {
			// 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.
			beanNames = new ArrayList<String>(this.beanDefinitionNames);
		}
		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<Boolean>() {
							public Boolean run() {
								return ((SmartFactoryBean<?>) factory).isEagerInit();
							}
						}, getAccessControlContext());
					}
					else {
						isEagerInit = (factory instanceof SmartFactoryBean &&
								((SmartFactoryBean<?>) factory).isEagerInit());
					}
					if (isEagerInit) {
						getBean(beanName);
					}
				}
				else {
					<span style="color:#cc0000;">getBean(beanName);</span>
				}
			}
		}
	}

 getBean(beanName);bean进行实例化并对属性依赖进行注入过程。前面解析的代码不重要,主要是入口点,接下来才是重点, 创建bean时,如果缓存中有单例Bean时,就从缓存获取,如果没有就新建,通过匿名的内部类来创建Bean时根据Bean的作用域来创建的,有单实例作用域、原型作用域、Request等。源代码如下:

  1. public Object getBean(String name) throws BeansException {  
  2.         return doGetBean(name, nullnullfalse);  
  3.     }  
  4.     @SuppressWarnings("unchecked")  
  5.     protected <T> T doGetBean(  
  6.             final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)  
  7.             throws BeansException {  
  8.         //如果指定的是别名,将别名转换为规范的Bean名称   
  9.         final String beanName = transformedBeanName(name);  
  10.         Object bean;  
  11.   
  12.         // 如果缓存中有单例Bean时,就从缓存获取  
  13.         Object sharedInstance = getSingleton(beanName);  
  14.         if (sharedInstance != null && args == null) {  
  15.             if (logger.isDebugEnabled()) {  
  16.                 if (isSingletonCurrentlyInCreation(beanName)) {  
  17.                     logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +  
  18.                             "' that is not fully initialized yet - a consequence of a circular reference");  
  19.                 }  
  20.                 else {  
  21.                     logger.debug("Returning cached instance of singleton bean '" + beanName + "'");  
  22.                 }  
  23.             }  
  24.             bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);  
  25.         }  
  26.   
  27.         else {  
  28.             // Fail if we're already creating this bean instance:  
  29.             // We're assumably within a circular reference.  
  30.             if (isPrototypeCurrentlyInCreation(beanName)) {  
  31.                 throw new BeanCurrentlyInCreationException(beanName);  
  32.             }  
  33.   
  34.             // 获取父工厂  
  35.             BeanFactory parentBeanFactory = getParentBeanFactory();  
  36.             //检查BeanDefinition是否有当前的BeanFactory,如果没有,就到父工厂去查找  
  37.             if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {  
  38.                 // Not found -> check parent.  
  39.                 String nameToLookup = originalBeanName(name);  
  40.                 if (args != null) {  
  41.                     // Delegation to parent with explicit args.  
  42.                     return (T) parentBeanFactory.getBean(nameToLookup, args);  
  43.                 }  
  44.                 else {  
  45.                     // No args -> delegate to standard getBean method.  
  46.                     return parentBeanFactory.getBean(nameToLookup, requiredType);  
  47.                 }  
  48.             }  
  49.   
  50.             if (!typeCheckOnly) {  
  51.                 markBeanAsCreated(beanName);  
  52.             }  
  53.   
  54.             try {  
  55.                //看说明(2)  
  56.                 final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);  
  57.   
  58.                //是否为抽象的、是否Prototype  
  59.                 checkMergedBeanDefinition(mbd, beanName, args);  
  60.   
  61.                 // 获取当前Bean所有依赖Bean的名称  
  62.                 String[] dependsOn = mbd.getDependsOn();  
  63.                 if (dependsOn != null) {  
  64.                     for (String dependsOnBean : dependsOn) {  
  65.                         //递归调用getBean方法  
  66.                         getBean(dependsOnBean);  
  67.                         //注册依赖的bean  
  68.                         registerDependentBean(dependsOnBean, beanName);  
  69.                     }  
  70.                 }  
  71.   
  72.                 // 创建单例bean实例  
  73.                 if (mbd.isSingleton()) {  
  74.                   //内部类,实现创建bean  
  75.                     sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {  
  76.                         public Object getObject() throws BeansException {  
  77.                             try {  
  78.                                //创建bean  
  79.                                 return createBean(beanName, mbd, args);  
  80.   
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值