运行 Spring-引导的主要使用 IDE
Run Spring-boot's main using IDE
我有一个 spring-boot 应用程序需要:
- 可作为 war 部署在 servlet 容器中
- 运行可通过`mvn spring-boot:运行``
我还希望能够通过右键单击 main
在我的 IDE(Eclipse 或 IntelliJ IDE社区)中 运行 这个应用程序并 运行宁它。
以下是我的 pom.xml 中有趣的部分(请注意,我没有继承自 spring-boot-starter-parent pom):
...
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
...
<build>
<plugins>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring.boot.version}</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
这是我的 SpringBootServletInitializer
:
@Configuration
@EnableAutoConfiguration
@ComponentScan("com.company.theproject")
public class Application extends SpringBootServletInitializer
{
private static final Logger logger = LoggerFactory.getLogger(Application.class);
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application)
{
return application.sources(Application.class);
}
public static void main(String[] args)
{
SpringApplication.run(Application.class, args);
}
}
当 运行 在 IDE 中设置主函数时,我得到以下错误:
org.springframework.context.ApplicationContextException: Unable to start EmbeddedWebApplicationContext due to missing EmbeddedServletContainerFactory bean.
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.getEmbeddedServletContainerFactory(EmbeddedWebApplicationContext.java:183) ~[spring-boot-1.2.3.RELEASE.jar:1.2.3.RELEASE]
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.createEmbeddedServletContainer(EmbeddedWebApplicationContext.java:156) ~[spring-boot-1.2.3.RELEASE.jar:1.2.3.RELEASE]
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.onRefresh(EmbeddedWebApplicationContext.java:130) ~[spring-boot-1.2.3.RELEASE.jar:1.2.3.RELEASE]
... 12 common frames omitted
似乎 mvn spring-boot:run
做了一些在 运行 直接 main
时不会发生的魔法。
从 spring-boot-starter-tomcat
依赖项中删除 provided
作用域修复了这个问题,但当 war 在 servlet 容器中是 运行 时会造成问题。
目前我发现的唯一 "fix" 是在 IntelliJ IDEA 中 运行 mvn spring-boot:run
而不是直接 运行ning main。虽然这是一个可以接受的解决方法,但我仍然想知道为什么它不起作用以及是否可以修复。
mvn spring-boot:run
在创建类路径时包含 provided
依赖项。听起来像 IntelliJ IDEA 没有。如果类路径中没有 Tomcat,Spring Boot 将无法创建嵌入式 servlet 容器,这会导致您看到的异常。可以说这是 IntelliJ 中的一个错误,因为如果没有容器提供依赖项,那么它确实需要在类路径中。
您可以通过覆盖 IntelliJ 在 运行 包含 spring-boot-starter-tomcat
依赖项的主要方法时使用的默认类路径来解决问题。
我认为这可能与 https://youtrack.jetbrains.com/issue/IDEA-107048
有关
IntelliJ IDEA 没有将 provided
依赖项注入 CLASSPATH,正如 Andy 所说,这就是 spring 无法创建嵌入式 servlet 容器的原因。
他们自 2005 年以来就提出了关于此的功能请求:https://youtrack.jetbrains.com/issue/IDEABKL-99
评论中提到的解决方法包括拥有一个带有必要库的假模块并将其用作类路径,使用 -Xbootclasspath JVM 参数或使用自定义 maven 配置文件 运行 (compiled
) vs建筑物(provided
)。
受 https://youtrack.jetbrains.com/issue/IDEA-140041 强烈启发的解决方法是使用测试 class 路径(包括嵌入式 servlet。)启动主 class。
步骤(IntelliJ 16):
Run
-> Edit Configurations
-> Add new configuration
-> 选择 Application
类型。
- 将
Main class
设置为<your.main.class>
- 将
Use classpath of module
设置为<*>_test
(测试模块!)
Ok
又Run
啦!
我找到这个 page,并使用 maven 配置文件来管理配置文件。
<profiles>
<profile>
<id>PROD</id>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
</profile>
<profile>
<id>DEV</id>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>TEST</scope>
</dependency>
</dependencies>
</profile>
</profiles>
并配置主要 class beforeLanuce
,设置命令
mvn clean compile -Pdev
我能够通过在项目结构->依赖项选项卡下将 spring-boot-starter-tomcat 依赖项的范围更改为 "compile" 来完成这项工作。这不会影响 pom.xml 但允许此依赖项可用于 spring 启动 运行 配置
Click here for image on where to change this setting in idea
我能够通过将提供的 libaray (spring-boot-starter-tomcat) 添加到项目配置来解决 Intellij IDEA 2017.2 中的这个问题。
Select 文件 -> 项目结构。 Select 库并添加一个新的项目库(type = From Maven...)。使用对话框搜索 spring-boot-starter-tomcat,select 正确的版本,然后单击确定添加它。该库已添加到外部库列表中。
缺点是如果 Spring 引导版本发生变化,那么您将不得不记得删除该库并添加新版本。
使用下面的配置文件和说明,您可以向 Maven 添加配置文件,允许在 IntelliJ 中进行开发,而无需针对其他环境进行更改。
<!-- Leave original dependency as-is -->
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
<profiles>
<!-- Enable this profile to run in IntelliJ. IntelliJ excludes provided dependencies from compile by default. -->
<profile>
<id>intellij</id>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>compile</scope>
</dependency>
</dependencies>
</profile>
</profiles>
点击IntelliJ右侧的Maven Projects按钮,在Profiles下,selectintellij
.
我在使用 IntelliJ 2018 时遇到了同样的问题。
最初,请确保您已在 IntelliJ 中为 spring 项目添加 Maven 库。
我的解决方案是:
转到 Run
-> Edit Configurations
。
Select Application
&& 选择你当前的项目。
检查Include dependencies with "Provided" scope
。
OK
-> RUN
按照以下步骤操作:
在 intellij window 的右上角,单击下拉菜单和 select 编辑配置,然后将打开一个新的 window。
在此 window 中,单击左上角的“+”按钮和 select 冲刺启动。
然后添加你的main class,其他细节如截图所示。
现在运行申请。
我有一个 spring-boot 应用程序需要:
- 可作为 war 部署在 servlet 容器中
- 运行可通过`mvn spring-boot:运行``
我还希望能够通过右键单击 main
在我的 IDE(Eclipse 或 IntelliJ IDE社区)中 运行 这个应用程序并 运行宁它。
以下是我的 pom.xml 中有趣的部分(请注意,我没有继承自 spring-boot-starter-parent pom):
...
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
...
<build>
<plugins>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring.boot.version}</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
这是我的 SpringBootServletInitializer
:
@Configuration
@EnableAutoConfiguration
@ComponentScan("com.company.theproject")
public class Application extends SpringBootServletInitializer
{
private static final Logger logger = LoggerFactory.getLogger(Application.class);
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application)
{
return application.sources(Application.class);
}
public static void main(String[] args)
{
SpringApplication.run(Application.class, args);
}
}
当 运行 在 IDE 中设置主函数时,我得到以下错误:
org.springframework.context.ApplicationContextException: Unable to start EmbeddedWebApplicationContext due to missing EmbeddedServletContainerFactory bean.
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.getEmbeddedServletContainerFactory(EmbeddedWebApplicationContext.java:183) ~[spring-boot-1.2.3.RELEASE.jar:1.2.3.RELEASE]
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.createEmbeddedServletContainer(EmbeddedWebApplicationContext.java:156) ~[spring-boot-1.2.3.RELEASE.jar:1.2.3.RELEASE]
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.onRefresh(EmbeddedWebApplicationContext.java:130) ~[spring-boot-1.2.3.RELEASE.jar:1.2.3.RELEASE]
... 12 common frames omitted
似乎 mvn spring-boot:run
做了一些在 运行 直接 main
时不会发生的魔法。
从 spring-boot-starter-tomcat
依赖项中删除 provided
作用域修复了这个问题,但当 war 在 servlet 容器中是 运行 时会造成问题。
目前我发现的唯一 "fix" 是在 IntelliJ IDEA 中 运行 mvn spring-boot:run
而不是直接 运行ning main。虽然这是一个可以接受的解决方法,但我仍然想知道为什么它不起作用以及是否可以修复。
mvn spring-boot:run
在创建类路径时包含 provided
依赖项。听起来像 IntelliJ IDEA 没有。如果类路径中没有 Tomcat,Spring Boot 将无法创建嵌入式 servlet 容器,这会导致您看到的异常。可以说这是 IntelliJ 中的一个错误,因为如果没有容器提供依赖项,那么它确实需要在类路径中。
您可以通过覆盖 IntelliJ 在 运行 包含 spring-boot-starter-tomcat
依赖项的主要方法时使用的默认类路径来解决问题。
我认为这可能与 https://youtrack.jetbrains.com/issue/IDEA-107048
有关IntelliJ IDEA 没有将 provided
依赖项注入 CLASSPATH,正如 Andy 所说,这就是 spring 无法创建嵌入式 servlet 容器的原因。
他们自 2005 年以来就提出了关于此的功能请求:https://youtrack.jetbrains.com/issue/IDEABKL-99
评论中提到的解决方法包括拥有一个带有必要库的假模块并将其用作类路径,使用 -Xbootclasspath JVM 参数或使用自定义 maven 配置文件 运行 (compiled
) vs建筑物(provided
)。
受 https://youtrack.jetbrains.com/issue/IDEA-140041 强烈启发的解决方法是使用测试 class 路径(包括嵌入式 servlet。)启动主 class。
步骤(IntelliJ 16):
Run
->Edit Configurations
->Add new configuration
-> 选择Application
类型。- 将
Main class
设置为<your.main.class>
- 将
Use classpath of module
设置为<*>_test
(测试模块!) Ok
又Run
啦!
我找到这个 page,并使用 maven 配置文件来管理配置文件。
<profiles>
<profile>
<id>PROD</id>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
</profile>
<profile>
<id>DEV</id>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>TEST</scope>
</dependency>
</dependencies>
</profile>
</profiles>
并配置主要 class beforeLanuce
,设置命令
mvn clean compile -Pdev
我能够通过在项目结构->依赖项选项卡下将 spring-boot-starter-tomcat 依赖项的范围更改为 "compile" 来完成这项工作。这不会影响 pom.xml 但允许此依赖项可用于 spring 启动 运行 配置
Click here for image on where to change this setting in idea
我能够通过将提供的 libaray (spring-boot-starter-tomcat) 添加到项目配置来解决 Intellij IDEA 2017.2 中的这个问题。
Select 文件 -> 项目结构。 Select 库并添加一个新的项目库(type = From Maven...)。使用对话框搜索 spring-boot-starter-tomcat,select 正确的版本,然后单击确定添加它。该库已添加到外部库列表中。
缺点是如果 Spring 引导版本发生变化,那么您将不得不记得删除该库并添加新版本。
使用下面的配置文件和说明,您可以向 Maven 添加配置文件,允许在 IntelliJ 中进行开发,而无需针对其他环境进行更改。
<!-- Leave original dependency as-is -->
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
<profiles>
<!-- Enable this profile to run in IntelliJ. IntelliJ excludes provided dependencies from compile by default. -->
<profile>
<id>intellij</id>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>compile</scope>
</dependency>
</dependencies>
</profile>
</profiles>
点击IntelliJ右侧的Maven Projects按钮,在Profiles下,selectintellij
.
我在使用 IntelliJ 2018 时遇到了同样的问题。 最初,请确保您已在 IntelliJ 中为 spring 项目添加 Maven 库。
我的解决方案是:
转到
Run
->Edit Configurations
。Select
Application
&& 选择你当前的项目。检查
Include dependencies with "Provided" scope
。OK
->RUN
按照以下步骤操作:
在 intellij window 的右上角,单击下拉菜单和 select 编辑配置,然后将打开一个新的 window。
在此 window 中,单击左上角的“+”按钮和 select 冲刺启动。
然后添加你的main class,其他细节如截图所示。
现在运行申请。