欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2022-05-23 10:20:16
...

. 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的创建过程~