java框架之SpringBoot(10)-启动流程及自定义starter
启动流程
直接从 SpringBoot 程序入口的 run 方法看起:
public static ConfigurableApplicationContext run(Object source, String... args) { return run(new Object[] { source }, args); }
org.springframework.boot.SpringApplication#run(java.lang.Object, java.lang.String...)
执行第 2 行的 run(new Object[] { source }, args) 方法:
public static ConfigurableApplicationContext run(Object[] sources, String[] args) { return new SpringApplication(sources).run(args); }
org.springframework.boot.SpringApplication#run(java.lang.Object[], java.lang.String[])
可以看到,这里启动实际上是分为两步,先是创建 SpringApplication 对象,然后执行该对象的 run 方法。下面根据这两步进行深入:
创建SpringApplication对象
下一步会进入 SpringApplication 类的构造方法:
public SpringApplication(Object... sources) { initialize(sources); }
org.springframework.boot.SpringApplication#SpringApplication(java.lang.Object...)
接着进入 initialize 方法:
private void initialize(Object[] sources) { if (sources != null && sources.length > 0) { // 保存配置类,包含入口类 this.sources.addAll(Arrays.asList(sources)); } // 判断当前是否是一个 web 应用 this.webEnvironment = deduceWebEnvironment(); // 从类路径下找到 META-INF/spring.factories 配置的所有 ApplicationContextInitializer 类并反射创建实例并保存到当前 SpringApplication 实例的 initializers 属性 setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class)); // 从类路径下找到 META-INF/spring.factories 配置的所有 ApplicationListener 类并反射创建实例保存到当前 SpringApplication 实例的 listeners 属性 setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class)); // 从调用栈中获取到执行了 main 方法的配置类即入口类保存到当前 SpringApplication 实例的 mainApplicationClass 属性 this.mainApplicationClass = deduceMainApplicationClass(); }
org.springframework.boot.SpringApplication#initialize
在创建 SpringApplication 对象的过程中实例化了类路径下 META-INF/spring.factories 中 ApplicationContextInitializer 节对应的应用上下文初始化器类和 ApplicationListener 节对应的应用监听器类并保存到了 SpringApplication 对象中。
可以看到在很多包中都有这个文件,下面为自动配置包中的 spring.factories 文件:
# Initializers org.springframework.context.ApplicationContextInitializer=\ org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer,\ org.springframework.boot.autoconfigure.logging.AutoConfigurationReportLoggingInitializer # Application Listeners org.springframework.context.ApplicationListener=\ org.springframework.boot.autoconfigure.BackgroundPreinitializer # Auto Configuration Import Listeners org.springframework.boot.autoconfigure.AutoConfigurationImportListener=\ org.springframework.boot.autoconfigure.condition.ConditionEvaluationReportAutoConfigurationImportListener # Auto Configuration Import Filters org.springframework.boot.autoconfigure.AutoConfigurationImportFilter=\ org.springframework.boot.autoconfigure.condition.OnClassCondition # Auto Configure org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\ org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\ org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\ org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration,\ org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration,\ org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration,\ org.springframework.boot.autoconfigure.cloud.CloudAutoConfiguration,\ org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration,\ org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration,\ org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration,\ org.springframework.boot.autoconfigure.couchbase.CouchbaseAutoConfiguration,\ org.springframework.boot.autoconfigure.dao.PersistenceExceptionTranslationAutoConfiguration,\ org.springframework.boot.autoconfigure.data.cassandra.CassandraDataAutoConfiguration,\ org.springframework.boot.autoconfigure.data.cassandra.CassandraRepositoriesAutoConfiguration,\ org.springframework.boot.autoconfigure.data.couchbase.CouchbaseDataAutoConfiguration,\ org.springframework.boot.autoconfigure.data.couchbase.CouchbaseRepositoriesAutoConfiguration,\ org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchAutoConfiguration,\ org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchDataAutoConfiguration,\ org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchRepositoriesAutoConfiguration,\ org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration,\ org.springframework.boot.autoconfigure.data.ldap.LdapDataAutoConfiguration,\ org.springframework.boot.autoconfigure.data.ldap.LdapRepositoriesAutoConfiguration,\ org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration,\ org.springframework.boot.autoconfigure.data.mongo.MongoRepositoriesAutoConfiguration,\ org.springframework.boot.autoconfigure.data.neo4j.Neo4jDataAutoConfiguration,\ org.springframework.boot.autoconfigure.data.neo4j.Neo4jRepositoriesAutoConfiguration,\ org.springframework.boot.autoconfigure.data.solr.SolrRepositoriesAutoConfiguration,\ org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration,\ org.springframework.boot.autoconfigure.data.redis.RedisRepositoriesAutoConfiguration,\ org.springframework.boot.autoconfigure.data.rest.RepositoryRestMvcAutoConfiguration,\ org.springframework.boot.autoconfigure.data.web.SpringDataWebAutoConfiguration,\ org.springframework.boot.autoconfigure.elasticsearch.jest.JestAutoConfiguration,\ org.springframework.boot.autoconfigure.freemarker.FreeMarkerAutoConfiguration,\ org.springframework.boot.autoconfigure.gson.GsonAutoConfiguration,\ org.springframework.boot.autoconfigure.h2.H2ConsoleAutoConfiguration,\ org.springframework.boot.autoconfigure.hateoas.HypermediaAutoConfiguration,\ org.springframework.boot.autoconfigure.hazelcast.HazelcastAutoConfiguration,\ org.springframework.boot.autoconfigure.hazelcast.HazelcastJpaDependencyAutoConfiguration,\ org.springframework.boot.autoconfigure.info.ProjectInfoAutoConfiguration,\ org.springframework.boot.autoconfigure.integration.IntegrationAutoConfiguration,\ org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration,\ org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\ org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration,\ org.springframework.boot.autoconfigure.jdbc.JndiDataSourceAutoConfiguration,\ org.springframework.boot.autoconfigure.jdbc.XADataSourceAutoConfiguration,\ org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration,\ org.springframework.boot.autoconfigure.jms.JmsAutoConfiguration,\ org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration,\ org.springframework.boot.autoconfigure.jms.JndiConnectionFactoryAutoConfiguration,\ org.springframework.boot.autoconfigure.jms.activemq.ActiveMQAutoConfiguration,\ org.springframework.boot.autoconfigure.jms.artemis.ArtemisAutoConfiguration,\ org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration,\ org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAutoConfiguration,\ org.springframework.boot.autoconfigure.jersey.JerseyAutoConfiguration,\ org.springframework.boot.autoconfigure.jooq.JooqAutoConfiguration,\ org.springframework.boot.autoconfigure.kafka.KafkaAutoConfiguration,\ org.springframework.boot.autoconfigure.ldap.embedded.EmbeddedLdapAutoConfiguration,\ org.springframework.boot.autoconfigure.ldap.LdapAutoConfiguration,\ org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration,\ org.springframework.boot.autoconfigure.mail.MailSenderAutoConfiguration,\ org.springframework.boot.autoconfigure.mail.MailSenderValidatorAutoConfiguration,\ org.springframework.boot.autoconfigure.mobile.DeviceResolverAutoConfiguration,\ org.springframework.boot.autoconfigure.mobile.DeviceDelegatingViewResolverAutoConfiguration,\ org.springframework.boot.autoconfigure.mobile.SitePreferenceAutoConfiguration,\ org.springframework.boot.autoconfigure.mongo.embedded.EmbeddedMongoAutoConfiguration,\ org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration,\ org.springframework.boot.autoconfigure.mustache.MustacheAutoConfiguration,\ org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration,\ org.springframework.boot.autoconfigure.reactor.ReactorAutoConfiguration,\ org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration,\ org.springframework.boot.autoconfigure.security.SecurityFilterAutoConfiguration,\ org.springframework.boot.autoconfigure.security.FallbackWebSecurityAutoConfiguration,\ org.springframework.boot.autoconfigure.security.oauth2.OAuth2AutoConfiguration,\ org.springframework.boot.autoconfigure.sendgrid.SendGridAutoConfiguration,\ org.springframework.boot.autoconfigure.session.SessionAutoConfiguration,\ org.springframework.boot.autoconfigure.social.SocialWebAutoConfiguration,\ org.springframework.boot.autoconfigure.social.FacebookAutoConfiguration,\ org.springframework.boot.autoconfigure.social.LinkedInAutoConfiguration,\ org.springframework.boot.autoconfigure.social.TwitterAutoConfiguration,\ org.springframework.boot.autoconfigure.solr.SolrAutoConfiguration,\ org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration,\ org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration,\ org.springframework.boot.autoconfigure.transaction.jta.JtaAutoConfiguration,\ org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration,\ org.springframework.boot.autoconfigure.web.DispatcherServletAutoConfiguration,\ org.springframework.boot.autoconfigure.web.EmbeddedServletContainerAutoConfiguration,\ org.springframework.boot.autoconfigure.web.ErrorMvcAutoConfiguration,\ org.springframework.boot.autoconfigure.web.HttpEncodingAutoConfiguration,\ org.springframework.boot.autoconfigure.web.HttpMessageConvertersAutoConfiguration,\ org.springframework.boot.autoconfigure.web.MultipartAutoConfiguration,\ org.springframework.boot.autoconfigure.web.ServerPropertiesAutoConfiguration,\ org.springframework.boot.autoconfigure.web.WebClientAutoConfiguration,\ org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration,\ org.springframework.boot.autoconfigure.websocket.WebSocketAutoConfiguration,\ org.springframework.boot.autoconfigure.websocket.WebSocketMessagingAutoConfiguration,\ org.springframework.boot.autoconfigure.webservices.WebServicesAutoConfiguration # Failure analyzers org.springframework.boot.diagnostics.FailureAnalyzer=\ org.springframework.boot.autoconfigure.diagnostics.analyzer.NoSuchBeanDefinitionFailureAnalyzer,\ org.springframework.boot.autoconfigure.jdbc.DataSourceBeanCreationFailureAnalyzer,\ org.springframework.boot.autoconfigure.jdbc.HikariDriverConfigurationFailureAnalyzer # Template availability providers org.springframework.boot.autoconfigure.template.TemplateAvailabilityProvider=\ org.springframework.boot.autoconfigure.freemarker.FreeMarkerTemplateAvailabilityProvider,\ org.springframework.boot.autoconfigure.mustache.MustacheTemplateAvailabilityProvider,\ org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAvailabilityProvider,\ org.springframework.boot.autoconfigure.thymeleaf.ThymeleafTemplateAvailabilityProvider,\ org.springframework.boot.autoconfigure.web.JspTemplateAvailabilityProvider
spring-boot-autoconfigure-1.5.19.RELEASE.jar!/META-INF/spring.factories
执行SpringApplication.run()
执行 org.springframework.boot.SpringApplication#run(java.lang.String...) 方法:
public ConfigurableApplicationContext run(String... args) { StopWatch stopWatch = new StopWatch(); stopWatch.start(); // 声明一个 IoC 容器 ConfigurableApplicationContext context = null; FailureAnalyzers analyzers = null; // AWT 相关 configureHeadlessProperty(); // 通过 getSpringFactoriesInstances 从类路径下找到 META-INF/spring.factories 配置的所有 SpringApplicationRunListener 类并反射创建实例返回 SpringApplicationRunListeners listeners = getRunListeners(args); // 回调执行所有 SpringApplicationRunListener 实例的 starting 方法 listeners.starting(); try { // 封装命令行参数 ApplicationArguments applicationArguments = new DefaultApplicationArguments( args); // 准备环境,创建环境完成后在该方法中又回调执行了所有 SpringApplicationRunListener 实例的 environmentPrepared 方法,表示环境准备完成 ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments); // 控制台打印 SpringBoot 图标 Banner printedBanner = printBanner(environment); // 根据当前环境的不同创建不同类型的 IoC 容器 context = createApplicationContext(); // 初始化异常分析器 analyzers = new FailureAnalyzers(context); // 准备上下文环境: // 1、将 environment 保存到了 context 即 IoC 容器中 // 2、通过 applyInitializers(context) 方法,执行了所有 ApplicationContextInitializer 实例的 initialize(context) 方法(这些 ApplicationContextInitializer 实例是在初始化 SpringApplication 实例时创建保存的) // 3、还会回调执行所有 SpringApplicationRunListener 实例的 contextPrepared(context) 方法 // 4、在 prepareContext 方法最后一行还会回调执行所有 SpringApplicationRunListener 实例的 contextLoaded(context) 方法 prepareContext(context, environment, listeners, applicationArguments, printedBanner); // 刷新 IoC 容器,IoC 容器初始化,扫描、创建、加载所有组件(配置类、自动配置功能),如果是 web 应用,在这一步还会创建嵌入式 Servlet 容器 refreshContext(context); // 刷新后处理,会通过 callRunners(context, args) 方法从 IoC 容器中获取所有 ApplicationRunner 和 CommandLineRunner 的 bean,并回调它们的 run 方法 afterRefresh(context, applicationArguments); // 回调执行所有的 SpringApplicationRunListener 实例的 finished 方法,表示应用启动完成 listeners.finished(context, null); stopWatch.stop(); if (this.logStartupInfo) { new StartupInfoLogger(this.mainApplicationClass) .logStarted(getApplicationLog(), stopWatch); } // 整个 SpringBoot 应用启动完成后返回 IoC 容器 return context; } catch (Throwable ex) { handleRunFailure(context, listeners, analyzers, ex); throw new IllegalStateException(ex); } }
总结:
在 SpringBoot 应用启动的过程中会回调一些我们预配置组件的指定方法,这些组件可以是我们配置在指定文件中的类,也可以是我们注册到 IoC 容器的 bean。分类如下:
配置在 META-INF/spring.factories 中:
- org.springframework.context.ApplicationContextInitializer
- org.springframework.context.ApplicationListener
- org.springframework.boot.SpringApplicationRunListener
注册在 IoC 容器中:
- org.springframework.boot.ApplicationRunner
- org.springframework.boot.CommandLineRunner
执行的方法按回调顺序排序如下:
- SpringApplicationRunListener.starting()
- SpringApplicationRunListener.environmentPrepared()
- ApplicationContextInitializer.initialize()
- SpringApplicationRunListener.contextPrepared()
- SpringApplicationRunListener.contextLoaded()
- ApplicationRunner.run()
- CommandLineRunner.run()
- SpringApplicationRunListener.finished()
自定义starter
了解了 SpringBoot 程序的启动流程后,我们也可以自己编写一个 starter 了,下面为一个小案例,功能是让程序在启动时注册一个 hello 组件,并且能通过配置修改输出内容。
创建自动配置组件
1、使用 maven 创建一个 SpringBoot 程序作为自动配置组件,依赖如下:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.19.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.zze.springboot</groupId> <artifactId>mystarter_autoconfigure</artifactId> <version>0.0.1-SNAPSHOT</version> <name>mystarter_autoconfigure</name> <description>Demo project for Spring Boot</description> <packaging>jar</packaging> <properties> <java.version>1.8</java.version> </properties> <dependencies> <!--引入 spring-boot-starter--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> </dependencies> </project>
pom.xml
2、编写与配置文件属性映射的配置类:
package com.zze.springboot.config; import org.springframework.boot.context.properties.ConfigurationProperties; @ConfigurationProperties(prefix = "com.zze") public class HelloProperties { private String name; private String remark; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getRemark() { return remark; } public void setRemark(String remark) { this.remark = remark; } }
com.zze.springboot.config.HelloProperties
3、编写 hello 服务:
package com.zze.springboot.service; import com.zze.springboot.config.HelloProperties; public class HelloService { private HelloProperties helloProperties; public void setHelloProperties(HelloProperties helloProperties) { this.helloProperties = helloProperties; } public void sayHello() { System.out.println("hello " + helloProperties.getName() + " " + helloProperties.getRemark()); } }
com.zze.springboot.service.HelloService
4、编写自动配置类:
package com.zze.springboot.autoconfigure; import com.zze.springboot.config.HelloProperties; import com.zze.springboot.service.HelloService; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; /** * 自定义自动配置类 */ @EnableConfigurationProperties(HelloProperties.class) // 启用指定类的配置映射,并将配置类实例注册到 IoC 容器 @Configuration @ConditionalOnWebApplication // web 应用时才生效 public class MyStarterAutoConfiguration { private HelloProperties helloProperties; public MyStarterAutoConfiguration(HelloProperties helloProperties){ this.helloProperties = helloProperties; } // 注册 hello 服务到 IoC 容器 @Bean public HelloService helloService(){ HelloService helloService = new HelloService(); helloService.setHelloProperties(helloProperties); return helloService; } }
com.zze.springboot.autoconfigure.MyStarterAutoConfiguration
5、配置自动配置类,让程序启动时加载自动配置类让其生效:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ com.zze.springboot.autoconfigure.MyStarterAutoConfiguration
META-INF/spring.factories
创建starter工程
1、创建普通的 maven 项目作为 starter 组件,引入上面编写的自动配置组件依赖:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.zze.springboot</groupId> <artifactId>mystarter</artifactId> <version>1.0-SNAPSHOT</version> <dependencies> <!--引入自动配置模块--> <dependency> <groupId>com.zze.springboot</groupId> <artifactId>mystarter_autoconfigure</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency> </dependencies> </project>
pom.xml
2、将自动配置组件及 starter 组件安装到 maven 仓库。
测试
1、使用 maven 新创建一个 SpringBoot 项目,引入我们编写的 starter 依赖:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.19.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.example</groupId> <artifactId>demo</artifactId> <version>0.0.1-SNAPSHOT</version> <name>demo</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>com.zze.springboot</groupId> <artifactId>mystarter</artifactId> <version>1.0-SNAPSHOT</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
pom.xml
2、配置 hello 服务所需要的相关属性:
com.zze.name=张三 com.zze.remark=会员
application.properties
3、直接注入 hello 服务,测试:
package com.example.demo; import com.zze.springboot.service.HelloService; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) @SpringBootTest public class DemoApplicationTests { @Autowired private HelloService helloService; @Test public void contextLoads() { helloService.sayHello(); /* hello 张三 会员 */ } }
test
- 启动器模块是一个空 jar 文件,仅提供辅助性依赖管理,这些依赖可能用于自动装配或其它类库。启动器依赖于自动配置,第三方使用只需要引入启动器。
- 自动配置类能加载的前提是要将其配置在 META-INF/spring.factories 文件中的 org.springframework.boot.autoconfigure.EnableAutoConfiguration 节下。
java框架之SpringBoot(10)-启动流程及自定义starter的更多相关文章
- SpringBoot IoC启动流程、初始化过程及Bean生命周期各个阶段的作用
目录 SpringBoot IoC启动流程.初始化过程及Bean生命周期各个阶段的作用 简述 首先明确IoC容器是啥 准备-SpringApplication的实例化 启动-SpringApplica ...
- SpringBoot的启动流程是怎样的?SpringBoot源码(七)
注:该源码分析对应SpringBoot版本为2.1.0.RELEASE 1 温故而知新 本篇接 SpringBoot内置的各种Starter是怎样构建的? SpringBoot源码(六) 温故而知新, ...
- java框架之SpringBoot(2)-配置
规范 SpringBoot 使用一个全局的配置文件,配置文件名固定为 application.properties 或 application.yml .比如我们要配置程序启动使用的端口号,如下: s ...
- SpringBoot的启动流程分析(2)
我们来分析SpringApplication启动流程中的run()方法,代码如下 public ConfigurableApplicationContext run(String... args) { ...
- SpringBoot的启动流程分析(1)
通过分析我们可以找到 org.springframework.boot.SpringApplication 中如下, public static ConfigurableApplicationCont ...
- SpringBoot之旅第六篇-启动原理及自定义starter
一.引言 SpringBoot的一大优势就是Starter,由于SpringBoot有很多开箱即用的Starter依赖,使得我们开发变得简单,我们不需要过多的关注框架的配置. 在日常开发中,我们也会自 ...
- linux启动流程及自定义gurb
linux 启动流程 POST BIOS(boot sequence) 所选择的启动设备次序的MBR中是否有引导程序, ----> MBR(bootloader) 提供内核列表 -------& ...
- springboot项目启动之后初始化自定义配置类
前言 今天在写项目的时候,需要再springboot项目启动之后,加载我自定义的配置类的一些方法,百度了之后特此记录下. 正文 方法有两种: 1. 创建自定义类实现 CommandLineRunner ...
- java框架之SpringBoot(1)-入门
简介 Spring Boot 用来简化 Spring 应用开发,约定大于配置,去繁从简,just run 就能创建一个独立的.产品级别的应用. 背景: J2EE 笨重的开发.繁多的配置.低下的开发效率 ...
随机推荐
- Unity3D中录制和输出wav文件
近期在做视频录制方面的事情,看了下音频的录制和输出.主要参考官方的FrameCapturer: https://github.com/unity3d-jp/FrameCapturer wav文件结构较 ...
- electron-vue开发爬坑指南
electron-vue开发遇到的爬坑过程,遇到了以下几种坑: 1:静态资源目录访问不了,想访问放在static目录下的静态资源,使用express指定静态目录访问不到,解决办法:使用electron ...
- python模块import具体用法
同级目录 import 文件名 form 文件名 import * 子目录 import 目录名.文件名 form 目录名.文件名 import * 不同目录 先导入sys包,然后把对应的目录加入pa ...
- 【iCore4 双核心板_ARM】例程三十七:SDRAM实验——读写SDRAM
实验现象: 上电即开始读写SDRAM测试,测试过程中,蓝色LED点亮,如果出现错误,红色LED闪烁,测试成功,绿色LED点亮. 核心代码: int main(void) { /* USER CODE ...
- C++ 如何决定字面常量类型
C++ 是如何决定字面常量的类型的? #include <iostream> #include <cmath> int main() { using namespace std ...
- linux下access函数
Linux内核总是根据进程的有效用户ID和有效组ID来决定一个进程是否有权访问某个文件. 因此,在编写调整用户ID的程序时,在读写一个文件之前必须明确检查其用户是否原本就有对此文件的访问权限. 为了实 ...
- 关于QT Graphics View开启OpenGL渲染后复选框、微调框等无法正常显示的问题
之前学习QT Graphics View框架,除了基本的图元外,还可以通过QGraphicsProxyWidget类添加QT的基本Widget(如按钮.复选框.单选框等),常使用的场景类接口如下: Q ...
- mvc 根据模板导出excel,直接导出文件流
1.c# /// <summary> /// 导出员工 /// </summary> /// <returns></returns> [HttpGet] ...
- Jquery EasyUI Combotree只能选择叶子节点且叶子节点有多选框
Jquery EasyUI Combotree只能选择叶子节点且叶子节点有多选框 Jquery EasyUI Combotree单选框,Jquery EasyUI Combotree只能选择叶子节点 ...
- linux telnet检测与某个端口是否开通
转自:http://blog.51cto.com/meiling/1982402 一:telnet此法常被用来检测是个远端端口是否通畅. 测试域名: # telnet baidu.com 80 Try ...