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