SpringBoot应用开发已经非常普遍,的确,SpringBoot给我们的开发带来了很多便利,但其实,SpringBoot并没有增加什么新特性,只不过是在Spring注解的基础上做了升级版混合使用。SpringBoot的精髓就是自动装配(@EnableAutoConfiguration),我们不需要像以前使用Maven搭建项目时,引入过多的依赖包,同时还需要处理各种包冲突问题,简直是烦的要死,现在只需依赖SpringBoot核心包就能完成简单的应用开发了,所以了解Spring核心原理就非常重要了,下面我们开始从源码角度分析Spring底层原理。
下面我们首先定义一个实体类和配置类
/** * @Description: Dog实体类 * @Auther: Java思享汇 */@Data@ToStringpublic class Dog { private String name; private Integer age; public Dog(){ System.out.println("------>构造函数调用"); } public void init(){ System.out.println("------>init函数调用"); }}
/** * @Description: Configuration配置类 * @Auther: Java思享汇 */@ComponentScan("com.study.spring")@Configurationpublic class DogConfiguration { public Dog dog(){ return new Dog(); }}
接下来定一个测试类
/** * @Description: 测试类 * @Auther: Java思享汇 */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下
@Overridepublic void refresh() throws BeansException, IllegalStateException {synchronized (this.startupShutdownMonitor) {// 1、刷新前的预处理prepareRefresh();// 2、获取BeanFactoryConfigurableListableBeanFactory 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的定义信息;
- xml注册bean;
- 注解注册Bean;@Service、@Component、@Bean
2⃣️、Spring容器会合适的时机创建这些Bean
- 用到这个bean的时候;利用getBean创建bean;创建好以后保存在容器中;
- 统一创建剩下所有的bean的时候;finishBeanFactoryInitialization();
3⃣️、后置处理器;BeanPostProcessor
- 每一个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() {@Overridepublic String resolveStringValue(String strVal) {return getEnvironment().resolvePlaceholders(strVal);}});}// 3、初始化LoadTimeWeaverAware类型的bean // LoadTimeWeaverAware-->加载Spring Bean时织入第三方模块,如AspectJString[] 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下,源码如下:
@Overridepublic void preInstantiateSingletons() throws BeansException {if (this.logger.isDebugEnabled()) {this.logger.debug("Pre-instantiating singletons in " + this);}// 1、获取Bean的定义信息List beanNames = new ArrayList(this.beanDefinitionNames);// 2、触发初始化非懒加载单例beansfor (String beanName : beanNames) {// 2.1、根据beanName获取bean的RootBeanDefinitionRootBeanDefinition 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() {@Overridepublic Boolean run() {return ((SmartFactoryBean>) factory).isEagerInit();}}, getAccessControlContext());}else {isEagerInit = (factory instanceof SmartFactoryBean &&((SmartFactoryBean>) factory).isEagerInit());}if (isEagerInit) { // 2.2.1、重点在这,获取创建beangetBean(beanName);}}// 非FactoryBeanelse { 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() {@Overridepublic Object run() {smartSingleton.afterSingletonsInstantiated();return null;}}, getAccessControlContext());}else {smartSingleton.afterSingletonsInstantiated();}}}}
重点代码在 2.2.1、getBean(beanName);,根据beanName去获取单例bean信息,我们继续跟踪代码,位于类AbstractBeanFactory
@Overridepublic Object getBean(String name) throws BeansException {return doGetBean(name, null, null, false);}protected T doGetBean(final String name, @Nullable final Class 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的创建过程~
不断分享开发过程用到的技术和面试经常被问到的问题,如果您也对IT技术比较感兴趣可以「关注」我