转自:http://singleant.iteye.com/blog/1177358
本文将以ClassPathXmlApplicationContext这个容器的实现作为基础,学习容器的初始化过程。
ClassPathXmlApplicationContext类体系结构
以下是ClassPathXmlApplicationContext的类继承体系结构,理解这个结构有助于后面的代码理解。
左边黄色部分是ApplicationContext体系继承结构,右边是BeanFactory的结构体系,两个结构是典型模板方法设计模式的使用。
从该继承体系可以看出:
1. BeanFactory是一个bean工厂的最基本定义,里面包含了一个bean工厂的几个最基本的方法,getBean(…)、containsBean(…)等,是一个很纯粹的bean工厂,不关注资源、资源位置、事件等。ApplicationContext是一个容器的最基本接口定义,它继承了BeanFactory,拥有工厂的基本方法。同时继承了ApplicationEventPublisher、MessageSource、ResourcePatternResolver等接口,使其定义了一些额外的功能,如资源、事件等这些额外的功能。
2. AbstractBeanFactory和AbstractAutowireCapableBeanFactory是两个模板抽象工厂类。AbstractBeanFactory提供了bean工厂的抽象基类,同时提供了ConfigurableBeanFactory的完整实现。AbstractAutowireCapableBeanFactory是继承了AbstractBeanFactory的抽象工厂,里面提供了bean创建的支持,包括bean的创建、依赖注入、检查等等功能,是一个核心的bean工厂基类。
3. ClassPathXmlApplicationContext之所以拥有bean工厂的功能是通过持有一个真正的bean工厂DefaultListableBeanFactory的实例,并通过代理该工厂完成。
4. ClassPathXmlApplicationContext的初始化过程是对本身容器的初始化同时也是对其持有的DefaultListableBeanFactory的初始化。
下面通过源码着重介绍一个容器的初始化过程,并重点理解bean的创建过程。
容器初始化过程
通过上文 啃啃老菜: Spring IOC核心源码学习(一) 已经可以了解一个容器的大概过程是:
整个过程可以理解为是容器的初始化过程。第一个过程是ApplicationContext的职责范围,第二步是BeanFactory的职责范围。可以看出ApplicationContext是一个运行时的容器需要提供不容资源环境的支持,屏蔽不同环境的差异化。而BeanDifinition是内部关于bean定义的基本结构。Bean的创建就是基于它,回头会介绍一下改结构的定义。下面看一下整个容器的初始化过程。
容器的初始化是通过调用refresh()来实现。该方法是非常重要的一个方法,定义在AbstractApplicationContext接口里。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();
- // 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) {
- // Destroy already created singletons to avoid dangling resources.
- beanFactory.destroySingletons();
- // Reset 'active' flag.
- cancelRefresh(ex);
- // Propagate exception to caller.
- throw ex;
- }
- }
- }
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) { // Destroy already created singletons to avoid dangling resources. beanFactory.destroySingletons(); // Reset 'active' flag. cancelRefresh(ex); // Propagate exception to caller. throw ex; } } }
解释如下:
Bean的创建过程
Bean的创建过程基本是BeanFactory所要完成的事情.
根据以上过程,将会重点带着以下两个个问题来理解核心代码:
1.Bean的创建时机
bean是在什么时候被创建的,有哪些规则。
2.Bean的创建过程
bean是怎么创建的,会选择哪个构造函数?依赖如何注入?InitializingBean的set方法什么时候被调用?实现ApplicationContextAware, BeanFactoryAware,BeanNameAware, ResourceLoaderAware 这些接口的bean的set方法何时被调用?
在解释这两个问题前,先看一下BeanDefinition接口的定义。
从该接口定义可以看出,通过bean定义能够得到bean的详细信息,如类名子、工厂类名称、scope、是否单例、是否抽象、是否延迟加载等等。基于此,来看一下以下两个问题:
问题1:Bean的创建时机
bean是在什么时候被创建的,有哪些规则?
容器初始化的时候会预先对单例和非延迟加载的对象进行预先初始化。其他的都是延迟加载是在第一次调用getBean的时候被创建。从DefaultListableBeanFactory的preInstantiateSingletons里可以看到这个规则的实现。
- public void preInstantiateSingletons() throws BeansException {
- if (this.logger.isInfoEnabled()) {
- this.logger.info("Pre-instantiating singletons in " + this);
- }
- synchronized (this.beanDefinitionMap) {
- for (Iterator it = this.beanDefinitionNames.iterator(); it.hasNext();) {
- String beanName = (String) it.next();
- RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
- <span style="color: rgb(255, 0, 0);">if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {</span>
- //对非抽象、单例的和非延迟加载的对象进行实例化。
- if (isFactoryBean(beanName)) {
- FactoryBean factory = (FactoryBean) getBean(FACTORY_BEAN_PREFIX + beanName);
- if (factory instanceof SmartFactoryBean && ((SmartFactoryBean) factory).isEagerInit()) {
- getBean(beanName);
- }
- }
- else {
- getBean(beanName);
- }
- }
- }
- }
- }
public void preInstantiateSingletons() throws BeansException { if (this.logger.isInfoEnabled()) { this.logger.info("Pre-instantiating singletons in " + this); } synchronized (this.beanDefinitionMap) { for (Iterator it = this.beanDefinitionNames.iterator(); it.hasNext();) { String beanName = (String) it.next(); RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName); if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {//对非抽象、单例的和非延迟加载的对象进行实例化。 if (isFactoryBean(beanName)) { FactoryBean factory = (FactoryBean) getBean(FACTORY_BEAN_PREFIX + beanName); if (factory instanceof SmartFactoryBean && ((SmartFactoryBean) factory).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>
<?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>
问题二:Bean的创建过程
对于bean的创建过程其实都是通过调用工厂的getBean方法来完成的。这里面将会完成对构造函数的选择、依赖注入等。
无论预先创建还是延迟加载都是调用getBean实现,AbstractBeanFactory定义了getBean的过程:
- protected Object doGetBean(
- final String name, final Class requiredType, final Object[] args, boolean typeCheckOnly) throws BeansException {
- final String beanName = transformedBeanName(name);
- Object bean = null;
- // 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 parentBeanFactory.getBean(nameToLookup, args);
- }
- else {
- // No args -> delegate to standard getBean method.
- return parentBeanFactory.getBean(nameToLookup, requiredType);
- }
- }
- if (!typeCheckOnly) {
- markBeanAsCreated(beanName);
- }
- 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 (int i = 0; i < dependsOn.length; i++) {
- String dependsOnBean = dependsOn[i];
- getBean(dependsOnBean);
- registerDependentBean(dependsOnBean, beanName);
- }
- }
- // Create bean instance.
- <span style="color: rgb(255, 0, 0);">if (mbd.isSingleton()) {//单例对象创建过程,间接通过getSingleton方法来创建,里面会实现将单例对象缓存</span>
- sharedInstance = getSingleton(beanName, new ObjectFactory() {
- 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);
- }
- <span style="color: rgb(255, 0, 0);">else if (mbd.isPrototype()) {//非单例对象创建</span>
- // It's a prototype -> create a new instance.
- Object prototypeInstance = null;
- try {
- beforePrototypeCreation(beanName);
- prototypeInstance = createBean(beanName, mbd, args);<span style="color: rgb(255, 0, 0);">//直接调用createBean</span>
- }
- finally {
- afterPrototypeCreation(beanName);
- }
- bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
- }
- else {
- String scopeName = mbd.getScope();
- final Scope 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() {
- 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);
- }
- }
- }
- // Check if required type matches the type of the actual bean instance.
- if (requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass())) {
- throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
- }
- return bean;
- }
protected Object doGetBean( final String name, final Class requiredType, final Object[] args, boolean typeCheckOnly) throws BeansException { final String beanName = transformedBeanName(name); Object bean = null; // 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 parentBeanFactory.getBean(nameToLookup, args); } else { // No args -> delegate to standard getBean method. return parentBeanFactory.getBean(nameToLookup, requiredType); } } if (!typeCheckOnly) { markBeanAsCreated(beanName); } 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 (int i = 0; i < dependsOn.length; i++) { String dependsOnBean = dependsOn[i]; getBean(dependsOnBean); registerDependentBean(dependsOnBean, beanName); } } // Create bean instance. if (mbd.isSingleton()) {//单例对象创建过程,间接通过getSingleton方法来创建,里面会实现将单例对象缓存 sharedInstance = getSingleton(beanName, new ObjectFactory() { 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);//直接调用createBean } finally { afterPrototypeCreation(beanName); } bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd); } else { String scopeName = mbd.getScope(); final Scope 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() { 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); } } } // Check if required type matches the type of the actual bean instance. if (requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass())) { throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass()); } return bean; }
GetBean的大概过程:
1. 先试着从单例缓存对象里获取。
2. 从父容器里取定义,有则由父容器创建。
3. 如果是单例,则走单例对象的创建过程:在spring容器里单例对象和非单例对象的创建过程是一样的。都会调用父类AbstractAutowireCapableBeanFactory的createBean方法。不同的是单例对象只创建一次并且需要缓存起来。DefaultListableBeanFactory的父类DefaultSingletonBeanRegistry提供了对单例对象缓存等支持工作。所以是单例对象的话会调用DefaultSingletonBeanRegistry的getSingleton方法,它会间接调用AbstractAutowireCapableBeanFactory的createBean方法。
如果是Prototype多例则直接调用父类AbstractAutowireCapableBeanFactory的createBean方法。
bean的创建是由AbstractAutowireCapableBeanFactory来定义:
- protected Object createBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
- throws BeanCreationException {
- AccessControlContext acc = AccessController.getContext();
- return AccessController.doPrivileged(new PrivilegedAction() {
- public Object run() {
- 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;
- }
- }, acc);
- }
protected Object createBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) throws BeanCreationException { AccessControlContext acc = AccessController.getContext(); return AccessController.doPrivileged(new PrivilegedAction() { public Object run() { 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; } }, acc); }
createBean会调用doCreateBean方法:
- protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) {
- // Instantiate the bean.
- BeanWrapper instanceWrapper = null;
- if (mbd.isSingleton()) {
- instanceWrapper = (BeanWrapper) 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() {
- public Object getObject() throws BeansException {
- return getEarlyBeanReference(beanName, mbd, bean);
- }
- });
- }
- // Initialize the bean instance.
- Object exposedObject = bean;
- try {
- populateBean(beanName, mbd, instanceWrapper);
- 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 actualDependentBeans = new LinkedHashSet(dependentBeans.length);
- for (int i = 0; i < dependentBeans.length; i++) {
- String dependentBean = dependentBeans[i];
- 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.
- registerDisposableBeanIfNecessary(beanName, bean, mbd);
- return exposedObject;
- }
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) { // Instantiate the bean. BeanWrapper instanceWrapper = null; if (mbd.isSingleton()) { instanceWrapper = (BeanWrapper) 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() { public Object getObject() throws BeansException { return getEarlyBeanReference(beanName, mbd, bean); } }); } // Initialize the bean instance. Object exposedObject = bean; try { populateBean(beanName, mbd, instanceWrapper); 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 actualDependentBeans = new LinkedHashSet(dependentBeans.length); for (int i = 0; i < dependentBeans.length; i++) { String dependentBean = dependentBeans[i]; 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. registerDisposableBeanIfNecessary(beanName, bean, mbd); return exposedObject; }
doCreateBean的流程:
1. 会创建一个BeanWrapper 对象 用于存放实例化对象。
2. 如果没有指定构造函数,会通过反射拿到一个默认的构造函数对象,并赋予beanDefinition.resolvedConstructorOrFactoryMethod。
3. 调用spring的BeanUtils的instantiateClass方法,通过反射创建对象。
4. applyMergedBeanDefinitionPostProcessors
5. populateBean(beanName, mbd, instanceWrapper);根据注入方式进行注入。根据是否有依赖检查进行依赖检查。
执行bean的注入里面会选择注入类型:
- 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);
- }<span style="color: rgb(255, 0, 0);">//根据名字注入</span>
- // Add property values based on autowire by type if applicable.
- if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
- autowireByType(beanName, mbd, bw, newPvs);
- }<span style="color: rgb(255, 0, 0);">//根据类型注入</span>
- pvs = newPvs;
- }
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; }
6. initializeBean(beanName, exposedObject, mbd);
判断是否实现了BeanNameAware、BeanClassLoaderAware等spring提供的接口,如果实现了,进行默认的注入。同时判断是否实现了InitializingBean接口,如果是的话,调用afterPropertySet方法。
- protected Object initializeBean(String beanName, Object bean, RootBeanDefinition mbd) {
- if (bean instanceof BeanNameAware) {
- ((BeanNameAware) bean).setBeanName(beanName);
- }
- if (bean instanceof BeanClassLoaderAware) {
- ((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader());
- }
- if (bean instanceof BeanFactoryAware) {
- ((BeanFactoryAware) bean).setBeanFactory(this);
- }
- Object wrappedBean = bean;
- if (mbd == null || !mbd.isSynthetic()) {
- wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
- }
- <span style="color: rgb(255, 0, 0);"> try {
- invokeInitMethods(beanName, wrappedBean, mbd);
- }</span>
- 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;
- }
protected Object initializeBean(String beanName, Object bean, RootBeanDefinition mbd) { if (bean instanceof BeanNameAware) { ((BeanNameAware) bean).setBeanName(beanName); } if (bean instanceof BeanClassLoaderAware) { ((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader()); } if (bean instanceof BeanFactoryAware) { ((BeanFactoryAware) bean).setBeanFactory(this); } 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; }
其中invokeInitMethods实现如下:
- protected void invokeInitMethods(String beanName, 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 + "'");
- }
- ((InitializingBean) bean).afterPropertiesSet();<span style="color: rgb(255, 0, 0);">//调用afterPropertiesSet方法</span>
- }
- String initMethodName = (mbd != null ? mbd.getInitMethodName() : null);
- if (initMethodName != null && !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
- !mbd.isExternallyManagedInitMethod(initMethodName)) {
- invokeCustomInitMethod(beanName, bean, initMethodName, mbd.isEnforceInitMethod());
- }
- }
protected void invokeInitMethods(String beanName, 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 + "'"); } ((InitializingBean) bean).afterPropertiesSet();//调用afterPropertiesSet方法 } String initMethodName = (mbd != null ? mbd.getInitMethodName() : null); if (initMethodName != null && !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) && !mbd.isExternallyManagedInitMethod(initMethodName)) { invokeCustomInitMethod(beanName, bean, initMethodName, mbd.isEnforceInitMethod()); } }
总结
以上基本描述了spring容器的初始化过程和bean的创建过程。主要还是从大处着眼,很多细节没有涉及到。代码阅读总体感觉就是spring的代码抽象很好,结合结构读起来还是蛮顺利的。后面的学习将从细节着手。
下面源码学习预告:
1. Spring的声明式标签如实现
2. Spring aop代理如何实现
---------------------------------------------------------------
-------------------------------------------
提到spring,第一印象就是DI与IOC,虽然有概念上的解释,但是要理解这些概念还是需要动手进行试验。如果要深入了解spring的原来,那么最先了解得就应该是spring容器。Spring提供了两个核心的IOC容器接口:
1.beanFactory: IOC 容器的基本实现。
2.ApplicationContext: 提供了更多的高级特性,是beanFactory的子接口。
在spring的应用中,经常见到的代码就是如下典型的从容器中获取bean实例的代码:
ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
OrderService service = (OrderService)ctx.getbean("personService");
第一行代码就是创建一个IOC容器的实例。BeanFactory、ApplicationContext只是接口,在应用中需要实例化其实现类。ApplicationContext实现类有以下三种是经常要用到的:
ClassPathXmlApplicationContext: 从 classpath 下加载配置文件
FileSystemXmlApplicationContext: 从文件系统中加载配置文件
XmlWebApplicationContext: 只能用于 web 应用
无论使用何种方式, 配置文件时相同的。但是由于ApplicationContext提供了更多的附加功能,比如它提供了文本信息解析工具、载入资源的通用方法等等,所以使用的时候大部分都是用该接口。在web应用中通常都是通过ClassPathXmlApplicationContext去类路径下加载配置文件,生成一个IOC容器并管理配置文件中配置的bean。
Spring提供了强大的IOC容器来管理组成应用程序中的bean(组件)。要利用容器提供的服务,就必须配置bean,让这些bean运行在Spring IOC容器中。为了让Spring IOC 容器能够对bean进行实例化,每个bean 都应该提供一个唯一的名称和一个全限定类名。例如下面三种方式实例化bean:
1.使用类构造器实例化
<bean id="orderService" class="cn.itcast.OrderServiceBean"/>
2.使用静态工厂方法实例化
<bean id="personService" class="cn.itcast.service.OrderFactory" factory-method="createOrder"/>
public class OrderFactory {
public static OrderServiceBean createOrder(){
return new OrderServiceBean();
}
}
3.使用实例工厂方法实例化:
<bean id="personServiceFactory" class="cn.itcast.service.OrderFactory"/>
<bean id="personService" factory-bean="personServiceFactory" factory-method="createOrder"/>
public class OrderFactory {
public OrderServiceBean createOrder(){
return new OrderServiceBean();
}
}
第一种方法,IOC容易直接根据配置文件中的class属性通过反射创建一个实例,使用的是该类的默认构造方法。第二种则是调用class指定的工厂类的工厂方法,来返回一个相应的bean实例,值得注意的是工厂类的方法是静态方法,所以不用产生工厂本身的实例。而第三种则不同,它除了配置与第二种相同外,唯一的不同就是方法不是静态的,所以创建bean的实例对象时需要先生成工厂类的实例。
实例了bean对象时,需要对其中的属性也进行赋值,这时就是经常被提及的依赖注入。对bean的每个简单类型的属性来说,可以为其制定<value>元素。Spring会尝试将值转换为该属性的声明类型。比较常用的有:
1.setter注入使用<property>元素,使用name属性指定bean的属性名称。优点: setter 方法可以自动生成,简单。缺点: 组件使用者或许会忘记给组件注入它需要的依赖; 在第一次注入后,依赖可能会因为 setter 方法的调用而被修改。
2.构造器注入在 <constructor-arg>元素里声明属性,因为构造器的参数是基于位置的, 所以 <constructor-arg>中没有name属性。优点: 解决了setter注入的缺点。缺点: 需通过参数位置来确定参数; 若组件有多个依赖需要注入, 会导致构造器参数列表非常冗长。
IOC容器里可能会声明很多的bean,这些bean之间的依赖关系通常会比较复杂。使用setter注入并不能保证属性一定会被注入。spring通过依赖检查来检查属性:
1.Spring 的依赖检查特性可以检查bean上的某些类型的所有属性是否被设置。
2.Spring 的依赖检查特性只需在<bean>的dependency-check 属性里指定依赖检查模式即可。
3.Spring 的依赖检查特性只能检查属性是否被设置,但对设置的属性值是 null 的情况则无能为力。
4.Spring 的依赖检查特性只对属性是否通过 setter 方法设置进行检查。 所以, 即使通过构造器注入,依然会抛出异常。
以上是通过配置文件来检查,另外一种方式就是通过@Required注解检查属性。Spring的依赖检查特性只能检查某些类型的所有属性。不能只针对个别属性进行检查。RequiredAnnotationbeanPostProcessor 是Spring的bean后置处理器,它检查所有具有@Required注解的属性是否已被设置。bean后置处理器是一种特殊类型的Spring bean,它能够在每个bean实例化后执行一些额外的工作。要激活bean后置处理器来进行属性检查,必须在Spring IOC容器里注册它。RequiredAnnotationbeanPostProcessor只能检查属性是否被设置,但对设置的属性值是 null 的情况则无能为力。