皮皮网

【指标源码怎么查看】【永城网页制作源码】【什么是gpu源码】profile 注解源码_profile注解的作用

2024-12-29 02:18:33 来源:游戏纯源码下载

1.springboot启动类原理?
2.如何优雅地在 Spring Boot 中使用自定义注解,注注解AOP 切面统一打印出入参日志
3.docker的解源指标源码怎么查看架构(docker的架构体系是服务器和客户端)
4.电脑系统的分类
5.spring启动原理(spring工程启动)

profile 注解源码_profile注解的作用

springboot启动类原理?

       SpringbootBatch的启动原理-Configuration

       Springboot整合了web和batch,但是他们肯定不是同一条路,在springboot中,会推断当前的运行环境。this.webApplicationType=WebApplicationType.deduceFromClasspath();

       ä»Žä¸Šæ–‡å¯ä»¥çœ‹å‡ºï¼ŒSpring尝试从classpath里找到特征类,来判断当前app是什么类型。当然这种判断是有局限性的,有可能是transitive带进来一个带有servlet的类被当成了WebApplicationType.SERVLET,实际上是个WebApplicationType.NONE;。如果不想以web运行就是想运行batch可以在application.properties强行指定WebApplicationType

       å…·ä½“发生作用的请看下面的stacktrace

       å½“一个batchapplication需要启动,需要配置JobRepository,Datasource等等,所有的开始都来自一个annotation@EnableBatchProcessing

       å½“加入@EnableBatchProcessing时,BatchConfigurationSelector开始启动,怎么启动的大家可以参考下面的stacktrace。

       import类主要是由ConfigurationClassPostProcessor来实现的。当BatchConfigurationSelector被调用的时候,我们可以看到他有两条支路。

       é‚£ä¹ˆè¿™ä¸¤æ¡è·¯æœ‰å•¥ä¸åŒå‘¢ã€‚主要是job定义的方式不同。

       modular=true的情况下,下面是一个例子

       å¯ä»¥æœ‰å¤šä¸ªå­ApplicationContextFactory,这样好处是在除了job大家不可以重复,因为是在不同的context里,其他的step,reader,writer,processor,mapper,以及所有的bean等等都可以重名。

       é‚£ä¸ºä»€ä¹ˆJob不可以重复,是因为虽然可以重复,但是如果job也重复,对用户来讲太不友好了。用户可能不知道自己配的是哪个context的job。具体为什么可以重名要看看GenericApplicationContextFactory的实现。

       å½“GenericApplicationContextFactory::createApplicationContext,会触发ApplicationContextHelper的构造函数从而调用loadConfiguration(config)把定义的bean加入到context里。那么有个问题,parent在哪里设置,createApplicationContext是什么时候调用的。

       æˆ‘们继续看ModularConfiguration

       ä»ŽModular的角度来看首先他可以外部注入一个Configurer,如果没有就选择DefaultBatchConfigurer,如果有多个选择则会抛出。

       å½“然Datasource也可以选择外部注入,或者由DefaultBatchConfigurer::initialize方法SimpleJobLauncher,JobRepository和JobExplorer都是由FactoryBean的方式实现的。

       åœ¨è¿™ä¸ªDefaultBatchConfigurer中可以看到JobLauncher的类型是

       initialize里MapJobRepositoryFactoryBean这个可以重点读一下。首先用FactoryBean的模式实现了一个ProxyBean,如果想了解FactoryBean的用法,这是个典型的例子。但是这个FactoryBean是以api行为直接调用的,并没有注册到Spring的context中。

       é…ç½®å¥½job需要的jobRepository,jobLauncher等那么重点来了,下面的AutomaticJobRegistrar就是来处理ApplicationContextFactory

       è¿™ä¸ªé€»è¾‘是把所有的ApplicationContextFactory的beaninstance放入到AutomaticJobRegistrar里去。这就回到了第一个问题,parentcontext是什么时候放进去的。就是在

       context.getBeansOfType(ApplicationContextFactory.class)请看下面的调用栈,在ApplicationContextAwareProcessor里会自动把parentcontext注入。

       ä½†æ˜¯æ”¾è¿›åŽ»å•¥æ—¶å€™ç”¨å‘¢ï¼Ÿæˆ‘们看一下AutomaticJobRegistrar

       åŽŸæ¥AutomaticJobRegistrar是个Smartlifecycle,从Smartlifecycle的细节可以从SpringbootSmartlifecycle来得知。它就是在所有bean都初始化结束后开始进行的一个阶段。在这个start方法中,开始遍历所有的ApplicationContextFactory,来进行加载。从上文这个jobLoader是DefaultJobLoader。

       é‚£ä¹ˆå¯ä»¥çœ‹çœ‹DefaultJobLoader::doLoad方法

       è¿™é‡Œæœ‰å‡ ä¸ªå…³é”®è°ƒç”¨ç¬¬ä¸€ä¸ªæ˜¯createApplicationContext,把context里定义的全部加载到Springcontext里去,这就满足了GenericApplicationContextFactory工作的两个条件。第二个是doRegister(context,job)里jobRegistry.register(jobFactory);

       æˆ‘们看一下JobRepository的实现MapJobRegistry::register方法,在这里就把jobname和jobFactory的键值对存储起来了。

       è¿™æ ·å°±å¯ä»¥é€šè¿‡JobRepository这个bean拿到所有注册的job了。

       å’±ä»¬å†å›žæ¥çœ‹@EnableBatchProcessing这个annotation,当没有设定modular的时候是比较简单的,只是实现了一个proxybased的Job的bean。

       åŒæ ·ä¹Ÿåªæœ‰BatchConfigurer来配置。这个逻辑和Modular是一样的。从这两个配置知道,Modular注册了在子context的配置,并且加载。但是当以正常bean的方式存在的,是怎么读进来的呢。这时候就要看JobRegistryBeanPostProcessor

       è¿™ä¸ªpostProcessAfterInitialization方法里,对每个job类型的bean,jobRegistry加入了ReferenceJobFactory。这样所有的以bean的方式定义的都可以通过jobRegistry获得。

SpringBootStater原理

       ä¸€.SpringBoot的好处

       1.依赖管理:可插拔式的组件管理,当需要某个组件时,只需要引入相关stater即可,不需要再手动引入各个jar包,避免了包遗漏、包冲突等不必要的问题。开发人员可以专注于业务开发,

       2.自动配置:遵从"约定优于配置"的原则,开发人员可以在少量配置或者不配置的情况下,使用某组件。

       å¤§å¤§é™ä½Žé¡¹ç›®æ­å»ºåŠç»„件引入的成本,开发人员可以专注于业务开发,避免繁杂的配置和大量的jar包管理。

       äºŒ.实现原理

       è¦å¼•å…¥æŸç»„件,无非要做两件事。一是引入jar包即pom文件引入stater;二就是编写配置文件,使用Java配置的情况下就是编写一系列@Configuration注解标注的类。那么SpringBoot是怎么来引入这些配置类的呢?就需要我们深入SpringBoot启动类一探究竟。

       SpringBoot启动类上面会有@SpringBootApplication注解,这是SpringBoot中最重要的一个注解,是实现自动配置的关键。@SpringBootApplication是一个租合注解,主要由@SpringBootConfiguration、@EnableAutoConfiguration、@ComponentScan三部分组成。

@SpringBootConfiguration表明该类是一个配置类。

@EnableAutoConfiguration由@AutoConfigurationPackage和@Import(AutoConfigurationImportSelector.class)组成。@AutoConfigurationPackage由@Import(AutoconfigurationPackages.Registrar.class)组成,向Bean容器中注册一个AutoConfigurationPackages类,该类持有basePackage,目前我发现的作用是在MyBatis扫描注册Mapper时作为包扫描路径。

       @AutoConfigurationPackage的执行流程如下图:

@Import(AutoConfigurationImportSelector.class)是启动自动配置的核心。这里还有一个小插曲,一直在看AutoConfigurationImportSelector的selectImports方法,却发现没有被调用,以为是demo项目问题,去真实项目中debug断点,发现也没有进入,瞬间懵逼。。。继续跟踪发现执行流程如下:

       SpringBoot启动原理分析

       è‡ªåŠ¨é…ç½®æ ¸å¿ƒç±»SpringFactoriesLoader

       ä¸Šé¢åœ¨è¯´@EnableAutoConfiguration的时候有说META-INF下的spring.factories文件,那么这个文件是怎么被spring加载到的呢,其实就是SpringFactoriesLoader类。

       SpringFactoriesLoader是一个供Spring内部使用的通用工厂装载器,SpringFactoriesLoader里有两个方法,

       åœ¨è¿™ä¸ªSpringBoot应用启动过程中,SpringFactoriesLoader做了以下几件事:

       åŠ è½½æ‰€æœ‰META-INF/spring.factories中的Initializer

       åŠ è½½æ‰€æœ‰META-INF/spring.factories中的Listener

       åŠ è½½EnvironmentPostProcessor(允许在Spring应用构建之前定制环境配置)

       æŽ¥ä¸‹æ¥åŠ è½½Properties和YAML的PropertySourceLoader(针对SpringBoot的两种配置文件的加载器)

       å„种异常情况的FailureAnalyzer(异常解释器)

       åŠ è½½SpringBoot内部实现的各种AutoConfiguration

       æ¨¡æ¿å¼•æ“ŽTemplateAvailabilityProvider(如Freemarker、Thymeleaf、Jsp、Velocity等)

       æ€»å¾—来说,SpringFactoriesLoader和@EnableAutoConfiguration配合起来,整体功能就是查找spring.factories文件,加载自动配置类。

       æ•´ä½“启动流程

       åœ¨æˆ‘们执行入口类的main方法之后,运行SpringApplication.run,后面new了一个SpringApplication对象,然后执行它的run方法。

       åˆå§‹åŒ–SpringApplicationç±»

       åˆ›å»ºä¸€ä¸ªSpringApplication对象时,会调用它自己的initialize方法

       æ‰§è¡Œæ ¸å¿ƒrun方法

       åˆå§‹åŒ–initialize方法执行完之后,会调用run方法,开始启动SpringBoot。

       é¦–先遍历执行所有通过SpringFactoriesLoader,在当前classpath下的META-INF/spring.factories中查找所有可用的SpringApplicationRunListeners并实例化。调用它们的starting()方法,通知这些监听器SpringBoot应用启动。

       åˆ›å»ºå¹¶é…ç½®å½“前SpringBoot应用将要使用的Environment,包括当前有效的PropertySource以及Profile。

       éåŽ†è°ƒç”¨æ‰€æœ‰çš„SpringApplicationRunListeners的environmentPrepared()的方法,通知这些监听器SpringBoot应用的Environment已经完成初始化。

       æ‰“印SpringBoot应用的banner,SpringApplication的showBanner属性为true时,如果classpath下存在banner.txt文件,则打印其内容,否则打印默认banner。

       æ ¹æ®å¯åŠ¨æ—¶è®¾ç½®çš„applicationContextClass和在initialize方法设置的webEnvironment,创建对应的applicationContext。

       åˆ›å»ºå¼‚常解析器,用在启动中发生异常的时候进行异常处理(包括记录日志、释放资源等)。

       è®¾ç½®SpringBoot的Environment,注册SpringBean名称的序列化器BeanNameGenerator,并设置资源加载器ResourceLoader,通过SpringFactoriesLoader加载ApplicationContextInitializer初始化器,调用initialize方法,对创建的ApplicationContext进一步初始化。

       è°ƒç”¨æ‰€æœ‰çš„SpringApplicationRunListeners的contextPrepared方法,通知这些Listener当前ApplicationContext已经创建完毕。

       æœ€æ ¸å¿ƒçš„一步,将之前通过@EnableAutoConfiguration获取的所有配置以及其他形式的IoC容器配置加载到已经准备完毕的ApplicationContext。

       è°ƒç”¨æ‰€æœ‰çš„SpringApplicationRunListener的contextLoaded方法,加载准备完毕的ApplicationContext。

       è°ƒç”¨refreshContext,注册一个关闭Spring容器的钩子ShutdownHook,当程序在停止的时候释放资源(包括:销毁Bean,关闭SpringBean的创建工厂等)

       æ³¨ï¼šé’©å­å¯ä»¥åœ¨ä»¥ä¸‹å‡ ç§åœºæ™¯ä¸­è¢«è°ƒç”¨ï¼š

       1)程序正常退出

       2)使用System.exit()

       3)终端使用Ctrl+C触发的中断

       4)系统关闭

       5)使用Killpid命令杀死进程

       èŽ·å–当前所有ApplicationRunner和CommandLineRunner接口的实现类,执行其run方法

       éåŽ†æ‰€æœ‰çš„SpringApplicationRunListener的finished()方法,完成SpringBoot的启动。

SpringBoot应用启动原理(二)扩展URLClassLoader实现嵌套jar加载

       åœ¨ä¸Šç¯‡æ–‡ç« ã€ŠSpringBoot应用启动原理(一)将启动脚本嵌入jar》中介绍了SpringBoot如何将启动脚本与RunnableJar整合为ExecutableJar的原理,使得生成的jar/war文件可以直接启动

       æœ¬ç¯‡å°†ä»‹ç»SpringBoot如何扩展URLClassLoader实现嵌套jar的类(资源)加载,以启动我们的应用。

       é¦–先,从一个简单的示例开始

       build.gradle

       WebApp.java

       æ‰§è¡Œgradlebuild构建jar包,里面包含应用程序、第三方依赖以及SpringBoot启动程序,其目录结构如下

       æŸ¥çœ‹MANIFEST.MF的内容(MANIFEST.MF文件的作用请自行GOOGLE)

       å¯ä»¥çœ‹åˆ°ï¼Œjar的启动类为org.springframework.boot.loader.JarLauncher,而并不是我们的com.manerfan.SpringBoot.theory.WebApp,应用程序入口类被标记为了Start-Class

       jar启动并不是通过应用程序入口类,而是通过JarLauncher代理启动。其实SpringBoot拥有3中不同的Launcher:JarLauncher、WarLauncher、PropertiesLauncher

       SpringBoot使用Launcher代理启动,其最重要的一点便是可以自定义ClassLoader,以实现对jar文件内(jarinjar)或其他路径下jar、class或资源文件的加载

       å…³äºŽClassLoader的更多介绍可参考《深入理解JVM之ClassLoader》

       SpringBoot抽象了Archive的概念,一个Archive可以是jar(JarFileArchive),可以是一个文件目录(ExplodedArchive),可以抽象为统一访问资源的逻辑层。

       ä¸Šä¾‹ä¸­ï¼Œspring-boot-theory-1.0.0.jar既为一个JarFileArchive,spring-boot-theory-1.0.0.jar!/BOOT-INF/lib下的每一个jar包也是一个JarFileArchive

       å°†spring-boot-theory-1.0.0.jar解压到目录spring-boot-theory-1.0.0,则目录spring-boot-theory-1.0.0为一个ExplodedArchive

       æŒ‰ç…§å®šä¹‰ï¼ŒJarLauncher可以加载内部/BOOT-INF/lib下的jar及/BOOT-INF/classes下的应用class

       å…¶å®žJarLauncher实现很简单

       å…¶ä¸»å…¥å£æ–°å»ºäº†JarLauncher并调用父类Launcher中的launch方法启动程序

       å†åˆ›å»ºJarLauncher时,父类ExecutableArchiveLauncher找到自己所在的jar,并创建archive

       åœ¨Launcher的launch方法中,通过以上archive的getNestedArchives方法找到/BOOT-INF/lib下所有jar及/BOOT-INF/classes目录所对应的archive,通过这些archives的url生成LaunchedURLClassLoader,并将其设置为线程上下文类加载器,启动应用

       è‡³æ­¤ï¼Œæ‰æ‰§è¡Œæˆ‘们应用程序主入口类的main方法,所有应用程序类文件均可通过/BOOT-INF/classes加载,所有依赖的第三方jar均可通过/BOOT-INF/lib加载

       åœ¨åˆ†æžLaunchedURLClassLoader前,首先了解一下URLStreamHandler

       java中定义了URL的概念,并实现多种URL协议(见URL)*.manerfan.SpringBoot.theory.WebApp,应用程序入口类被标记为了Start-Class

       jar启动并不是通过应用程序入口类,而是通过JarLauncher代理启动。其实SpringBoot拥有3中不同的Launcher:JarLauncher、WarLauncher、PropertiesLauncher

       SpringBoot使用Launcher代理启动,其最重要的一点便是可以自定义ClassLoader,以实现对jar文件内(jarinjar)或其他路径下jar、class或资源文件的加载

       å…³äºŽClassLoader的更多介绍可参考《深入理解JVM之ClassLoader》

       SpringBoot抽象了Archive的概念,一个Archive可以是jar(JarFileArchive),可以是一个文件目录(ExplodedArchive),可以抽象为统一访问资源的逻辑层。

       ä¸Šä¾‹ä¸­ï¼Œspring-boot-theory-1.0.0.jar既为一个JarFileArchive,spring-boot-theory-1.0.0.jar!/BOOT-INF/lib下的每一个jar包也是一个JarFileArchive

       å°†spring-boot-theory-1.0.0.jar解压到目录spring-boot-theory-1.0.0,则目录spring-boot-theory-1.0.0为一个ExplodedArchive

       æŒ‰ç…§å®šä¹‰ï¼ŒJarLauncher可以加载内部/BOOT-INF/lib下的jar及/BOOT-INF/classes下的应用class

       å…¶å®žJarLauncher实现很简单

       å…¶ä¸»å…¥å£æ–°å»ºäº†JarLauncher并调用父类Launcher中的launch方法启动程序

       å†åˆ›å»ºJarLauncher时,父类ExecutableArchiveLauncher找到自己所在的jar,并创建archive

       åœ¨Launcher的launch方法中,通过以上archive的getNestedArchives方法找到/BOOT-INF/lib下所有jar及/BOOT-INF/classes目录所对应的archive,通过这些archives的url生成LaunchedURLClassLoader,并将其设置为线程好橡上下文类加载器,启动应用

       è‡³æ­¤ï¼Œæ‰æ‰§è¡Œæˆ‘们应用程序主入口类的main方法,所有应用程序类文件均可通过/BOOT-INF/classes加载,所有依赖的第三方jar均可通过/BOOT-INF/lib加载

       åœ¨åˆ†æžLaunchedURLClassLoader前,首先了解一下URLStreamHandler

       java中定义了URL的概念,并实现多种URL协议(见URL)*http**file**ftp**jar*等,结合对应的URLConnection可以灵活地获取各种协议下的资源

       å¯¹äºŽjar,每个jar都会对应一个url,如

       jar:file:/data/spring-boot-theory/BOOT-INF/lib/spring-aop-5.0.4.RELEASE.jar!/

       jar中的资源,也会对应一个url,并以'!/'分割,如

       jar:file:/data/spring-boot-theory/BOOT-INF/lib/spring-aop-5.0.4.RELEASE.jar!/org/springframework/aop/SpringProxy.class

       å¯¹äºŽåŽŸå§‹çš„JarFileURL,只支持一个'!/',SpringBoot扩展了此协议,使其支持多个'!/',以实现jarinjar的资源,如

       jar:file:/data/spring-boot-theory.jar!/BOOT-INF/lib/spring-aop-5.0.4.RELEASE.jar!/org/springframework/aop/SpringProxy.class

       è‡ªå®šä¹‰URL的类格式为[pkgs].[protocol].Handler,在运行Launcher的launch方法时调用了JarFile.registerUrlProtocolHandler()以注册自定义的Handler

       åœ¨å¤„理如下URL时,会循环处理'!/'分隔符,从最上层出发,先构造spring-boot-theory.jar的JarFile,再构造spring-aop-5.0.4.RELEASE.jar的JarFile,最后构造指向SpringProxy.class的

       JarURLConnection,通过JarURLConnection的getInputStream方法获取SpringProxy.class内容

       ä»Žä¸€ä¸ªURL,到读取其中的内容,整个过程为

       URLClassLoader可以通过原始的jar协议,加载jar中从class文件

       LaunchedURLClassLoader通过扩展的jar协议,以实现jarinjar这种情况下的class文件加载

       æž„建war包很简单

       æž„建出的war包,其目录机构为

       MANIFEST.MF内容为

       æ­¤æ—¶ï¼Œå¯åŠ¨ç±»å˜ä¸ºäº†org.springframework.boot.loader.WarLauncher,查看WarLauncher实现,其实与JarLauncher并无太大差别

       å·®åˆ«ä»…在于,JarLauncher在构建LauncherURLClassLoader时,会搜索BOOT-INF/classes目录及BOOT-INF/lib目录下jar,WarLauncher在构建LauncherURLClassLoader时,则会搜索WEB-INFO/classes目录及WEB-INFO/lib和WEB-INFO/lib-provided两个目录下的jar

       å¦‚此依赖,构建出的war便支持两种启动方式

       PropretiesLauncher的实现与JarLauncherWarLauncher的实现极为相似,通过PropretiesLauncher可以实现更为轻量的thinjar,其实现方式可自行查阅源码

SpringBoot运行原理

       SpringBoot是一个基于Spring开发,集成了大量第三方库配置的javaweb开发框架

       pom.xml

       çˆ¶ä¾èµ–

       å…¶ä¸­å®ƒä¸»è¦æ˜¯ä¾èµ–一个父项目,主要是管理项目的资源过滤及插件。以后我们导入依赖默认是不需要写版本的。

       å¯åŠ¨å™¨spring-boot-starter

       springboot-boot-starter-xxx:spring-boot的场景启动器郑御

       spring-boot-starter-web:帮我们导入了web模块正常运行所依赖的组件。

       springBoot将所有的功能场景都抽取出来,做成一个个的starter(启动器),只需要在项目中引入这些starter即可,所有相关的依赖都会被引进来,我们要用什么功能就导入什么样的场景启动器即可。

       @SpringBootApplication

       ä½œç”¨ï¼šæ ‡æ³¨åœ¨æŸä¸ªç±»ä¸Šè¯´æ˜Žè¿™ä¸ªç±»æ˜¯SpringBoot的主配置类,SpringBoot运行这个类的main方法来启动SpringBoot应用。

       è¿›å…¥è¿™ä¸ªæ³¨è§£ï¼Œé‡Œé¢åŒ…含了很多其他注解

       @ComponentScan作用:自动扫描并加载符合条件的组件或者bean,将这个bean定义加载到IOC容器中。

       @SpringBootConfiguration作用:SpringBoot的配置类,标注在某个类上,表示这是一个姿咐SpringBoot的配置类。

       è¿›å…¥@SpringBootConfiguration注解查看,这里的@Configuration说明这是一个配置类,配置类对应Spring的xml配置文件。

       ç»§ç»­æŸ¥çœ‹@SpringBootConfiguration包含的其他注解

       @EnableAutoConfiguration:开启自动配置功能

       è¿›å…¥@EnableAutoConfiguration注解查看

       @AutoConfigurationPackage自动配置包

       @import:Spring底层注解@import,给容器中导入一个组件

       @Import({ AutoConfigurationImportSelector.class})给容器导入组件

       AutoConfigurationImportSelector:自动配置导入选择器。那么它导入哪些组件的选择器呢

       è¿™ä¸ªç±»ä¸­æœ‰è¿™æ ·ä¸€ä¸ªæ–¹æ³•ï¼šgetCandidateConfiguration,而在这个方法中有调用了SpringFactoriesLoader类的静态方法loadFactoryNames()方法

       è¿›å…¥loadSpringFactories方法

       æ ¹æ®å…¨å±€æœç´¢Spring.factories,打开后是自动配置的文件。

       éšä¾¿æ‰“开一个其中的自动配置类看,它们都喊册岩是javaConfig配置类,都注入了一些Bean

       æ‰€ä»¥ï¼Œè‡ªåŠ¨é…ç½®çœŸæ­£å®žçŽ°æ˜¯ä»Žclasspath中搜寻所有的META-INF/spring.factories配置文件,并将其中对应的org.springframework.boot.autoconfigure包下的配置项通过反射实例化为对应标注了@Configuration的javaConfig形式的IOC容器配置类,然后将这些都汇总成为一个实例并加载到IOC容器中。

       ç»“论:

       1.SpringBoot在启动的时候从类路径下的META-INF/spring.factories中获取EnableAutoConfiguration指定的值

       2.将这些值作为自动配置类导入容器,自动配置类就生效,帮我们进行自动配置工作。

       3.整个J2EE的整体解决方案和自动配置都在springboot-autoConfigure的jar包中。

       4.它会给容器中导入非常多的自动配置类(xxxAutoConfiguration),就是给容器中导入这个场景需要的所有组件,并配置好这些组件。

       5.有了自动配置类,免去了我们手动编写配置注入功能组件等的工作。

       SpringApplication

       è¿™ä¸ªç±»ä¸»è¦åšäº†ä»¥ä¸‹å››ä»¶äº‹

       1.推断应用的类型是普通的项目还是web项目

       2.查找并加载所有可用初始化器,设置到initializers属性中

       3.找出所有的应用程序监听器,设置到listeners属性中

       4.推断并设置main方法的定义类,找到运行的主类

SpringbootBatch的启动原理-Configuration

       Springboot整合了web和batch,但是他们肯定不是同一条路,在springboot中,会推断当前的运行环境。this.webApplicationType=WebApplicationType.deduceFromClasspath();

       ä»Žä¸Šç¨¿æ¨±æ–‡å¯ä»¥çœ‹å‡ºï¼ŒSpring尝试从classpath里找到特征类,来判断当前app是什么类型。当然这种判断是有局限性的,有可能是transitive带搭渗进来一个带有servlet的类被当成了WebApplicationType.SERVLET,实际上是个WebApplicationType.NONE;。如果不想以web运行就是想运行batch可以在application.properties强行指定WebApplicationType

       å…·ä½“发生作用的请看下面的stacktrace

       å½“一个batchapplication需要启动,需要配置JobRepository,Datasource等等,所有的开始都来自一个annotation@EnableBatchProcessing

       å½“加入@EnableBatchProcessing时,BatchConfigurationSelector开始启动,怎么启动的大家可以键枝丛参考下面的stacktrace。

       import类主要是由ConfigurationClassPostProcessor来实现的。当BatchConfigurationSelector被调用的时候,我们可以看到他有两条支路。

       é‚£ä¹ˆè¿™ä¸¤æ¡è·¯æœ‰å•¥ä¸åŒå‘¢ã€‚主要是job定义的方式不同。

       modular=true的情况下,下面是一个例子

       å¯ä»¥æœ‰å¤šä¸ªå­Ap