栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

SpringBoot源码解读,启动流程(一)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

SpringBoot源码解读,启动流程(一)

1、org.springframework.boot下的构造方法public SpringApplication(ResourceLoader resourceLoader, Class... primarySources)启动,开始加载SpirngBootFactories文件,加载SpringBoot自动配置类。
-------------------------------------------------------------------------------------------
public SpringApplication(ResourceLoader resourceLoader, Class... primarySources) {
    this.sources = new linkedHashSet();
    this.bannerMode = Mode.CONSOLE;
    this.logStartupInfo = true;
    this.addCommandLineProperties = true;
    this.addConversionService = true;
    this.headless = true;
    this.registerShutdownHook = true;
    this.additionalProfiles = new HashSet();
    this.isCustomEnvironment = false;
    this.lazyInitialization = false;
    this.resourceLoader = resourceLoader;
    Assert.notNull(primarySources, "PrimarySources must not be null");
    this.primarySources = new linkedHashSet(Arrays.asList(primarySources));
    this.webApplicationType = WebApplicationType.deduceFromClasspath();
    this.setInitializers(this.getSpringFactoriesInstances(ApplicationContextInitializer.class));
    this.setListeners(this.getSpringFactoriesInstances(ApplicationListener.class));
    this.mainApplicationClass = this.deduceMainApplicationClass();
}
-------------------------------------------------------------------------------------------
2、通过SpringFactoriesLoader获取spring.factories文件的set集合。
-------------------------------------------------------------------------------------------
public static List loadFactoryNames(Class factoryType, @Nullable ClassLoader classLoader) {
    String factoryTypeName = factoryType.getName();
    return (List)loadSpringFactories(classLoader).getOrDefault(factoryTypeName, Collections.emptyList());
}
-------------------------------------------------------------------------------------------
3、通过SpringFactoriesLoader下的loadFactories方法:获取所有meta_INFO文件下的所有配置类的List集合,通过instantiateFactory(String factoryImplementationName, Class factoryType, ClassLoader classLoader)方法获取所有配置类的Class对象,并通过反射自动创建接口实现类的对象 ,public static  Constructor accessibleConstructor(Class clazz, Class... parameterTypes),在loadFactories方法中最终返回所有的spring.factories文件的所有对象。
-------------------------------------------------------------------------------------------------------------------------------
private static  T instantiateFactory(String factoryImplementationName, Class factoryType, ClassLoader classLoader) {
    try {
        Class factoryImplementationClass = ClassUtils.forName(factoryImplementationName, classLoader);
        if (!factoryType.isAssignableFrom(factoryImplementationClass)) {
            throw new IllegalArgumentException("Class [" + factoryImplementationName + "] is not assignable to factory type [" + factoryType.getName() + "]");
        } else {
            return ReflectionUtils.accessibleConstructor(factoryImplementationClass, new Class[0]).newInstance();
        }
    } catch (Throwable var4) {
        throw new IllegalArgumentException("Unable to instantiate factory class [" + factoryImplementationName + "] for factory type [" + factoryType.getName() + "]", var4);
    }
}
--------------------------------------------------------------------------------------------------------------------------------

4、初始化应用容器后再初始化应用监听private  Collection getSpringFactoriesInstances(Class type),把监听对象添加仅ApplicationListener容器中,初步初始化容器对象完成;
5、使用初始化容器ApplicationContext启动配置对象容器public ConfigurableApplicationContext run(String... args);开始装配@Comciguration和@Component组件对象,容器对象名称:org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@54da5fdc, started on Thu Mar 24 16:12:56 CST 2022, parent: org.springframework.context.annotation.AnnotationConfigApplicationContext@1195d52f 容器存储了根据注解进行自动配置的对象。

6、更新ConfigurationContext容器,初始化过程中使用锁机制。
--------------------------------------------------------------------------------------------------------------------------------
public void refresh() throws BeansException, IllegalStateException {
    synchronized(this.startupShutdownMonitor) {
        this.prepareRefresh();
        ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
        this.prepareBeanFactory(beanFactory);
        try {
            this.postProcessBeanFactory(beanFactory);
            this.invokeBeanFactoryPostProcessors(beanFactory);
            this.registerBeanPostProcessors(beanFactory);
            this.initMessageSource();
            this.initApplicationEventMulticaster();
            this.onRefresh();
            this.registerListeners();
            this.finishBeanFactoryInitialization(beanFactory);
            this.finishRefresh();
        } catch (BeansException var9) {
            if (this.logger.isWarnEnabled()) {
                this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
            }
            this.destroyBeans();
            this.cancelRefresh(var9);
            throw var9;
        } finally {
            this.resetCommonCaches();
        }
    }
}
--------------------------------------------------------------------------------------------------------------------------------
7、获取候选自动加载Bean对象进行加载。获取包扫描@ComponentScan()的结果,获取basePackage,Exclude,Fileter等结果,扫描basePackeage路径下的类,遍历basePackage路径下所有对象,如果该对象所在的下标对应的对象不在@ExcludeFilter注解之内,则把该对象加入候选人(Candidate容器内),否则给出该对象无法加入候选人容器的轨迹。

8、扫描对象加入候选人集合后,判断其候选的方式实现还是加了注解,为候选人添加操作,如果为注解候选人(@Confituration,@Component),判断所添加的注解类型赋予特性:懒加载(@Lazy)0、是否优先选择(@Primary),是否是依赖组件(@DpendsOn)(先行条件)以及角色(@Role)、描述(@Description)等
--------------------------------------------------------------------------------------------------------------------------------
while(var8.hasNext()) {
    BeanDefinition candidate = (BeanDefinition)var8.next();
    Scopemetadata scopemetadata = this.scopemetadataResolver.resolveScopemetadata(candidate);
    candidate.setScope(scopemetadata.getScopeName());
    String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);
    if (candidate instanceof AbstractBeanDefinition) {
        this.postProcessBeanDefinition((AbstractBeanDefinition)candidate, beanName);
    }
    if (candidate instanceof AnnotatedBeanDefinition) {
        AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition)candidate);
    }
    if (this.checkCandidate(beanName, candidate)) {
        BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
        definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopemetadata, definitionHolder, this.registry);
        beanDefinitions.add(definitionHolder);
        this.registerBeanDefinition(definitionHolder, this.registry);
    }
}
--------------------------------------------------------------------------------------------------------------------------------
9、根据AutoConfigurationimportFilter.class筛选出是否符合自动注入规则的对象并进行加载,loadFacotries作用看来是根据工厂类型去构建对象。
--------------------------------------------------------------------------------------------------------------------------------
protected List getAutoConfigurationimportFilters() {
    return SpringFactoriesLoader.loadFactories(AutoConfigurationimportFilter.class, this.beanClassLoader);
}
--------------------------------------------------------------------------------------------------------------------------------

10、加载TemplateAvailabilityProvider模板提供程序,也是通过loadFactories(AutoConfigurationimportFilter.class, this.beanClassLoader)方法进行加载。
--------------------------------------------------------------------------------------------------------------------------------
protected List getAutoConfigurationimportFilters() {
    return SpringFactoriesLoader.loadFactories(AutoConfigurationimportFilter.class, this.beanClassLoader);
}
--------------------------------------------------------------------------------------------------------------------------------

总结:以上只是粗略大致的对SpringBoot类启动流程进行梳理,也加深了自己对SpringBoot启动的理解,及源码的一些设计高深之处。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/777296.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号