您的位置:首页 > 其它

Ioc容器初始化过程

2015-03-20 13:29 246 查看
1.ClassPathXmlApplicationContext类体系结构



左边的黄色部分是ApplicationContext体系继承结构,右边是BeanFactory结构体系,两个体系是典型的模板方法设计模式的使用。

从该继承体系可以看出:

(1)BeanFactory是一个bean工厂的最基本定义,里面包含了一个bean工厂的几个最基本方法:getBean(),containsBean()等,是一个很纯粹的bean工厂,不关注资源、资源位置、事件等。



ApplicationContext是一个容器的最基本接口定义,它继承了BeanFactory,拥有工厂的基本方法。同时继承了ApplicationEventPublisher、MessageSource、ResourcePatternResolver等接口,使其定义了一些额外的功能,如事件、资源等这些额外功能。

public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory,
MessageSource, ApplicationEventPublisher, ResourcePatternResolver
public interface HierarchicalBeanFactory extends BeanFactory


(2)AbstractBeanFactory和AbstractAutowireCapableBeanFactory是两个模板抽象工厂类。AbstractBeanFactory提供了bean工厂的抽象基类,同时提供了ConfigurableBeanFactory的完整实现。AbstractAutowireapableBeanFactory是继承了AbstractBeanFactory的抽象工厂,里面提供了bean创建的支持,包括bean的创建、依赖注入、检查等功能,是一个核心的bean工厂类。

(3)ClassPathXmlApplicationContext之所以拥有bean工厂的功能是通过持有一个真正的bean工厂DefaultListableBeanFactory的实例,并通过代理该工厂完成

public class ClassPathXmlApplicationContext extends AbstractXmlApplicationContext
public abstract class AbstractXmlApplicationContext extends AbstractRefreshableConfigApplicationContext
public abstract class AbstractRefreshableConfigApplicationContext extends AbstractRefreshableApplicationContext
implements BeanNameAware, InitializingBean
public abstract class AbstractRefreshableApplicationContext extends AbstractApplicationContext {
.........
/** Bean factory for this context */
private DefaultListableBeanFactory beanFactory;


(4)ClassPathXmlApplicationContext的初始化过程是对本身容器的初始化,同时也是对其持有的DefaultListableBeanFactory的初始化

2.容器初始化过程

整个过程可以通过下图来表示



从xml文件到BeanDefinition的过程是ApplicationContext的职责范围,从BeanDefinition Map到Bean是BeanFactory的职责。可以看出ApplicationContext是一个运行时的容器需要提供不同资源的支持,屏蔽不同环境的差异化。而BeanDefinition是内部关于bean定义的基本结构,bean的创建就是基于它。

整个容器的初始化是通过调用refresh()方法来实现的,该方法定义在AbstractApplicationContext接口中。AbstractApplicationContext是容器的最基础的一个抽象父类。也就是说在里面定义了一个容器初始化的基本流程。

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) {
logger.warn("Exception encountered during context initialization - cancelling refresh attempt", ex);

// Destroy already created singletons to avoid dangling resources.
destroyBeans();

// Reset 'active' flag.
cancelRefresh(ex);

// Propagate exception to caller.
throw ex;
}
}
}
解释如下:



3.Bean的创建过程

Bean的创建过程是BeanFactory索要完成的事情

(1)先看一下BeanDefinition的定义



从接口定义可以看出,通过bean定义能够bean的详细信息,如类名称、工厂类名称、scope、是否单例、是否抽象、是否延迟加载等等。

(2)bean的创建时机

容器初始化的时候,会先对单例和非延迟加载的对象进行预先初始化。其他的都是延迟加载,是在第一次调用getBean的时候被创建。从DefaultListableBeanFactory的preInstantiateSingletons()里可以看到这样的实现规则

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

// 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<Boolean>() {
public Boolean run()
{
return ((SmartFactoryBean<?>) factory).isEagerInit();
}
}, getAccessControlContext());
}
else
{
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
if (isEagerInit)
{
getBean(beanName);
}
}
else
{
getBean(beanName);
}
}
}
}
从上面的代码看,如果用以下配置,只有singletonBean会被预先创建

<?xml version="1.0" encoding="GB2312"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
<beans default-autowire="byName">
<bean id="otherBean"          class="com.test.OtherBean" scope="prototype"/>
<bean id="myBean"          class="com.test.MyBean" lazy-init="true"/>
<bean id="singletonBean"          class="com.test.SingletonBean"/>
</beans>


(3)bean的创建过程

对于bean的创建过程,其实都是通过调用工厂的getBean方法来完成的。在这个方法中会完成对构造函数的选择、依赖注入等。

无论预先创建还是延迟加载都是调用getBean来实现,AbstractBeanFactory定义了getBean的过程:

public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
再看doGetBean()方法

protected <T> T doGetBean(
final String name, final Class<T> 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)
{
getBean(dependsOnBean);
registerDependentBean(dependsOnBean, beanName);
}
}

// Create bean instance.
if (mbd.isSingleton())              //如果是单例,间接通过getSingleton方法来创建,里面会实现将单例对象缓存
{
sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
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 '" + scopeName + "'");
}
try
{
Object scopedInstance = scope.get(beanName, new ObjectFactory<Object>() {
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;
}
doGetBean的大概过程

1)先试着从单例缓存中获取对象

2)从父容器中取定义,有则由父容器创建

3)如果是单例,则走单例对象的创建过程:在spring容器中单例对象和非单例对象的创建过程是一样的。都会调用父类AbstractAutowireCapableBeanFactory的createBean()方法。不同的是单例对象之创建一次并且需要缓存起来。DefaultListableBeanFactory的父类DefaultSingletonBeanRegistry提供了对单例对象缓存等支持工作。所以是单例对象的话,会调用DefaultSingletonBeanRegistry的getSingleton()方法,它会间接调用AbstractAutowireCapableBeanFactory的createBean()方法。

bean的创建是由AbstractAutowireCapableBeanFactory来定义

/**
* Central method of this class: creates a bean instance,
* populates the bean instance, applies post-processors, etc.
* @see #doCreateBean
*/
@Override
protected Object createBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
throws BeanCreationException
{

if (logger.isDebugEnabled())
{
logger.debug("Creating instance of bean '" + beanName + "'");
}
// Make sure bean class is actually resolved at this point.
resolveBeanClass(mbd, beanName);

// Prepare method overrides.
try
{
mbd.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex)
{
throw new BeanDefinitionStoreException(mbd.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}

try
{
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
Object bean = resolveBeforeInstantiation(beanName, mbd);
if (bean != null)
{
return bean;
}
}
catch (Throwable ex)
{
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}

Object beanInstance = doCreateBean(beanName, mbd, args);
if (logger.isDebugEnabled())
{
logger.debug("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
createBean会调用doCreateBean方法

/**
* Actually create the specified bean. Pre-creation processing has already happened
* at this point, e.g. checking {@code postProcessBeforeInstantiation} callbacks.
* <p>Differentiates between default bean instantiation, use of a
* factory method, and autowiring a constructor.
* @param beanName the name of the bean
* @param mbd the merged bean definition for the bean
* @param args arguments to use if creating a prototype using explicit arguments to a
* static factory method. This parameter must be {@code null} except in this case.
* @return a new instance of the bean
* @throws BeanCreationException if the bean could not be created
* @see #instantiateBean
* @see #instantiateUsingFactoryMethod
* @see #autowireConstructor
*/
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);

// Allow post-processors to modify the merged bean definition.
synchronized (mbd.postProcessingLock)
{
if (!mbd.postProcessed)
{
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
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>() {
public Object getObject() throws BeansException
{
return getEarlyBeanReference(beanName, mbd, 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;
}
doCreateBean流程

1)会创建一个BeanWrapper对象,用来存放实例化对象

2)如果没有指定构造函数,会通过反射拿到一个默认的构造函数

3)调用spring的BeanUtils的instantiateClass方法,通过反射创建对象。

4)applyMergedBeanDefinitionPostProcessors

5)populateBean(),根据注入方式进行注入。根据是否有依赖检查进行依赖检查

执行bean注入的时候,会选择注入类型

/**
* Populate the bean instance in the given BeanWrapper with the property values
* from the bean definition.
* @param beanName the name of the bean
* @param mbd the bean definition for the bean
* @param bw BeanWrapper with bean instance
*/
protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw)
{
PropertyValues pvs = mbd.getPropertyValues();

if (bw == null)
{
if (!pvs.isEmpty())
{
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
}
else
{
// Skip property population phase for null instance.
return;
}
}

// Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
// state of the bean before properties are set. This can be used, for example,
// to support styles of field injection.
boolean continueWithPropertyPopulation = true;

if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors())
{
for (BeanPostProcessor bp : getBeanPostProcessors())
{
if (bp instanceof InstantiationAwareBeanPostProcessor)
{
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName))
{
continueWithPropertyPopulation = false;
break;
}
}
}
}

if (!continueWithPropertyPopulation)
{
return;
}

if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE)
{
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);

// Add property values based on autowire by name if applicable.
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) //根据名称注入
{
autowireByName(beanName, mbd, bw, newPvs);
}

// Add property values based on autowire by type if applicable.
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) //根据类型注入
{
autowireByType(beanName, mbd, bw, newPvs);
}

pvs = newPvs;
}

boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);

if (hasInstAwareBpps || needsDepCheck)
{
PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
if (hasInstAwareBpps)
{
for (BeanPostProcessor bp : getBeanPostProcessors())
{
if (bp instanceof InstantiationAwareBeanPostProcessor)
{
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvs == null)
{
return;
}
}
}
}
if (needsDepCheck)
{
checkDependencies(beanName, mbd, filteredPds, pvs);
}
}

applyPropertyValues(beanName, mbd, bw, pvs);
}
6)initializeBean(),判断是否实现了BeanNameAware、BeanClassLoaderAware等spring提供的接口,如果实现了,进行默认的注入。同时判断是否实现了InitializingBean接口,如果实现了,调用afterPropertySet方法

protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
public Object run() {
invokeAwareMethods(beanName, bean);
return null;
}
}, getAccessControlContext());
}
else {
invokeAwareMethods(beanName, bean);
}

Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}

try {
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}

if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}

private void invokeAwareMethods(final String beanName, final Object bean) {
if (bean instanceof Aware) {
if (bean instanceof BeanNameAware) {
((BeanNameAware) bean).setBeanName(beanName);
}
if (bean instanceof BeanClassLoaderAware) {
((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader());
}
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
}
}
}
其中invokeInitMethods实现如下:

protected void invokeInitMethods(String beanName, final Object bean, RootBeanDefinition mbd)
throws Throwable {

boolean isInitializingBean = (bean instanceof InitializingBean);
if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
if (logger.isDebugEnabled()) {
logger.debug("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
}
if (System.getSecurityManager() != null) {
try {
AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
public Object run() throws Exception {
((InitializingBean) bean).afterPropertiesSet();
return null;
}
}, getAccessControlContext());
}
catch (PrivilegedActionException pae) {
throw pae.getException();
}
}
else {
((InitializingBean) bean).afterPropertiesSet();
}
}

if (mbd != null) {
String initMethodName = mbd.getInitMethodName();
if (initMethodName != null && !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
!mbd.isExternallyManagedInitMethod(initMethodName)) {
invokeCustomInitMethod(beanName, bean, mbd);
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: