写一个springboot入门的入门案例,为什么SpringApplication.run会报错?

springboot 初始化 web 项目 启动报错。。。一直解决不了 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
已注册用户请 &
springboot 初始化 web 项目 启动报错。。。一直解决不了
· 121 天前 · 981 次点击
17:08:30.711 ERROR 18688 --- [cat-startStop-1] org.apache.catalina.core.ContainerBase
: A child container failed during start
java.util.concurrent.ExecutionException: org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Tomcat].StandardHost[localhost].TomcatEmbeddedContext[]]
at java.util.concurrent.FutureTask.report(FutureTask.java:122) [na:1.8.0_91]
at java.util.concurrent.FutureTask.get(FutureTask.java:192) [na:1.8.0_91]
at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:941) ~[tomcat-embed-core-8.5.29.jar:8.5.29]
at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:872) [tomcat-embed-core-8.5.29.jar:8.5.29]
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) [tomcat-embed-core-8.5.29.jar:8.5.29]
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1421) [tomcat-embed-core-8.5.29.jar:8.5.29]
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1411) [tomcat-embed-core-8.5.29.jar:8.5.29]
at java.util.concurrent.FutureTask.run(FutureTask.java:266) [na:1.8.0_91]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_91]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_91]
at java.lang.Thread.run(Thread.java:745) [na:1.8.0_91]
Caused by: org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Tomcat].StandardHost[localhost].TomcatEmbeddedContext[]]
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:167) [tomcat-embed-core-8.5.29.jar:8.5.29]
... 6 common frames omitted
Caused by: org.apache.catalina.LifecycleException: Failed to start component [Pipeline[StandardEngine[Tomcat].StandardHost[localhost].TomcatEmbeddedContext[]]]
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:167) [tomcat-embed-core-8.5.29.jar:8.5.29]
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5125) ~[tomcat-embed-core-8.5.29.jar:8.5.29]
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) [tomcat-embed-core-8.5.29.jar:8.5.29]
... 6 common frames omitted
Caused by: org.apache.catalina.LifecycleException: Failed to start component [org.apache.catalina.authenticator.NonLoginAuthenticator[]]
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:167) [tomcat-embed-core-8.5.29.jar:8.5.29]
at org.apache.catalina.core.StandardPipeline.startInternal(StandardPipeline.java:182) ~[tomcat-embed-core-8.5.29.jar:8.5.29]
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) [tomcat-embed-core-8.5.29.jar:8.5.29]
... 8 common frames omitted
Caused by: java.lang.NoSuchMethodError: javax.servlet.ServletContext.getVirtualServerName()Ljava/lang/S
at org.apache.catalina.authenticator.AuthenticatorBase.startInternal(AuthenticatorBase.java:1186) ~[tomcat-embed-core-8.5.29.jar:8.5.29]
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) [tomcat-embed-core-8.5.29.jar:8.5.29]
... 10 common frames omitted
17:08:30.712 ERROR 18688 --- [
main] org.apache.catalina.core.ContainerBase
: A child container failed during start
java.util.concurrent.ExecutionException: org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Tomcat].StandardHost[localhost]]
at java.util.concurrent.FutureTask.report(FutureTask.java:122) ~[na:1.8.0_91]
at java.util.concurrent.FutureTask.get(FutureTask.java:192) ~[na:1.8.0_91]
at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:941) ~[tomcat-embed-core-8.5.29.jar:8.5.29]
at org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.java:262) [tomcat-embed-core-8.5.29.jar:8.5.29]
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) [tomcat-embed-core-8.5.29.jar:8.5.29]
at org.apache.catalina.core.StandardService.startInternal(StandardService.java:422) [tomcat-embed-core-8.5.29.jar:8.5.29]
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) [tomcat-embed-core-8.5.29.jar:8.5.29]
at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:793) [tomcat-embed-core-8.5.29.jar:8.5.29]
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) [tomcat-embed-core-8.5.29.jar:8.5.29]
at org.apache.catalina.startup.Tomcat.start(Tomcat.java:367) [tomcat-embed-core-8.5.29.jar:8.5.29]
at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.initialize(TomcatWebServer.java:107) [spring-boot-2.0.1.RELEASE.jar:2.0.1.RELEASE]
at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.&init&(TomcatWebServer.java:86) [spring-boot-2.0.1.RELEASE.jar:2.0.1.RELEASE]
at org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory.getTomcatWebServer(TomcatServletWebServerFactory.java:409) [spring-boot-2.0.1.RELEASE.jar:2.0.1.RELEASE]
at org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory.getWebServer(TomcatServletWebServerFactory.java:174) [spring-boot-2.0.1.RELEASE.jar:2.0.1.RELEASE]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.createWebServer(ServletWebServerApplicationContext.java:179) [spring-boot-2.0.1.RELEASE.jar:2.0.1.RELEASE]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.java:152) [spring-boot-2.0.1.RELEASE.jar:2.0.1.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:544) [spring-context-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:140) [spring-boot-2.0.1.RELEASE.jar:2.0.1.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:759) [spring-boot-2.0.1.RELEASE.jar:2.0.1.RELEASE]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:395) [spring-boot-2.0.1.RELEASE.jar:2.0.1.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:327) [spring-boot-2.0.1.RELEASE.jar:2.0.1.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1255) [spring-boot-2.0.1.RELEASE.jar:2.0.1.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1243) [spring-boot-2.0.1.RELEASE.jar:2.0.1.RELEASE]
at com.example.demo.DemoApplication.main(DemoApplication.java:10) [classes/:na]
Caused by: org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Tomcat].StandardHost[localhost]]
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:167) [tomcat-embed-core-8.5.29.jar:8.5.29]
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1421) ~[tomcat-embed-core-8.5.29.jar:8.5.29]
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1411) ~[tomcat-embed-core-8.5.29.jar:8.5.29]
at java.util.concurrent.FutureTask.run(FutureTask.java:266) ~[na:1.8.0_91]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) ~[na:1.8.0_91]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) ~[na:1.8.0_91]
at java.lang.Thread.run(Thread.java:745) ~[na:1.8.0_91]
Caused by: org.apache.catalina.LifecycleException: A child container failed during start
at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:949) ~[tomcat-embed-core-8.5.29.jar:8.5.29]
at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:872) ~[tomcat-embed-core-8.5.29.jar:8.5.29]
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) [tomcat-embed-core-8.5.29.jar:8.5.29]
... 6 common frames omitted
4 回复 &| &直到
13:59:44 +08:00
& &121 天前
8 common frames omitted Caused by: java.lang.NoSuchMethodError: javax.servlet.ServletContext.getVirtualServerName()Ljava/lang/S 依赖库没倒全吧maven 重新 import 一下
& &120 天前
我试过了 不行
我本地仓库清空了 重置也不行
& &119 天前 via iPhone
有 javaee-api 这个包吗
& &118 天前
打扰到大家了,我已经找到问题所在了,是因为我配置 jdk 环境变量的时候,照网上的教程加了 classpath 这个变量,导致执行程序的时候优先去这里找,这里的 ext lib 里有 servlet.jar 估计跟 springboot 内嵌的 tomcat servlet 冲突了,导致无法启动。
& · & 1784 人在线 & 最高记录 3762 & · &
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.1 · 39ms · UTC 04:46 · PVG 12:46 · LAX 21:46 · JFK 00:46? Do have faith in what you're doing.之前的文章我们分析了SpringApplication#run方法执行的前4步,这里我们分析第5步,打印banner.
SpringApplication#run方法的第5步执行如下代码:
private Banner printBanner(ConfigurableEnvironment environment) {
if (this.bannerMode == Banner.Mode.OFF) {
return null;
ResourceLoader resourceLoader = this.resourceLoader != null ? this.resourceLoader
: new DefaultResourceLoader(getClassLoader());
SpringApplicationBannerPrinter bannerPrinter = new SpringApplicationBannerPrinter(
resourceLoader, this.banner);
if (this.bannerMode == Mode.LOG) {
return bannerPrinter.print(environment, this.mainApplicationClass, logger);
return bannerPrinter.print(environment, this.mainApplicationClass, System.out);
如果this.bannerMode等于Banner.Mode.OFF,则直接返回空。
获取资源加载器ResourceLoader.代码如下:
ResourceLoader resourceLoader = this.resourceLoader != null ? this.resourceLoader
: new DefaultResourceLoader(getClassLoader());
对于当前的场景来说, SpringApplication 中的 resourceLoader为null.因此会实例化DefaultResourceLoader.
实例化SpringApplicationBannerPrinter类.代码如下:
SpringApplicationBannerPrinter(ResourceLoader resourceLoader, Banner fallbackBanner) {
this.resourceLoader = resourceL
this.fallbackBanner = fallbackB
注意.在当前场景下, SpringApplicationBannerPrinter中的fallbackBanner为null.
如果banner的输出模式是Mode.LOG,则直接将其信息输出到logger日志中.
默认情况下. SpringApplication中的banner输出模式为CONSOLE.因此是不会输出到日志的.
banner的输出默认如下:
enum Mode {
* Disable printing of the banner.
* Print the banner to System.out.
* Print the banner to the log file.
将banner输出到控制台,也就是System.out.代码如下:
public Banner print(Environment environment, Class&?& sourceClass, PrintStream out) {
Banner banner = getBanner(environment, this.fallbackBanner);
banner.printBanner(environment, sourceClass, out);
return new PrintedBanner(banner, sourceClass);
做了3件事:
获取Banner
调用Banner中的printBanner方法.进行banner的打印.
实例化PrintedBanner类
获取banner的方法如下:
private Banner getBanner(Environment environment, Banner definedBanner) {
Banners banners = new Banners();
banners.addIfNotNull(getImageBanner(environment));
banners.addIfNotNull(getTextBanner(environment));
if (banners.hasAtLeastOneBanner()) {
if (this.fallbackBanner != null) {
return this.fallbackB
return DEFAULT_BANNER;
实例化Banners.然后为其设置ImageBanner和TextBanner.如果此时anners对象的banners不为空.则返回Banners.
如果fallbackBanner不为null的话,返回fallbackBanner.对于当前场景来说fallbackBanner为null.
返回默认的banner.默认的bannenr为 SpringBootBanner.
这里有必要说明一下banner的继承体系.如下:
其只声明了一个方法.如下:
public interface Banner {
* Print the banner to the specified print stream.
* environment the spring environment
* sourceClass the source class for the application
* out the output print stream
void printBanner(Environment environment, Class&?& sourceClass, PrintStream out);
Banners实例化后,会调用getImageBanner方法进行加载.代码如下:
static final String[] IMAGE_EXTENSION = { "gif", "jpg", "png" };
private Banner getImageBanner(Environment environment) {
String location = environment.getProperty(BANNER_IMAGE_LOCATION_PROPERTY);
if (StringUtils.hasLength(location)) {
Resource resource = this.resourceLoader.getResource(location);
return (resource.exists() ? new ImageBanner(resource) : null);
for (String ext : IMAGE_EXTENSION) {
Resource resource = this.resourceLoader.getResource("banner." + ext);
if (resource.exists()) {
return new ImageBanner(resource);
return null;
首先判断是否配置了系统属性banner.image.location,如果有直接返回ImageBanner.
如果没有配置则在classpath中查找banner.gif,banner.jpg,banner.png,如果找到,则创建一个ImageBanner对象并添加到Banners对象的banners属性中,该属性是一个List.代码如下:
private final List&Banner& banners = new ArrayList&Banner&();
public void addIfNotNull(Banner banner) {
if (banner != null) {
this.banners.add(banner);
很明显 对于当前场景来说. getImageBanner返回的是null.
接下来调用getTextBanner.来加载TextBanner.代码如下:
private Banner getTextBanner(Environment environment) {
String location = environment.getProperty(BANNER_LOCATION_PROPERTY,
DEFAULT_BANNER_LOCATION);
Resource resource = this.resourceLoader.getResource(location);
if (resource.exists()) {
return new ResourceBanner(resource);
return null;
还是同样的套路.
从environment中获取banner.location属性,默认为banner.txt
进行加载.如果存在的话,则返回ResourceBanner.否则返回null.
对于当前场景来说.返回的是null.
因此,对于当前场景来说. getBanner返回的是SpringBootBanner.
接下来调用SpringBootBanner#printBanner方法.代码如下:
private static final String[] BANNER = { "",
" /\\\\ / ___'_ __ _ _(_)_ __
__ _ \\ \\ \\ \\",
"( ( )\\___ | '_ | '_| | '_ \\/ _` | \\ \\ \\ \\",
___)| |_)| | | | | || (_| |
|____| .__|_| |_|_| |_\\__, | / / / /",
" =========|_|==============|___/=/_/_/_/" };
private static final String SPRING_BOOT = " :: Spring Boot :: ";
private static final int STRAP_LINE_SIZE = 42;
public void printBanner(Environment environment, Class&?& sourceClass,
PrintStream printStream) {
for (String line : BANNER) {
printStream.println(line);
String version = SpringBootVersion.getVersion();
version = (version == null ? "" : " (v" + version + ")");
String padding = "";
while (padding.length() & STRAP_LINE_SIZE
- (version.length() + SPRING_BOOT.length())) {
padding += " ";
printStream.println(AnsiOutput.toString(AnsiColor.GREEN, SPRING_BOOT,
AnsiColor.DEFAULT, padding, AnsiStyle.FAINT, version));
printStream.println();
循环遍历BANNER数组,并依次进行数组内容的打印
调用SpringBootVersion#getVersion,进行springboot版本信息的获取.然后为了与之前的输出字符进行对齐,在springboot版本信息前加空格.SpringBootVersion#getVersion代码如下:
public static String getVersion() {
Package pkg = SpringApplication.class.getPackage();
return (pkg != null ? pkg.getImplementationVersion() : null);
通过AnsiOutput#toString方法生成字符.输出到PrintStream.最后输出一个回车换行.
public static String toString(Object... elements) {
StringBuilder sb = new StringBuilder();
if (isEnabled()) {
buildEnabled(sb, elements);
buildDisabled(sb, elements);
return sb.toString();
实例化StringBuilder进行字符串拼接.
判断是否可用.如果可以调用buildEnabled.否则调用buildDisabled. isEnabled方法如下:
private static boolean isEnabled() {
if (enabled == Enabled.DETECT) {
if (ansiCapable == null) {
ansiCapable = detectIfAnsiCapable();
return ansiC
return enabled == Enabled.ALWAYS;
这里用到了我们之前分析过的知识.springApplication run 方法执行前4步的过程中.发送了ApplicationEnvironmentPreparedEvent 时间. 其中AnsiOutputApplicationListener 对该事件进行了处理.代码如下:
public void onApplicationEvent(ApplicationEnvironmentPreparedEvent event) {
RelaxedPropertyResolver resolver = new RelaxedPropertyResolver(
event.getEnvironment(), "spring.output.ansi.")
if (resolver.containsProperty("enabled")) {
String enabled = resolver.getProperty("enabled")
AnsiOutput.setEnabled(Enum.valueOf(Enabled.class, enabled.toUpperCase()))
if (resolver.containsProperty("console-available")) {
AnsiOutput.setConsoleAvailable(
resolver.getProperty("console-available", Boolean.class))
对于当前场景来说. resolver中是含有spring.output.ansi.enabled 的配置的.默认为true
因此会将AnsiOutput的enabled 设置为Enabled.ALWAYS.
因此这里会执行buildEnabled方法.代码如下:
private static void buildEnabled(StringBuilder sb, Object[] elements) {
boolean writingAnsi = false;
boolean containsEncoding = false;
for (Object element : elements) {
if (element instanceof AnsiElement) {
containsEncoding = true;
if (!writingAnsi) {
sb.append(ENCODE_START);
writingAnsi = true;
sb.append(ENCODE_JOIN);
if (writingAnsi) {
sb.append(ENCODE_END);
writingAnsi = false;
sb.append(element);
if (containsEncoding) {
sb.append(writingAnsi ? ENCODE_JOIN : ENCODE_START);
sb.append(RESET);
sb.append(ENCODE_END);
这里返回的字符串为
[32m :: Spring Boot :: 
自定义banner
通过之前的分析,我们知道了SpringApplicationBannerPrinter#getBanner 默认返回的是SpringBootBanner.但是当我们在类路径下 放入banner.txt或者在banner.image.location 放入图片.又该如何呢? 此时返回的是Banners.在打印时会调用Banners#printBanner方法.代码如下:
public void printBanner(Environment environment, Class&?& sourceClass,
PrintStream out) {
for (Banner banner : this.banners) {
banner.printBanner(environment, sourceClass, out);
很简单循环遍历banners调用其printBanner进行打印.那么Banners会有哪些banner呢?由前可知有
ImageBanner
ResourceBanner
那么我们就分别看下其printBanner方法.
ImageBanner#printBanner 代码如下:
public void printBanner(Environment environment, Class&?& sourceClass,
PrintStream out) {
// 1. 获取系统环境变量中的java.awt.headless变量。
String headless = System.getProperty("java.awt.headless")
// 2. 设置java.awt.headless变量值为true。并调用printBanner方法进行图案的打印工作
System.setProperty("java.awt.headless", "true")
printBanner(environment, out)
catch (Throwable ex) {
logger.warn("Image banner not printable: " + this.image + " (" + ex.getClass()
+ ": '" + ex.getMessage() + "')")
logger.debug("Image banner printing failure", ex)
// 3. finally中还原操作系统中的java.awt.headless环境变量值
if (headless == null) {
System.clearProperty("java.awt.headless")
System.setProperty("java.awt.headless", headless)
获取系统环境变量中的java.awt.headless变量。
设置java.awt.headless变量值为true。并调用printBanner方法进行图案的打印工作
finally中还原操作系统中的java.awt.headless环境变量值
指定一提的是,java.awt.headless 默认就是true.
printBanner方法代码如下:
private void printBanner(Environment environment, PrintStream out)
throws IOException {
PropertyResolver properties = new RelaxedPropertyResolver(environment,
"banner.image.");
int width = properties.getProperty("width", Integer.class, 76);
int height = properties.getProperty("height", Integer.class, 0);
int margin = properties.getProperty("margin", Integer.class, 2);
boolean invert = properties.getProperty("invert", Boolean.class, false);
BufferedImage image = readImage(width, height);
printBanner(image, margin, invert, out);
读取banner.image.width,默认为 76 .
读取banner.image.height,默认为 0 .
读取banner.image.margin,默认为 2.
读取banner.image.invert,默认为 false.
调用readImage 进行图片的读取.代码如下:
private BufferedImage readImage(int width, int height) throws IOException {
InputStream inputStream = this.image.getInputStream();
BufferedImage image = ImageIO.read(inputStream);
return resizeImage(image, width, height);
inputStream.close();
通过ImageIO进行读取,最后通过读取图片的配置参数,进行图片的缩放处理.
printBanner 实现如下:
private void printBanner(BufferedImage image, int margin, boolean invert,
PrintStream out) {
AnsiElement background = (invert ? AnsiBackground.BLACK : AnsiBackground.DEFAULT)
out.print(AnsiOutput.encode(AnsiColor.DEFAULT))
out.print(AnsiOutput.encode(background))
out.println()
out.println()
AnsiColor lastColor = AnsiColor.DEFAULT
for (int y = 0
for (int i = 0
out.print(" ")
for (int x = 0
Color color = new Color(image.getRGB(x, y), false)
AnsiColor ansiColor = AnsiColors.getClosest(color)
if (ansiColor != lastColor) {
out.print(AnsiOutput.encode(ansiColor))
lastColor = ansiColor
out.print(getAsciiPixel(color, invert))
out.println()
out.print(AnsiOutput.encode(AnsiColor.DEFAULT))
out.print(AnsiOutput.encode(AnsiBackground.DEFAULT))
out.println()
没什么可说的,图片是由一个一个的像素组成的,直接输出每个像素即可.
ResourceBanner#printBanner,代码如下:
public void printBanner(Environment environment, Class&?& sourceClass,
PrintStream out) {
// 1. 获取resource中的输入流,并将其转化为字符串 通过environment获取banner.charset变量,如果不存在,则默认使用UTF-8编码
String banner = StreamUtils.copyToString(this.resource.getInputStream(),
environment.getProperty("banner.charset", Charset.class,
Charset.forName("UTF-8")))
// 2. 循环遍历所有的PropertyResolver 去解析banner中配置的spel表达式
for (PropertyResolver resolver : getPropertyResolvers(environment,
sourceClass)) {
banner = resolver.resolvePlaceholders(banner)
// 3. 打印字符串信息
out.println(banner)
catch (Exception ex) {
logger.warn("Banner not printable: " + this.resource + " (" + ex.getClass()
+ ": '" + ex.getMessage() + "')", ex)
获取resource中的输入流,并将其转化为字符串 通过environment获取banner.charset变量,如果不存在,则默认使用UTF-8编码
循环遍历所有的PropertyResolver 去解析banner中配置的spel表达式.
首先通过getPropertyResolvers 获得所有的PropertyResolver.代码如下:
protected List&PropertyResolver& getPropertyResolvers(Environment environment,
Class&?& sourceClass) {
List&PropertyResolver& resolvers = new ArrayList&PropertyResolver&();
resolvers.add(environment);
resolvers.add(getVersionResolver(sourceClass));
resolvers.add(getAnsiResolver());
resolvers.add(getTitleResolver(sourceClass));
实例化resolvers集合,并添加environment元素,Environment接口继承自PropertyResolver接口
调用getVersionResolver(sourceClass)方法并将其返回值添加到resolvers集合
private PropertyResolver getVersionResolver(Class&?& sourceClass) {
MutablePropertySources propertySources = new MutablePropertySources();
propertySources
.addLast(new MapPropertySource("version", getVersionsMap(sourceClass)));
return new PropertySourcesPropertyResolver(propertySources);
其构建了一个MapPropertySource,名为version,value是通过getVersionsMap方法获得的.最后返回一个PropertySourcesPropertyResolver.代码如下:
private Map&String, Object& getVersionsMap(Class&?& sourceClass) {
String appVersion = getApplicationVersion(sourceClass);
String bootVersion = getBootVersion();
Map&String, Object& versions = new HashMap&String, Object&();
versions.put("application.version", getVersionString(appVersion, false));
versions.put("spring-boot.version", getVersionString(bootVersion, false));
versions.put("application.formatted-version", getVersionString(appVersion, true));
versions.put("spring-boot.formatted-version",
getVersionString(bootVersion, true));
protected String getApplicationVersion(Class&?& sourceClass) {
Package sourcePackage = (sourceClass == null ? null : sourceClass.getPackage());
return (sourcePackage == null ? null : sourcePackage.getImplementationVersion());
protected String getBootVersion() {
return SpringBootVersion.getVersion();
private String getVersionString(String version, boolean format) {
if (version == null) {
return "";
return (format ? " (v" + version + ")" : version);
首先通过调用getApplicationVersion方法获得appVersion.其是通过获取sourceClass所在包的版本号. sourceClass为应用的启动类
获取Boot版本号.同样是通过获得SpringApplication所在包的版本号完成的
在map中存入数据.
该方法最终的数据为:
{application.formatted-version=, application.version=, spring-boot.formatted-version=, spring-boot.version=}
调用getAnsiResolver(sourceClass)方法并将其返回值添加到resolvers集合 直接设置开启了ansi.代码如下:
private PropertyResolver getAnsiResolver() {
MutablePropertySources sources = new MutablePropertySources();
sources.addFirst(new AnsiPropertySource("ansi", true));
return new PropertySourcesPropertyResolver(sources);
调用getTitleResolver(sourceClass)方法并将其返回值添加到resolvers集合.代码如下:
private PropertyResolver getTitleResolver(Class&?& sourceClass) {
MutablePropertySources sources = new MutablePropertySources();
String applicationTitle = getApplicationTitle(sourceClass);
Map&String, Object& titleMap = Collections.&String, Object&singletonMap("application.title", (applicationTitle == null ? "" : applicationTitle));
sources.addFirst(new MapPropertySource("title", titleMap));
return new PropertySourcesPropertyResolver(sources);
调用getApplicationTitle获得title.代码如下:
protected String getApplicationTitle(Class&?& sourceClass) {
Package sourcePackage = (sourceClass == null ? null : sourceClass.getPackage());
return (sourcePackage == null ? null : sourcePackage.getImplementationTitle());
打印字符串信息
SpringBoot——run启动流程
SpringApplicationRunListener是SpringBoot应用的main()执行过程中接不同执行时点通知的【监听者】。
applicationListener是Spring框架对...
Spring Boot【原理分析】(1)——SpringApplication
SpringApplication作为Spring Boot的启动类。
一、入口方法run
public static ConfigurableApplicationContext run...
SpringApplication方法run的事件监听器机制
Spring boot应用,这里具体的来说,是指类SpringApplication,在其run()方法运行过程中,主要围绕所使用ApplicationContext对象的生命周期事件,应用了...
SpringApplication.run执行流程
1.这个方法里面首先创建一个SpringApplication对象实例,然后调用这个创建好的SpringApplication的实例方法。在SpringApplication实例初始化的时候,它会提前...
spring boot应用启动原理分析
spring boot quick start在spring boot里,很吸引人的一个特性是可以直接把应用打包成为一个jar/war,然后这个jar/war是可以直接启动的,不需要另外配置一个Web...
SpringApplication 的运行过程分析: run()
1 SpringBoot简介SpringBoot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程。该框架使用了特定的方式来进行配置,从而使开发人员不再...
技术不太好,对spring在慢慢学习ing.写的有错误还望指正..
spring的运行需要在web.xml加上spring的监听,
配置spring的xml文件路径
contextCo...
前言在spring boot 源码解析2-SpringApplication初始化 中我们分析了SpringApplication的初始化.接下来我们继续分析SpringApplication的run...
public static void main(String[] args) {
ApplicationContext context = new FileSy...
没有更多推荐了,

我要回帖

更多关于 springmvc工作原理 的文章

 

随机推荐