Spring IOC源码分析(七):IOC容器的设计实现与bean对象的创建流程

版权声明:非商业目的可自由转载,转载请标明出处 https://blog.csdn.net/u010013573/article/details/88356151

一、IOC容器的设计与实现

1. 获取bean对象

  • spring主要通过BeanFactory接口的getBean方法来从IOC容器,即BeanFactory的实现类中获取某个bean对象实例,如下为BeanFactory的getBean方法定义:

    public interface BeanFactory {
        
        ...
    
    	/**
    	 * Return an instance, which may be shared or independent, of the specified bean.
    	 * <p>This method allows a Spring BeanFactory to be used as a replacement for the
    	 * Singleton or Prototype design pattern. Callers may retain references to
    	 * returned objects in the case of Singleton beans.
    	 * <p>Translates aliases back to the corresponding canonical bean name.
    	 * Will ask the parent factory if the bean cannot be found in this factory instance.
    	 * @param name the name of the bean to retrieve
    	 * @return an instance of the bean
    	 * @throws NoSuchBeanDefinitionException if there is no bean definition
    	 * with the specified name
    	 * @throws BeansException if the bean could not be obtained
    	 */
    	 
    	// getBean方法的其中一个版本 
    	// 获取name对应的bean对象实例,如果是单例的则直接返回,原型的则每次创建一个新的bean对象实例
    	Object getBean(String name) throws BeansException;
    	
    	...
    	
    }
    
  • 在BeanFactory接口的具体实现类中,通过类型为ConcurrentHashMap的容器map来保存beanName和bean对象实例的映射。

  • 在接口设计层面,BeanFactory接口并不直接定义该映射map,只是定义从该映射map获取bean对象的方法,而是抽象了一个BeanRegistry的概念,分别在SingletonBeanRegistry定义单例bean对象的映射map和在FactoryBeanRegistrySupport定义了由FactoryBean创建的bean对象的映射map;然后BeanFactory接口的具体实现类同时实现BeanFactory接口和BeanRegistry概念的接口SingletonBeanRegistry和FactoryBeanRegistrySupport,从而实现一个完整的IOC容器,类似于使用了一种读写分离的方式来进行接口拓展。

2. 注册bean对象

  • 单例bean对象容器SingletonBeanRegistry:定义了registerSingleton注册bean对象到IOC容器中。

    public interface SingletonBeanRegistry {
    
    	/**
    	 * Register the given existing object as singleton in the bean registry,
    	 * under the given bean name.
    	 * <p>The given instance is supposed to be fully initialized; the registry
    	 * will not perform any initialization callbacks (in particular, it won't
    	 * call InitializingBean's {@code afterPropertiesSet} method).
    	 * The given instance will not receive any destruction callbacks
    	 * (like DisposableBean's {@code destroy} method) either.
    	 * <p>When running within a full BeanFactory: <b>Register a bean definition
    	 * instead of an existing instance if your bean is supposed to receive
    	 * initialization and/or destruction callbacks.</b>
    	 * <p>Typically invoked during registry configuration, but can also be used
    	 * for runtime registration of singletons. As a consequence, a registry
    	 * implementation should synchronize singleton access; it will have to do
    	 * this anyway if it supports a BeanFactory's lazy initialization of singletons.
    	 * @param beanName the name of the bean
    	 * @param singletonObject the existing singleton object
    	 * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet
    	 * @see org.springframework.beans.factory.DisposableBean#destroy
    	 * @see org.springframework.beans.factory.support.BeanDefinitionRegistry#registerBeanDefinition
    	 */
    	void registerSingleton(String beanName, Object singletonObject);
    	
    	...
    	
    }
    
  1. SingletonBeanRegistry接口实现类DefaultSingletonBeanRegistry

    public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {
    
    	/** Cache of singleton objects: bean name to bean instance. */
    	private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
    	
    	...
    	
    }
    
  2. FactoryBean创建的bean对象容器FactoryBeanRegistrySupport:继承于DefaultSingletonBeanRegistry,映射map中的bean对象实例是通过调用FactoryBean的getObject方法获取的bean对象。

    public abstract class FactoryBeanRegistrySupport extends DefaultSingletonBeanRegistry {
    
    	/** Cache of singleton objects created by FactoryBeans: FactoryBean name to object. */
    	private final Map<String, Object> factoryBeanObjectCache = new ConcurrentHashMap<>(16);
    
        ...
        
    }
    

3. 完整的IOC容器

  • BeanFactory的基础抽象实现类:AbstractBeanFactory,AbstractBeanFactory继承了以上的BeanFactory接口和
    SingletonBeanRegistry接口。

    public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory {
    
        ...
        
    }
    

二、IOC容器中bean对象的创建流程

在spring的体系结构设计当中,主要通过ApplicationContext来对外提供IOC服务,即与应用代码集成,而不是在应用代码中直接使用BeanFactory。通过ApplicationContext来初始化BeanFactory和从BeanFactory获取应用所需的bean对象。

1. ApplicationContext的生命周期

  • ApplicationContext的生命周期如下:具体在AbstractApplicationContext的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();
    
    		// 为beanFactory添加内部的BeanPostProcessor的bean对象等
    		// 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);
    
    			// 从beanFactory的beanDefinitions中获取实现了BeanPostProcessor接口的beanDefinition,
    			// 然后创建bean对象,添加到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();
    		}
    
    		...
    		
    	}
    }
    
  • 在finishBeanFactoryInitialization方法是创建单例bean对象,在这里涉及到bean对象的整个创建流程。

  • bean对象的创建是在调用了BeanFactory的getBean方法触发的,即如果指定beanName的bean对象不存在,则开始创建该bean对象实例,如下为AbstractBeanFactory的getBean方法定义:

    public Object getBean(String name) throws BeansException {
    
        // doGetBean底层调用createBean方法创建bean对象实例
    	return doGetBean(name, null, null, false);
    }
    

2. BeanFactory中普通bean对象的创建:不是FactoryBean创建的bean对象

  • 注意以下过程是正常bean对象的创建过程,不是由FactoryBean创建bean对象的过程。FactoryBean创建bean对象是在自身的getObject方法实现的。

  • 底层关于bean对象实例创建的核心方法为createBean:如下为AbstractAutowireCapableBeanFactory的createBean方法定义:核心过程为首先进行类加载,然后检查是否创建代理对象替代该bean对象,如果是则创建代理对象之间返回,否则进入bean对象的正常创建流程,具体在doCreateBean方法定义。

    /**
     * Central method of this class: creates a bean instance,
     * populates the bean instance, applies post-processors, etc.
     * @see #doCreateBean
     */
    @Override
    protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
    		throws BeanCreationException {
    
    	if (logger.isTraceEnabled()) {
    		logger.trace("Creating instance of bean '" + beanName + "'");
    	}
    	RootBeanDefinition mbdToUse = mbd;
    
    	// 为给定bean进行类加载
    
    	// 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.
    	Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
    	if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
    		mbdToUse = new RootBeanDefinition(mbd);
    		mbdToUse.setBeanClass(resolvedClass);
    	}
    
    	// Prepare method overrides.
    	try {
    		mbdToUse.prepareMethodOverrides();
    	}
    	catch (BeanDefinitionValidationException ex) {
    		throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
    				beanName, "Validation of method overrides failed", ex);
    	}
    
    	try {
    		// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
    
    		// 调用InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation
    		// (如果创建了bean,则还要调用BeanPostProcessor的postProcessAfterInitialization)
    
    		// 调用用于生成AOP的代理对象的BeanPostProcessor,如果bean不为null,则说明产生代理对象了,可以直接返回
    		Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
    		if (bean != null) {
    			// 如果bean不为null ,则直接返回,这种情况通常为AOP创建了代理对象。后面的doCreateBean不再执行
    			return bean;
    		}
    	}
    	catch (Throwable ex) {
    		throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
    				"BeanPostProcessor before instantiation of bean failed", ex);
    	}
    
    	try {
    		// 正常的,非代理bean对象的创建
    		// 包括检查是否进行了类加载(没有则进行类加载),bean对象实例创建,bean对象实例的属性赋值,init-method的调用,BeanPostProcessor的调用
    		Object beanInstance = doCreateBean(beanName, mbdToUse, args);
    		if (logger.isTraceEnabled()) {
    			logger.trace("Finished creating instance of bean '" + beanName + "'");
    		}
    		return beanInstance;
    	}
    	catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
    		// A previously detected exception with proper bean creation context already,
    		// or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
    		throw ex;
    	}
    	catch (Throwable ex) {
    		throw new BeanCreationException(
    				mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
    	}
    }
    
  • doCreateBean方法定义一个完整bean对象的创建,在内部完成bean对象后置处理器BeanPostProcessor的调用,初始化相关的init-methdo和InitializingBean的afterPropertiesSet的调用:

    // bean对象实例创建的核心实现方法
    protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
    		throws BeanCreationException {
    
    	// 使用构造函数或者工厂方法来创建bean对象实例
    	// 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.getWrappedInstance();
    	Class<?> beanType = instanceWrapper.getWrappedClass();
    	if (beanType != NullBean.class) {
    		mbd.resolvedTargetType = beanType;
    	}
    
    	// 修改BeanDefinition的BeanPostProcessor的执行,如合并其他BeanDefinition进来
    	// Allow post-processors to modify the merged bean definition.
    	synchronized (mbd.postProcessingLock) {
    		if (!mbd.postProcessed) {
    			try {
    
    				// 调用修改BeanDefinition的BeanPostProcessor,
    				// 即MergedBeanDefinitionPostProcessor的postProcessMergedBeanDefinition
    				applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
    			}
    			catch (Throwable ex) {
    				throw new BeanCreationException(mbd.getResourceDescription(), beanName,
    						"Post-processing of merged bean definition failed", ex);
    			}
    			mbd.postProcessed = true;
    		}
    	}
    
    	...
    
    	// 初始化bean对象实例,包括属性赋值,初始化方法,BeanPostProcessor的执行
    	// Initialize the bean instance.
    	Object exposedObject = bean;
    	try {
    
    		// 1. InstantiationAwareBeanPostProcessor执行:
    		// 	(1). 调用InstantiationAwareBeanPostProcessor的postProcessAfterInstantiation,
    		//  (2). 调用InstantiationAwareBeanPostProcessor的postProcessProperties和postProcessPropertyValues
    		// 2. bean对象的属性赋值
    		populateBean(beanName, mbd, instanceWrapper);
    
    		// 1. Aware接口的方法调用
    		// 2. BeanPostProcess执行:调用BeanPostProcessor的postProcessBeforeInitialization
    		// 3. 调用init-method:首先InitializingBean的afterPropertiesSet,然后应用配置的init-method
    		// 4. BeanPostProcess执行:调用BeanPostProcessor的postProcessAfterInitialization
    		exposedObject = initializeBean(beanName, exposedObject, mbd);
    	}
    
    	...
    
    	// Register bean as disposable.
    	try {
    		registerDisposableBeanIfNecessary(beanName, bean, mbd);
    	}
    	catch (BeanDefinitionValidationException ex) {
    		throw new BeanCreationException(
    				mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
    	}
    
    	return exposedObject;
    }
    

3. FactoryBean创建的bean对象

  • FactoryBean接口在其getObject方法自定义bean对象的创建过程,而不是使用以上的createBean方法,故应用中配置的BeanPostProcessor,InitializingBean接口的方法等不会对FactoryBean创建的bean对象起作用。
  • 这样设计也保证了spring自身可以利用FactoryBean接口来创建bean对象,如内部组件,而不会受到应用代码的影响。

4. 注册到IOC容器

单例bean对象
  • 单例bean对象注册到IOC容器是在doGetBean方法内完成的,核心逻辑为getSingleton:调用createBean方法创建bean对象实例然后注册到单例bean对象映射map中。

    // Create bean instance.
    if (mbd.isSingleton()) {
    	
    	// 创建bean对象实例并注册到单例bean映射map中
    	sharedInstance = getSingleton(beanName, () -> {
    		try {
    			// bean对象实例创建
    			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;
    		}
    	});
    
    	// 如果sharedInstance不是FactoryBean接口的实现类,则直接返回sharedInstance;
    	// 否则调用sharedInstance的getObject方法获取实际的bean对象
    	bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
    }
    
  • 在getSingleton方法内调用addSingleton方法将该bean对象存放到单例bean对象映射map,即singletonObjects:

    protected void addSingleton(String beanName, Object singletonObject) {
    	synchronized (this.singletonObjects) {
    		this.singletonObjects.put(beanName, singletonObject);
    		this.singletonFactories.remove(beanName);
    		this.earlySingletonObjects.remove(beanName);
    		this.registeredSingletons.add(beanName);
    	}
    }
    
FactoryBean创建的bean对象
  • FactoryBean创建的bean对象,即调用FactoryBean的getObject方法返回的bean对象,注册到IOC容器(由FactoryBean创建的bean对象的映射map,即FactoryBeanRegistrySupport的factoryBeanObjectCache),也是在doGetBean方法中实现的,具体在FactoryBeanRegistrySupport的getObjectForBeanInstance方法实现。

猜你喜欢

转载自blog.csdn.net/u010013573/article/details/88356151