死磕Spring系列,SpringBoot启动流程

参考文章:SpringBoot启动流程系列讲解
参考视频:SpringBoot启动流程
吐血推荐视频:史上最完整的Spring启动流程
超级好文:SpringBoot执行原理
参考文章:SpringBoot资源接口ResourceLoader和Resource学习
参考文章:到底什么是上下文(Context)
参考文章:超级好文
参考文章:这个系列的文章,让我自愧不如,痛删了原来2W字的内容

省流

1. 服务构建

  • 设置primarySources:YanggxApplication.class
  • 设置webType:SERVLET
  • 从Spring.factories获取初始化器
  • 从Spring.factories获取监听器ApplicationListener
  • 设置启动类:YanggxApplication.class

2. 环境准备

  • 发布Spring启动事件listeners.starting()
  • 封装args参数 new DefaultApplicationArguments(args);
  • 配置环境并让环境生效prepareEnvironment() & configureIgnoreBeanInfo()
  • 打印Banner图printBanner(environment)

3. 容器创建

  • 创建容器createApplicationContext()
  • 设置容器prepareContext()
  • 刷新容器refreshContext(),包括refresh()和注册钩子
  • afterRefresh()自定义接口
  • listener.started()
  • 执行Runners
  • listener.running()

4. 填充容器(就是容器创建的refreshContext().refresh())

  • prepareRefresh()刷新前操作,例如:清空缓存、初始化占位符
  • obtainFreshBeanFactory()创建BeanFactory
  • prepareBeanFactory(beanFactory)设置beanFactory.xxx属性
  • postProcessBeanFactory(beanFactory)注册与Servlet相关的特殊Bean,beanDefinition,beanFactory
  • invokeBeanFactoryPostProcessors(beanFactory)拓展接口,beanFactoryPostProcessor可以对bean的属性修改
  • registerBeanPostProcessors(beanFactory)对Bean实例的增强
  • initMessageSource()初始化信息源
  • initApplicationEventMulticaster()初始化Application事件发布器
  • onRefresh()初始化其他特殊bean
  • registerListeners()注册监听器
  • finishBeanFactoryInitialization(beanFactory)初始化剩下的Bean,例如用户自定义的Bean
  • finishRefresh()完成刷新,发布完成事件

Spring Boot启动流程

服务构建

//SpringApplication类
//只列出几个重要的字段和方法
public class SpringApplication {
    
    //SpringApplication默认web容器类
    public static final String DEFAULT_SERVLET_WEB_CONTEXT_CLASS = "org.springframework.boot."
            + "web.servlet.context.AnnotationConfigServletWebServerApplicationContext";

    //banner名称,默认为banner.txt
    public static final String BANNER_LOCATION_PROPERTY_VALUE = SpringApplicationBannerPrinter.DEFAULT_BANNER_LOCATION;

    //banner位置key,默认为spring.banner.location
    public static final String BANNER_LOCATION_PROPERTY = SpringApplicationBannerPrinter.BANNER_LOCATION_PROPERTY;

    
    //调用main函数的类,也就是YanggxApplication.class
    private Class<?> mainApplicationClass;
    
    //bean名称生成器,执行结果为null
    private BeanNameGenerator beanNameGenerator;

    //spring的环境,我们使用的是ServletWeb环境
    private ConfigurableEnvironment environment;

    //web类型,执行结果为SERVLET
    private WebApplicationType webApplicationType;

    //Application初始化器,springboot启动过程中执行其initialize方法
    private List<ApplicationContextInitializer<?>> initializers;

    //Application监听器,springboot启动过程执行其onApplicationEvent方法
    private List<ApplicationListener<?>> listeners;
    
    /**
     * SpringApplication构造函数
     * @param resourceLoader 资源加载器的策略接口,传参null,
     * @param primarySources 传参YanggxApplication.class
     */
    public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
    	//执行结果:null
        this.resourceLoader = resourceLoader;
                
        //Set去重:"primarySources":[com.yanggx.spring.YanggxApplication.class]
        Assert.notNull(primarySources, "PrimarySources must not be null");
        this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
        
        // 判断当前模块web类型:"webApplicationType":"SERVLET"
        this.webApplicationType = WebApplicationType.deduceFromClasspath();
    
        // 加载Application初始化器
        // 获取所有"META-INF/spring.factories"文件中维护的ApplicationContextInitializer子类列表
        // org.springframework.boot.context.ConfigurationWarningsApplicationContextInitializer
        // org.springframework.boot.context.ContextIdApplicationContextInitializer  
        // org.springframework.boot.context.config.DelegatingApplicationContextInitializer  
        // org.springframework.boot.web.context.ServerPortInfoApplicationContextInitializer   
        // org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListener
        setInitializers((Collection) getSpringFactoriesInstances(
                ApplicationContextInitializer.class));
    
        // 3.3 加载Application监听器
        // 获取所有"META-INF/spring.factories"文件中维护的ApplicationListener子类列表
        // org.springframework.boot.ClearCachesApplicationListener
        // org.springframework.boot.builder.ParentContextCloserApplicationListener
        // org.springframework.boot.context.FileEncodingApplicationListener
        // org.springframework.boot.context.config.AnsiOutputApplicationListener
        // org.springframework.boot.context.config.ConfigFileApplicationListener
        // org.springframework.boot.context.config.DelegatingApplicationListener
        // org.springframework.boot.context.logging.ClasspathLoggingApplicationListener
        // org.springframework.boot.context.logging.LoggingApplicationListener
        // org.springframework.boot.liquibase.LiquibaseServiceLocatorApplicationListener
        // org.springframework.boot.autoconfigure.BackgroundPreinitializer
        // 加载的这些类都是ApplicationListener的子类
        setListeners((Collection) getSpringFactoriesInstances(
                 ApplicationListener.class));
    
        // 3.4 找到启动类
        // 抛出一个RuntimeException,然后通过堆栈信息找到启动类
        //"mainApplicationClass": com.yanggx.spring.YanggxApplication.class
        this.mainApplicationClass = deduceMainApplicationClass();
    }
}

环境准备

public class SpringApplication {
    public ConfigurableApplicationContext run(String... args) {
    	//实例化一个StopWatch实例, 监控项目运行时间
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        //初始化Spring上下文
        ConfigurableApplicationContext context = null;
        //初始化错误报告参数
        Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
        //配置headless,在没有显示器,鼠标,键盘的情况下,仍然可以调用显示,输入输出的方法
        configureHeadlessProperty();
        
        //1. 发布Spring启动事件
        SpringApplicationRunListeners listeners = getRunListeners(args);
        listeners.starting();
        
        try {
        
        	/*2. 这一步的主要作用是处理启动类main函数的参数, 将其封装为一个		  
  					DefaultApplicationArguments对象, 为prepareEnvironment()提供参数*/
            ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
			
			//3.这一步的主要作用按顺序加载命令行参数, 系统参数和外部配置文件, 创建并配置Web环境
            ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);			
            configureIgnoreBeanInfo(environment);
            
            //4. 打印Banner图
            Banner printedBanner = printBanner(environment);
            
        //....
    }

容器创建

public ConfigurableApplicationContext run(String... args) {
	        
	        //步骤1: 根据switch创建context,分别有:SERVLET、REACTIVE、NONE,并且注册了Bean后置处理器
            context = createApplicationContext();            
            context.setApplicationStartup(this.applicationStartup);
            
            //步骤2: prepareContext()准备context
            prepareContext(context, environment, listeners, applicationArguments, printedBanner);
            
            //步骤3: refreshContext()刷新context,BeanDefinition和BeanFactory都是在这里创建的
            refreshContext(context);
            
            //步骤4: 刷新完成,该方法是拓展接口,用户可以自定义操作逻辑
            afterRefresh(context, applicationArguments);
            
            //步骤6: 发布Application开始事件
            listeners.started(context);

			//步骤7: 执行Runners,用于调用项目中自定义的执行器xxxRunner类,
			//在项目启动完成后立即执行,这些操作只在服务启动时执行一次
            callRunners(context, applicationArguments);
    
            //步骤8: 发布Application准备事件
            listeners.running(context);
            
    	    return context;
}

填充容器

/**
 * 抽象父类ApplicationContext
 */
public abstract class AbstractApplicationContext extends DefaultResourceLoader
        implements ConfigurableApplicationContext {
    
    @Override
    public void refresh() throws BeansException, IllegalStateException {
        synchronized (this.startupShutdownMonitor) {
            //刷新前操作,例如:清空缓存、初始化占位符
            prepareRefresh();
            
            //获取并刷新beanFactory,创建BeanFactory和BeanDefinition
            ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

            //设置beanFactory,配置各种beanFactory.xxx属性
            prepareBeanFactory(beanFactory);


            //beanFactory的后置处理器:注册与Servlet相关的特殊Bean,注册beanDefinition
            postProcessBeanFactory(beanFactory);

            /*
				BeanFactoryPostProcessor是一个接口, 处理beanFactory中所有的bean, 
				在所有的beanDefinition加载完成之后, BeanFactoryPostProcessor可以对
				beanDefinition进行属性的修改, 之后再进行bean实例化
			*/
            invokeBeanFactoryPostProcessors(beanFactory);

            //beanFactory注册后置处理器,对bean实例的增强
            registerBeanPostProcessors(beanFactory);

            //初始化messageSource
            initMessageSource();

            //初始化Application事件发布器
            initApplicationEventMulticaster();

            //初始化其他特殊的bean,例如实例化了TomcatWebServer
            onRefresh();

            //注册监听器
            registerListeners();

            //初始化剩下的Bean,例如用户自定义的bean
            finishBeanFactoryInitialization(beanFactory);

            //完成刷新,发布完成事件,实例化了所有bean
            finishRefresh();        
    }
}

非常重要的函数

getSpringFactoriesInstances()

    private <T> Collection<T> getSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes, Object... args) {
        ClassLoader classLoader = this.getClassLoader();
        Set<String> names = new LinkedHashSet(SpringFactoriesLoader.loadFactoryNames(type, classLoader));
        List<T> instances = this.createSpringFactoriesInstances(type, parameterTypes, classLoader, args, names);
        AnnotationAwareOrderComparator.sort(instances);
        return instances;
    }
	public static List<String> loadFactoryNames(Class<?> factoryType, @Nullable ClassLoader classLoader) {
		//主要获取spring.factories中的key,key对应接口全名
        String factoryTypeName = factoryType.getName();
        //筛选Map中key为factoryTypeName对应放到list返回	
        return loadSpringFactories(classLoader).getOrDefault(factoryTypeName, Collections.emptyList());
	}
	//会把Spring.factories文件中所有键值对放到Map中,其实就是缓存
	//classLoader参数就是"META-INF/spring.factories"加载器
	private static Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader) {
		//如果缓存已经有Spring.factories,那就从缓存中拿
		MultiValueMap<String, String> result = cache.get(classLoader);
		if (result != null) {
            return result;
        }

		//如果缓存中没有Spring.factories,那就从重新加载到缓存
		Enumeration<URL> urls = (classLoader != null ?
					// FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories" 
                    classLoader.getResources(FACTORIES_RESOURCE_LOCATION) :
                    ClassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION));
        result = new LinkedMultiValueMap<>();
            while (urls.hasMoreElements()) {
                URL url = urls.nextElement();
                UrlResource resource = new UrlResource(url);
                Properties properties = PropertiesLoaderUtils.loadProperties(resource);
                for (Map.Entry<?, ?> entry : properties.entrySet()) {
                    String factoryTypeName = ((String) entry.getKey()).trim();
                    for (String factoryImplementationName : StringUtils.commaDelimitedListToStringArray((String) entry.getValue())) {
                        result.add(factoryTypeName, factoryImplementationName.trim());
                    }
                }
            }
            cache.put(classLoader, result);
            return result;
	}
	private <T> List<T> createSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes,
        ClassLoader classLoader, Object[] args, Set<String> names) {
        List<T> instances = new ArrayList<>(names.size());
        for (String name : names) {
            try {
            	//通过反射机制创建实例
                Class<?> instanceClass = ClassUtils.forName(name, classLoader);
                Assert.isAssignable(type, instanceClass);
                Constructor<?> constructor = instanceClass.getDeclaredConstructor(parameterTypes);
                T instance = (T) BeanUtils.instantiateClass(constructor, args);
                instances.add(instance);
            }
            catch (Throwable ex) {
                throw new IllegalArgumentException("Cannot instantiate " + type + " : " + name, ex);
            }
        }
        return instances;
    }

总结:

  1. loadSpringFactories(@Nullable ClassLoader classLoader):判断缓存是否有Spring.factories文件,如果有就提取整个spring.factories。如果没有就加载到缓存再提取。
  2. loadFactoryNames(Class<?> factoryType, @Nullable ClassLoader classLoader):从spring.factories文件中获取指定factoryType
  3. createSpringFactoriesInstances(Class type, Class<?>[] parameterTypes,
    ClassLoader classLoader, Object[] args, Set names):将loadFactoryNames()返回的factoryType,通过反射机制实例化
  4. getSpringFactoriesInstances(Class type, Class<?>[] parameterTypes, Object… args):获取createSpringFactoriesInstances()返回的实例instances,返回实例

getClassLoader()

  1. 我们都知道java程序写好以后是以.java(文本文件)的文件存在磁盘上,然后,我们通过(bin/javac.exe)编译命令把.java文件编译成.class文件(字节码文件),并存在磁盘上。
    但是程序要运行,首先一定要把.class文件加载到JVM内存中才能使用的,我们所讲的classLoader,就是负责把磁盘上的.class文件加载到JVM内存中
  2. 你可以认为每一个Class对象拥有磁盘上的那个.class字节码内容,每一个class对象都有一个getClassLoader()方法,得到是谁把我从.class文件加载到内存中变成Class对象的

deduceMainApplicationClass()

private Class<?> deduceMainApplicationClass() {
    try {
        //通过一个RuntimeException,获取器堆栈信息
        StackTraceElement[] stackTrace = new RuntimeException().getStackTrace();
        for (StackTraceElement stackTraceElement : stackTrace) {
            if ("main".equals(stackTraceElement.getMethodName())) {
                //堆栈中包含main方法,实例化一个该类的对象
                return Class.forName(stackTraceElement.getClassName());
            }
        }
    }
    catch (ClassNotFoundException ex) { }
    return null;
}

getRunListeners(String[] args)

	//当前只能获取SpringApplicationRunListener子类列表EventPublishingRunListener
    private SpringApplicationRunListeners getRunListeners(String[] args) {
        Class<?>[] types = new Class<?>[] { SpringApplication.class, String[].class };
        
        return new SpringApplicationRunListeners(logger, getSpringFactoriesInstances(
                SpringApplicationRunListener.class, types, this, args));
    }

SpringApplicationRunListeners.starting()

//该SpringApplicationRunListeners存在多个子类,在下面starting方法中,会调用对应子类的starting方法
class SpringApplicationRunListeners {

    //发布启动事件
    public void starting() {
        for (SpringApplicationRunListener listener : this.listeners) {
            //目前调用EventPublishingRunListener的starting方法
            listener.starting();
        }
    }
    
    //其他事件都是相同的代码
}
//不仅仅是ApplicationListeners存在很多子类,EventPublishingRunListener也有很多子类
public class EventPublishingRunListener implements SpringApplicationRunListener, Ordered {

    //SpringApplication对象
    private final SpringApplication application;

    //命令函参数
    private final String[] args;

    //事件广播器
    private final SimpleApplicationEventMulticaster initialMulticaster;

    public EventPublishingRunListener(SpringApplication application, String[] args) {
        this.application = application;
        this.args = args;
        this.initialMulticaster = new SimpleApplicationEventMulticaster();
        // 通过application.getListeners(),获取到Listener列表
        // ConfigFileApplicationListener
        // AnsiOutputApplicationListener
        // LoggingApplicationListener
        // ClasspathLoggingApplicationListener
        // BackgroundPreinitializer
        // DelegatingApplicationListener
        // ParentContextCloserApplicationListener
        // ClearCachesApplicationListener
        // FileEncodingApplicationListener
        // LiquibaseServiceLocatorApplicationListener
        for (ApplicationListener<?> listener : application.getListeners()) {
            //将listener添加到事件广播器initialMulticaster
            this.initialMulticaster.addApplicationListener(listener);
        }
    }
    @Override
    public void starting() {
        // 广播器广播ApplicationStartingEvent事件
        this.initialMulticaster.multicastEvent(
                new ApplicationStartingEvent(this.application, this.args));
    }
    
    //其他事件发布都是相同的代码
    //...
}
public class SimpleApplicationEventMulticaster extends AbstractApplicationEventMulticaster {
	    public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {
        ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
        //调用父类getApplicationListeners方法
        //遍历所有支持ApplicationStartingEvent事件的监听器
        //LoggingApplicationListener
        //BackgroundPreinitializer
        //DelegatingApplicationListener
        //LiquibaseServiceLocatorApplicationListener
        for (final ApplicationListener<?> listener : getApplicationListeners(event, type)) {
            //此时的executor为null
            Executor executor = getTaskExecutor();
            if (executor != null) {
                executor.execute(() -> invokeListener(listener, event));
            }
            else {
                //调用listener
                invokeListener(listener, event);
            }
        }
    }	
}
    protected void invokeListener(ApplicationListener<?> listener, ApplicationEvent event) {
        ErrorHandler errorHandler = this.getErrorHandler();
        if (errorHandler != null) {
            try {
                this.doInvokeListener(listener, event);
            } catch (Throwable var5) {
                errorHandler.handleError(var5);
            }
        } else {
            this.doInvokeListener(listener, event);
        }

    }
    private void doInvokeListener(ApplicationListener listener, ApplicationEvent event) {
    
            //调用listener的onApplicationEvent方法
            listener.onApplicationEvent(event);
    }
onApplicationEvent(event){
	到这里就不再深究了,这个方法有三十个实现类,操作基本上就是绑定环境,设置参数等等
}

总结:

  1. SpringApplicationRunListeners.starting()调用了EventPublishingRunListener.starting();
  2. EventPublishingRunListener.starting()调用了广播器initialMulticaster.multicastEvent()发布SpringApplication启动事件
  3. initialMulticaster.multicastEvent()分别调用了LoggingApplicationListener、BackgroundPreinitializer、DelegatingApplicationListener、LiquibaseServiceLocatorApplicationListener的invokeListener()方法
    invokeListener()——doInvokeListener()——onApplicationEvent()——设置参数、绑定环境等等

prepareEnvironment(SpringApplicationRunListeners, applicationArguments)

    private ConfigurableEnvironment prepareEnvironment(
            SpringApplicationRunListeners listeners,
            ApplicationArguments applicationArguments) {
        //获取或者创建环境,根据switch判断,选择SERVLET、REACTIVE、NONE类型
        ConfigurableEnvironment environment = getOrCreateEnvironment();
        
        //配置环境:为environment配置“共享的类型转换服务”,即:A数据类型变成B数据类型 
        //然后将defaultProperties和args分别添加到environment的propertySources中
        configureEnvironment(environment, applicationArguments.getSourceArgs());
        //发布环境准备事件
        listeners.environmentPrepared(environment);
        //如果指定了main函数,那么会将当前环境绑定到指定的SpringApplication中
        bindToSpringApplication(environment);
        
        if (!this.isCustomEnvironment) {
            //环境转换:如果environment.class和模块EnvironmentClass()不一致,就转换成一样的
            environment = new EnvironmentConverter(getClassLoader())
                    .convertEnvironmentIfNecessary(environment, deduceEnvironmentClass());
        }
        //将环境依附到PropertySources
        ConfigurationPropertySources.attach(environment);
        return environment;
    }

prepareContext()

	private void prepareContext(ConfigurableApplicationContext context,
            ConfigurableEnvironment environment, SpringApplicationRunListeners listeners,
            ApplicationArguments applicationArguments, Banner printedBanner) {
            
        //设置context环境:统一ApplicationContext与Application.environment一致
        context.setEnvironment(environment);
        
        //设置ApplicationContext.beanNameGenerator、resourceLoader、classLoader、类型转换服务
        postProcessApplicationContext(context);
        
        //获取6个初始化器并执行初始化方法,例如设置元数据、配置警告、获取应用名称
        applyInitializers(context);
        
        //发布contextPrepared事件
        listeners.contextPrepared(context);
        if (this.logStartupInfo) {
            //配置了info日志
            //打印启动和profile日志
            logStartupInfo(context.getParent() == null);
            logStartupProfileInfo(context);
        }
        
        //获取到DefaultListableBeanFactory实例
        ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
        
        //注册名为springApplicationArguments,值为applicationArguments的单例bean
        beanFactory.registerSingleton("springApplicationArguments", applicationArguments);
        
        //banner不为空,那么注册名为springBootBanner,值为printedBanner的单例bean
        if (printedBanner != null) {
            beanFactory.registerSingleton("springBootBanner", printedBanner);
        }
        if (beanFactory instanceof DefaultListableBeanFactory) {
            //allowBeanDefinitionOverriding默认为false
            ((DefaultListableBeanFactory) beanFactory)
                    .setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
        }
        
        // 获取sources列表,获取到我们的YanggxApplication.class
        Set<Object> sources = getAllSources();
        Assert.notEmpty(sources, "Sources must not be empty");
        
        //初始化bean加载器,并加载bean到应用上下文
        load(context, sources.toArray(new Object[0]));
        
        //发布contextLoaded事件
        listeners.contextLoaded(context);
    }

refreshContext()

    //刷新应用上下文,注册关闭应用钩子
    private void refreshContext(ConfigurableApplicationContext context) {
        
        refresh(context);
        if (this.registerShutdownHook) 
                context.registerShutdownHook();
                
    }
/**
 * 抽象父类ApplicationContext
 */
public abstract class AbstractApplicationContext extends DefaultResourceLoader
        implements ConfigurableApplicationContext {
    
    @Override
    public void refresh() throws BeansException, IllegalStateException {
        synchronized (this.startupShutdownMonitor) {
            //清空缓存、清空监听器、判断必要属性是否被忽略、打印日志、初始化占位符、设置earlyApplicationEvents
            prepareRefresh();
            
            //获取并刷新beanFactory
            ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

            /*
				配置classLoader为当前context的classLoader
				设置BeanExpressionResolver, 解析EL表达式
				设置属性编辑器
				添加BeanPostProcessor
				配置自动装配
				手工注册environment相关bean
			*/
            prepareBeanFactory(beanFactory);


            /*
				注册basepackages
				注册annotatedClasses
				注册了request和session两个scopes
				注册几个Autowired依赖类	
			*/
            postProcessBeanFactory(beanFactory);

			/*
				BeanFactoryPostProcessor接口用于增强BeanFactory,
				Spring IoC 容器允许 BeanFactoryPostProcessor 在容器实例化任何 bean 之前读取
			 	bean 的定义,并可以修改它。

				例如:
				public static void invokeBeanFactoryPostProcessors(
            			ConfigurableListableBeanFactory beanFactory, 		
            			List<BeanFactoryPostProcessor> beanFactoryPostProcessors) 
			*/
            invokeBeanFactoryPostProcessors(beanFactory);

            //beanFactory注册后置处理器,对bean实例的增强
            registerBeanPostProcessors(beanFactory);

            //初始化messageSource
            initMessageSource();

            //初始化Application事件发布器
            initApplicationEventMulticaster();

            //初始化其他特殊的bean,例如实例化了TomcatWebServer
            onRefresh();

            //注册监听器
            registerListeners();
            
            //完成beanFactory初始化
            finishBeanFactoryInitialization(beanFactory);

            //完成刷新,发布完成事件,实例化了所有bean
            finishRefresh();
            }        
    }
}
public abstract class AbstractApplicationContext extends DefaultResourceLoader
        implements ConfigurableApplicationContext {
        
    protected void prepareRefresh() {
        //记录开始时间,调整active状态
        this.startupDate = System.currentTimeMillis();
        this.closed.set(false);
        this.active.set(true);

        //初始化占位符,例如:$,#,{}
        initPropertySources();

        //如果属性中缺少requiredProperties,那么抛出MissingRequiredPropertiesException
        getEnvironment().validateRequiredProperties();

		//清空监听器
        if (this.earlyApplicationListeners == null) {
            this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
        }
        else {
            this.applicationListeners.clear();
            this.applicationListeners.addAll(this.earlyApplicationListeners);
        }

        //初始化earlyApplicationEvents
        this.earlyApplicationEvents = new LinkedHashSet<>();
    }
}

refreshContext().refresh().obtainFreshBeanFactory()

/*
	refreshBeanFactory():创建beanFactory、指定序列化Id、定制beanFactory、加载bean定义
	getBeanFactory():返回beanFactory实例
*/
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
		//1.初始化beanFactory,并执行加载和解析配置操作
		refreshBeanFactory();
		//创建BeanFactory,返回beanFactory实例
		ConfigurableListableBeanFactory beanFactory = getBeanFactory();
		if (logger.isDebugEnabled()) {
			logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
		}
		return beanFactory;
	}
public abstract class AbstractRefreshableApplicationContext extends AbstractApplicationContext {
    ... 
    @Override
	protected final void refreshBeanFactory() throws BeansException {
		//判断是否存在beanFactory
		if (hasBeanFactory()) {
		    // 注销所有的单例
			destroyBeans();
			//重置beanFactory
			closeBeanFactory();
		}
		try {
		    //创建beanFactory
			DefaultListableBeanFactory beanFactory = createBeanFactory();
			//指定序列化id,如果需要的话,让这个BeanFactory从id反序列化到BeanFactory对象
			beanFactory.setSerializationId(getId());
			//定制BeanFactory
			customizeBeanFactory(beanFactory);
			//下载BeanDefinitions,放到BeanDefinitionsMap
			loadBeanDefinitions(beanFactory);
			synchronized (this.beanFactoryMonitor) {
				this.beanFactory = beanFactory;
			}
		}
		catch (IOException ex) {
			throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
		}
	}
	...
}

refreshContext().refresh().finishBeanFactoryInitialization(beanFactory)

/* 根据loadBeanDefinitions加载的BeanDinition到BeanDefinitionMap,
	再从BeanDefinitionMap拿出来BeanDefinitionMap创建Bean
*/
createBean(){
	//1. createBeanInstance
	通过反射机制获取Bean的构造方法,然后创建Bean。
	当然,如果构造方法需要参数,就会到单例池中查找。
	
	//2. populateBean
	填充Bean属性

	//3. 初始化
	1. 初始化容器信息,通过invokeAwareMethods(),唤醒各种Aware接口,获取Bean在容器中的信息
	2. 初始化Bean成普通对象:通过invokeInitMethods(),执行Bean的初始化方法,这个方法可以通过实现InitialzingBean接口实现的afterPropertiesSet方法。
	3. AOP操作Bean成:初始化之前和之后处理各种Bean的后置处理器,即在invokeInitMethods()之前和之后分别执行applyBeanPostProcessorsBeforeInitialization()和applyBeanPostProcessorsAfterInitialization()

	//4. 注册销毁
	实现了销毁接口DisposableBean,在registerDisposableBean方法注册指定的Bean
	在销毁时可以直接执行destroy方法销毁Bean
}

addSingleton(){
	将上面create出来的Bean放入单例池就可以获取和使用了
}

非常重要的类

ResourceLoader

//默认的资源加载器
public class DefaultResourceLoader implements ResourceLoader {
   @Nullable
    private ClassLoader classLoader;

    //自定义ProtocolResolver, 用于获取资源
    private final Set<ProtocolResolver> protocolResolvers = new LinkedHashSet<>(4);

    //
    private final Map<Class<?>, Map<Resource, ?>> resourceCaches = new ConcurrentHashMap<>(4);
    
    //实例化ClassLoader
    public DefaultResourceLoader() {
        this.classLoader = ClassUtils.getDefaultClassLoader();
    }
    
    //加载资源
    @Override
    public Resource getResource(String location) {
        Assert.notNull(location, "Location must not be null");

        //自定义资源加载方式
        for (ProtocolResolver protocolResolver : this.protocolResolvers) {
            //调用ProtocolResolver的resolve方法
            Resource resource = protocolResolver.resolve(location, this);
            if (resource != null) {
                //如果获取到资源,立即返回
                return resource;
            }
        }
        
        if (location.startsWith("/")) {
            //先判断是否是根目录
            return getResourceByPath(location);
        }
        else if (location.startsWith(CLASSPATH_URL_PREFIX)) {
            //再判断是否是classpath下的资源
            return new ClassPathResource(location.substring(CLASSPATH_URL_PREFIX.length()), getClassLoader());
        }
        else {
            try {
                //先当做一个URL处理
                URL url = new URL(location);
                //先判断是否是一个file
                //不是file的话,再从URL中获取
                return (ResourceUtils.isFileURL(url) ? new FileUrlResource(url) : new UrlResource(url));
            }
            catch (MalformedURLException ex) {
                //获取不到资源的话
                //当做resource处理
                return getResourceByPath(location);
            }
        }
    }
}

非常重要的问题

BeanFactory

BeanFactory BeanFactory定义了IOC容器的最基本形式,并提供了IOC容器应遵守的的最基本的接口,也就是Spring IOC所遵守的最底层和最基本的编程规范。在Spring代码中,BeanFactory只是个接口,并不是IOC容器的具体实现,但是Spring容器给出了很多种实现,如 DefaultListableBeanFactory、XmlBeanFactory、ApplicationContext等,都是附加了某种功能的实现

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值