spring项目的 WebApplicationContext 初始化两次的解决方法

本文介绍了解决Eclipse中因.settings/org.eclipse.wst.common.component文件设置不一致导致的双初始化问题。通过修改该文件中不一致的设置,可以有效避免应用程序在短时间内重复初始化的情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

wKiom1d1-c7jPgslAAGfIef-ARY014.png-wh_50

从图中可以看到Initializing Spring root WebApplicationContext两次初始化之间仅仅相隔了 5秒钟

问题的原因是.settings/org.eclipse.wst.common.component中两处不一致导致的,见下图红框,将两处都改为bi问题解决。

wKioL1d1-oLSoSypAADYkhHh4iU196.png-wh_50

修改后:

wKiom1d1-3OiCWGXAAClhuNzXG8476.png-wh_50













本文转自lzf0530377451CTO博客,原文链接:http://blog.51cto.com/8757576/1794896 ,如需转载请自行联系原作者








<think>我们正在处理一个关于Spring Boot项目启动方式转换的问题。用户希望将原本使用Tomcat插件启动的Spring项目(可能是通过Maven的tomcat7:run等插件)改为通过main方法直接启动。 根据引用内容,我们知道Spring Boot应用程序通常有一个主类(启动类),这个类包含main方法并调用`SpringApplication.run()`。因此,我们需要确保项目具有这样的主类,并且配置正确。 步骤: 1. 确保项目是一个Spring Boot项目,并且已经正确配置了Spring Boot的依赖(如spring-boot-starter-web)。 2. 创建一个主类(如果还没有的话),该类使用`@SpringBootApplication`注解,并包含main方法,在main方法中调用`SpringApplication.run`。 3. 如果之前是通过Maven的Tomcat插件(如tomcat7-maven-plugin)启动的,那么需要移除该插件,因为我们将使用内嵌的Tomcat(由Spring Boot管理)来启动。 4. 修改项目的打包方式(如果需要的话)。如果之前是war包部署到外部Tomcat,现在要改为直接运行main方法,则可能需要将打包方式改为jar(因为内嵌服务器通常使用jar包运行)。但注意,我们这里只是改变启动方式,并不一定需要改变打包方式,因为即使打包成war,也可以包含内嵌服务器并通过main方法启动(Spring Boot支持)。不过,对于简单的直接启动,我们通常使用jar。 但是,根据用户描述,他们之前可能是通过Maven的Tomcat插件(如tomcat7:run)来启动的,这通常用于非Spring Boot的传统的Spring MVC项目。因此,我们需要将项目转换为Spring Boot项目。 具体步骤: 1. 添加Spring Boot依赖: 在pom.xml中添加Spring Boot父项目(或者使用dependencyManagement)和starter-web依赖。 例如: ```xml <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.7.0</version> <!-- 使用合适的版本 --> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies> ``` 2. 创建主类: 在源代码的根包下(或其他包,但通常推荐根包)创建一个主类,例如: ```java import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } ``` 3. 移除外部的Tomcat插件: 在pom.xml中,移除之前用于启动的Tomcat插件,例如: ```xml <plugin> <groupId>org.apache.tomcat.maven</groupId> <artifactId>tomcat7-maven-plugin</artifactId> <version>2.2</version> </plugin> ``` 4. 如果之前项目是打包成war并部署到外部Tomcat,那么现在要改为内嵌Tomcat启动,需要: - 确保打包方式为jar(或者war,但由Spring Boot内嵌Tomcat运行,此时不需要外部Tomcat)。如果只是本地运行,打包方式可以不用改,因为运行main方法不依赖于打包。 - 移除对spring-boot-starter-tomcat的provided scope(如果有的话),因为内嵌运行需要包含它。 通常,如果只是为了通过main方法运行,我们不需要改变打包方式,可以直接运行主类。 5. 运行:现在可以直接运行主类的main方法,启动内嵌的Tomcat。 注意:如果项目之前是传统的Spring MVC项目(非Spring Boot),那么可能还需要进行一些配置的调整,比如将web.xml中的配置转换为Spring Boot的配置方式(使用@Configuration类)。 引用[1]中提到:如果代码中有两个类都调用了`SpringApplication.run()`,那么应用程序可能会启动两次。因此,确保只有一个主类(只有一个main方法调用`SpringApplication.run`)。 引用[2]和[3]提到了如何将Spring Boot项目部署到外部Tomcat(即打包成war并部署),但我们现在要做的是相反的事情:从外部Tomcat部署改为内嵌服务器启动。因此,我们不需要按照那些步骤,而是需要确保内嵌服务器被包含并正确启动。 引用[4]提到使用外置Tomcat启动,但用户希望的是直接通过main方法启动(使用内嵌服务器),所以我们不需要外置Tomcat。 总结:核心是添加Spring Boot依赖,创建主类,移除外部Tomcat插件,然后运行主类。 如果项目已经是Spring Boot项目,只是之前一直使用插件启动,那么只需要移除插件,然后直接运行主类即可。 但是,如果用户的项目原本不是Spring Boot项目,那么转换过程可能涉及更多配置的调整,比如将XML配置改为Java配置等。由于问题中没有说明项目原本的结构,我们假设它是一个可以转换为Spring Boot的项目。 因此,我们给出上述步骤。</think>### 如何将 Spring 项目从 Tomcat 插件启动改为 Main 方法启动 要将原本使用 Tomcat Maven 插件启动的 Spring 项目改为通过 `main` 方法直接启动,需遵循以下步骤: #### 1. **添加 Spring Boot 依赖** 在 `pom.xml` 中引入 Spring Boot 启动器和内嵌 Tomcat 依赖: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>3.1.0</version> <!-- 按需调整版本 --> </dependency> ``` #### 2. **创建 Spring Boot 主类** 在项目根包下创建主类,继承 `SpringBootServletInitializer` 并实现 `main` 方法: ```java import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; @SpringBootApplication public class Application extends SpringBootServletInitializer { @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) { return builder.sources(Application.class); } public static void main(String[] args) { SpringApplication.run(Application.class, args); // 直接启动内嵌Tomcat } } ``` - `@SpringBootApplication` 注解启用自动配置 - `main` 方法通过 `SpringApplication.run()` 启动内嵌服务器[^1] #### 3. **移除外部 Tomcat 插件** 删除 `pom.xml` 中的 Tomcat Maven 插件配置(如 `tomcat7-maven-plugin`): ```xml <!-- 删除此插件配置 --> <plugin> <groupId>org.apache.tomcat.maven</groupId> <artifactId>tomcat7-maven-plugin</artifactId> <version>2.2</version> </plugin> ``` #### 4. **修改打包方式(可选)** 如果项目需打包为可执行 JAR,将打包方式改为 `jar`: ```xml <packaging>jar</packaging> ``` 若需保留 WAR 包但通过 `main` 方法启动,保持 `war` 打包但确保内嵌 Tomcat 在类路径中[^3]。 #### 5. **验证启动** 运行主类的 `main` 方法,控制台将输出 Spring Boot 启动日志: ``` Tomcat initialized with port(s): 8080 (http) Starting embedded Tomcat server Initializing Spring embedded WebApplicationContext ``` ### 关键修改说明 | **原配置** | **修改后配置** | 作用 | |--------------------------|-----------------------------|----------------------------------------------------------------------| | Tomcat Maven 插件 | 移除插件 | 避免外部 Tomcat 启动 | | 无主类 | 添加 `@SpringBootApplication` 主类 | 提供 Spring Boot 入口点[^1] | | 外部服务器依赖 | `spring-boot-starter-web` | 引入内嵌 Tomcat 和 Spring MVC 支持 | | `mvn tomcat7:run` 命令 | 直接运行主类的 `main` 方法 | 通过内嵌服务器启动应用 | > **注意**:若项目中有多个 `SpringApplication.run()` 调用,需确保只有一个主类,否则会导致重复启动[^1]。 ### 常见问题解决 - **端口冲突**:在 `application.properties` 中配置 `server.port=新端口` - **依赖冲突**:检查是否遗留 `provided` 作用域的 Tomcat 依赖(应移除或改为 `compile`) - **静态资源加载**:将资源文件移至 `src/main/resources/static` 通过以上步骤,项目即可从插件启动转为标准的 Spring Boot 启动方式,简化开发部署流程[^4]。 --- ### 相关问题 1. Spring Boot 内嵌 Tomcat 与外部 Tomcat 在性能上有何差异? 2. 如何为 Spring Boot 应用配置 HTTPS 支持? 3. 在微服务架构中,直接启动与容器化部署该如何选择? 4. 如何监控 Spring Boot 内嵌 Tomcat 的运行指标? [^1]: 主类通过 `SpringApplication.run()` 初始化应用上下文并启动内嵌服务器 [^2]: Spring Boot 自动配置机制会根据类路径依赖加载内嵌容器 [^3]: WAR 包需包含 `SpringBootServletInitializer` 以支持外部容器部署 [^4]: 使用内嵌服务器可保持开发/生产环境一致性
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值