Spring加载IOC容器以及装载Bean源码解读

. SpringBoot应用开发已经非常普遍,确实,SpringBoot给我们的开发带来了很多便利,但其实,SpringBoot并没有增加什么新特性,只不过是在Spring注解的基础上做了升级版混合使用。SpringBoot的精髓就是自动装配(@EnableAutoConfiguration),我们不需要像以前使用Maven搭建项目时,引入过多的依赖包,同时还需要处理各种包冲突问题,简直是烦的要死,现在只需依赖SpringBoot核心包就能完成简单的应用开发了,所以了解Spring核心原理就非常正要了,下面我们开始从源码角度分析Spring底层原理。
. 下面我们首先定义一个实体类和配置类

/**
 * @Description: Dog实体类
 * @Auther: wenqi
 * @Date: 2019/4/19 20:22
 */
@Data
@ToString
public class Dog  {

    private String name;

    private Integer age;

    public Dog(){
        System.out.println("------>构造函数调用");
    }

    public void init(){
        System.out.println("------>init函数调用");
    }
}

/**
 * @Description: Configuration配置类
 * @Auther: wenqi
 * @Date: 2019/4/19 20:30
 */
@ComponentScan("com.study.spring")
@Configuration
public class DogConfiguration {

    public Dog dog(){
        return new Dog();
    }
}

接下来定一个测试类

/**
 * @Description: 测试类
 * @Auther: wenqi
 * @Date: 2019/4/19 20:31
 */
public class Test {
    @org.junit.Test
    public void test(){
        AnnotationConfigApplicationContext ac =new AnnotationConfigApplicationContext(DogConfiguration.class);
        Dog dog = (Dog) ac.getBean("dog");
        System.out.println(dog);
    }
}

我们就从AnnotationConfigApplicationContext这个类开始,探究下Spring的IOC容器是如何装载Bean的,源码如下:

public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
	this();
	register(annotatedClasses);
	//重点在下面这个方法,创建刷新容器
	refresh();
	}

然后,我们继续向下跟踪这个refresh()方法,这个方法在抽象类AbstractApplicationContext下

@Override
public void refresh() throws BeansException, IllegalStateException {
	synchronized (this.startupShutdownMonitor) {
		// 1、刷新前的预处理
		prepareRefresh();

		// 2、获取BeanFactory
		ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

		// 3、BeanFactory的预准备工作(BeanFactory进行一些设置)
		prepareBeanFactory(beanFactory);

		try {
			// 4、BeanFactory准备工作完成后进行的后置处理工作
			postProcessBeanFactory(beanFactory);

			// 5、执行BeanFactoryPostProcessor的方法
			invokeBeanFactoryPostProcessors(beanFactory);

			// 6、注册BeanPostProcessor(Bean的后置处理器),不同接口类型的BeanPostProcessor;在Bean创建前后的执行时机是不一样的
			registerBeanPostProcessors(beanFactory);

			// 7、初始化MessageSource组件(做国际化功能;消息绑定,消息解析)
			initMessageSource();

			// 8、初始化事件派发器;
			initApplicationEventMulticaster();

			// 9、留给子容器(子类),空方法
			onRefresh();

			// 10、给容器中将所有项目里面的ApplicationListener注册进来
			registerListeners();

			// 11、重点在这,初始化所有剩下的单实例bean(自定义的单例bean)
			finishBeanFactoryInitialization(beanFactory);

			// 12、完成BeanFactory的初始化创建工作;IOC容器就创建完成
			finishRefresh();
		}

		catch (BeansException ex) {
			if (logger.isWarnEnabled()) {
				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;
		}

		finally {
			// Reset common introspection caches in Spring's core, since we
			// might not ever need metadata for singleton beans anymore...
			resetCommonCaches();
		}
	}
}

通过以上步骤,我们发现Spring的IOC容器主要完成了以下操作:
1⃣️、Spring容器在启动的时候,先会保存所有注册进来的Bean的定义信息;
1)、xml注册bean;
2)、注解注册Bean;@Service、@Component、@Bean、xxx
2⃣️、Spring容器会合适的时机创建这些Bean
1)、用到这个bean的时候;利用getBean创建bean;创建好以后保存在容器中;
2)、统一创建剩下所有的bean的时候;finishBeanFactoryInitialization();
3⃣️、后置处理器;BeanPostProcessor
1)、每一个bean创建完成,都会使用各种后置处理器进行处理;来增强bean的功能;
AutowiredAnnotationBeanPostProcessor:处理自动注入
AnnotationAwareAspectJAutoProxyCreator:来做AOP功能;
xxx…
增强的功能注解:
AsyncAnnotationBeanPostProcessor

4⃣️、事件驱动模型;
ApplicationListener;事件监听;
ApplicationEventMulticaster;事件派发:

接下来,我们看下装载我们自己定义的单例bean的过程,主要通过11、finishBeanFactoryInitialization(beanFactory);方法来进行处理。

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
	// 1、判断有无ConversionService(bean属性类型转换服务接口),并初始化
	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));
	}

	// 2、如果beanFactory中不包含EmbeddedValueResolver,则向其中添加一个EmbeddedValueResolver
       // EmbeddedValueResolver-->解析bean中的占位符和表达式
	if (!beanFactory.hasEmbeddedValueResolver()) {
		beanFactory.addEmbeddedValueResolver(new StringValueResolver() {
			@Override
			public String resolveStringValue(String strVal) {
				return getEnvironment().resolvePlaceholders(strVal);
			}
		});
	}

	// 3、初始化LoadTimeWeaverAware类型的bean
      // LoadTimeWeaverAware-->加载Spring Bean时织入第三方模块,如AspectJ
	String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
	for (String weaverAwareName : weaverAwareNames) {
		getBean(weaverAwareName);
	}

	// 4、释放临时类加载器
	beanFactory.setTempClassLoader(null);

	// 5、冻结缓存的BeanDefinition元数据
	beanFactory.freezeConfiguration();

	// 6、重点来了,实例化所有剩余的(非lazy init)单例(包含自定义单例bean)
	beanFactory.preInstantiateSingletons();
}

继续向下跟踪代码,6、beanFactory.preInstantiateSingletons()位于类DefaultListableBeanFactory下,源码如下:

@Override
public void preInstantiateSingletons() throws BeansException {
	if (this.logger.isDebugEnabled()) {
		this.logger.debug("Pre-instantiating singletons in " + this);
	}

	// 1、获取Bean的定义信息
	List<String> beanNames = new ArrayList<String>(this.beanDefinitionNames);
	// 2、触发初始化非懒加载单例beans
	for (String beanName : beanNames) {
		// 2.1、根据beanName获取bean的RootBeanDefinition
		RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
		if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
		    // 2.2、判断为FactoryBean时
			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>() {
						@Override
						public Boolean run() {
							return ((SmartFactoryBean<?>) factory).isEagerInit();
						}
					}, getAccessControlContext());
				}
				else {
					isEagerInit = (factory instanceof SmartFactoryBean &&
							((SmartFactoryBean<?>) factory).isEagerInit());
				}
				if (isEagerInit) {
				    // 2.2.1、重点在这,获取创建bean	
					getBean(beanName);
				}
			}
			// 非FactoryBean
			else { 
				getBean(beanName);
			}
		}
	}
     // 3、所有Bean都利用getBean创建完成以后,检查所有的Bean是否是SmartInitializingSingleton接口的;如果是;就执行afterSingletonsInstantiated();
	for (String beanName : beanNames) {
		Object singletonInstance = getSingleton(beanName);
		if (singletonInstance instanceof SmartInitializingSingleton) {
			final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
			if (System.getSecurityManager() != null) {
				AccessController.doPrivileged(new PrivilegedAction<Object>() {
					@Override
					public Object run() {
						smartSingleton.afterSingletonsInstantiated();
						return null;
					}
				}, getAccessControlContext());
			}
			else {
				smartSingleton.afterSingletonsInstantiated();
			}
		}
	}
}	

重点代码在 2.2.1、getBean(beanName);,根据beanName去获取单例bean信息,我们继续跟踪代码,位于类AbstractBeanFactory

@Override
public Object getBean(String name) throws BeansException {
	return doGetBean(name, null, null, false);
}

protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,	@Nullable final Object[] args, boolean typeCheckOnly)
			throws BeansException {

    // 1、转换bean的名称,去掉&前缀,且如果bean有别名的话,优先使用别名
    final String beanName = transformedBeanName(name);
    Object bean;

    // 2、从缓存中获取bean
    Object sharedInstance = getSingleton(beanName);
    if (sharedInstance != null && args == null) {
        bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
    }

    // 3、如果未能从缓存中获取到bean,则要重新创建bean
    else {
        // Fail if we're already creating this bean instance: We're assumably within a circular reference.
        // 3.1判断指定的原型模式的bean是否当前正在创建(在当前线程内),如果是->则抛出异常(Spring不会解决原型模式bean的循环依赖)
        if (isPrototypeCurrentlyInCreation(beanName)) {
            throw new BeanCurrentlyInCreationException(beanName);
        }

        // Check if bean definition exists in this factory.
        // 3.2 检测bean definition是否存在beanFactory中
        BeanFactory parentBeanFactory = getParentBeanFactory();
        // 如果当前BeanFactory中不包含给定beanName的beanDefinition定义,且父beanFactory不为空,则去父beanFactory中再次查找
        if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
            // 3.3 将name转换为原始beanName
            // 	   因为这里的name已经经过beanName的规范处理,例如:&myBean-->规范-->myBean
            // 	   所以当我们再次去父beanFactory查找时,要将beanName再次转换为原始的beanName,myBean-->回转-->&myBean
            String nameToLookup = originalBeanName(name);
            // 3.4 下面会递归调用各种getBean的方法重载,从当前bean的父factoryBean中加载bean
            if (parentBeanFactory instanceof AbstractBeanFactory) {
                return ((AbstractBeanFactory) parentBeanFactory).doGetBean(nameToLookup, requiredType, args, typeCheckOnly);
            }
            else if (args != null) {
                // 参数不为空,则委托parentBeanFactory使用显式参数调动
                return (T) parentBeanFactory.getBean(nameToLookup, args);
            }
            else if (requiredType != null) {
                // 参数为空,则委托parentBeanFactory使用标准的getBean方法获取bean
                return parentBeanFactory.getBean(nameToLookup, requiredType);
            }
            else {
                // 否则委托parentBeanFactory使用默认的getBean方法
                return (T) parentBeanFactory.getBean(nameToLookup);
            }
        }

        // 3.3 如果当前bean不是用于类型检查,则将该bean标记为已经被创建或者即将被创建
        if (!typeCheckOnly) {
            markBeanAsCreated(beanName);
        }

        try {
            // 3.4 合并beanDefinition,如果指定的bean是一个子bean的话,则遍历其所有的父bean
            final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
            // 校验合并的beanDefinition,如果验证失败,则抛出异常
            checkMergedBeanDefinition(mbd, beanName, args);

            // 3.5 确保初始化当前bean所依赖的bean。
            String[] dependsOn = mbd.getDependsOn();
            if (dependsOn != null) {
                // 循环所有的依赖bean,并递归实例化
                for (String dep : dependsOn) {
                    if (isDependent(beanName, dep)) {
                        throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
                    }
                    // 注册依赖
                    registerDependentBean(dep, beanName);
                    try {
                        // 实例化依赖的bean
                        getBean(dep);
                    }
                    catch (NoSuchBeanDefinitionException ex) {
                        throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                "'" + beanName + "' depends on missing bean '" + dep + "'", ex);
                    }
                }
            }

            // 3.6 创建单例bean
            if (mbd.isSingleton()) {
                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;
                    }
                });
                bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
            }

            // 创建原型模式bean
            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 name '" + scopeName + "'");
                }
                try {
                    Object scopedInstance = scope.get(beanName, () -> {
                        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 && !requiredType.isInstance(bean)) {
        try {
            T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
            if (convertedBean == null) {
                throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
            }
            return convertedBean;
        }
        catch (TypeMismatchException ex) {
            throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
        }
    }
    return (T) bean;
}

该过程是为创建当前单例bean的准备工作。其中包括了:对BeanDefinition的检测、如果当前BeanFactory中不包含BeanDefinition则对父BeanFactory的检测、BeanDefinition的合并、依赖bean的初始化等。获取bean时,先从缓存Map中缓存中取,如果缓存中没有则到第3.6步,开始创建单例bean。
由于篇幅过长,在下面文章继续介绍Bean的创建过程~

猜你喜欢

转载自blog.csdn.net/qq_30035133/article/details/89669574