将Spring Boot应用作为构件引入主应用时的配置与依赖加载问题
问题分析与解决方案
问题现象
将包含Spring MVC控制器、Thymeleaf视图的Spring Boot构件作为依赖引入主应用后,出现两个问题:
- 构件内的
application.properties配置未被主应用加载 - 构件pom.xml中声明的依赖未传递到主应用,导致IntelliJ中无法找到
org.thymeleaf.spring5.view.ThymeleafViewResolver类
构件现有配置
1. pom.xml
<groupId>com.example</groupId> <artifactId>dashboard</artifactId> <version>0.0.0</version> <packaging>jar</packaging> <name>projectname</name> <description>some desc</description> <properties> <java.version>1.8</java.version> </properties> <dependencies> <!-- Spring Boot Starter --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> <version>2.7.2</version> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>2.7.2</version> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> <version>2.7.2</version> <optional>true</optional> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>2.7.2</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> <version>2.7.2</version> </dependency> </dependencies> </dependencyManagement>
2. 配置类
package com.example; @ConditionalOnProperty(name = "app.dashboard.enabled", havingValue = "true", matchIfMissing = true) @Configuration public class DashboardConfiguration { // 添加视图解析器仅处理构件视图 @Bean public ClassLoaderTemplateResolver templateResolver() { ClassLoaderTemplateResolver templateResolver = new ClassLoaderTemplateResolver(); templateResolver.setPrefix("myfolder/templates/"); templateResolver.setSuffix(".html"); templateResolver.setTemplateMode(TemplateMode.HTML); templateResolver.setCharacterEncoding("UTF-8"); return templateResolver; } @Bean public SpringTemplateEngine templateEngine(ClassLoaderTemplateResolver templateResolver) { SpringTemplateEngine templateEngine = new SpringTemplateEngine(); templateEngine.setTemplateResolver(templateResolver); return templateEngine; } @Bean public ViewResolver thymeleafViewResolver(SpringTemplateEngine templateEngine) { ThymeleafViewResolver resolver = new ThymeleafViewResolver(); resolver.setTemplateEngine(templateEngine); resolver.setCharacterEncoding("UTF-8"); resolver.setOrder(Ordered.HIGHEST_PRECEDENCE); return resolver; } }
3. 资源结构(main/resources下)
myfolder/templates/:存放index.html、login.html等视图文件application.propertiesMETA-INF/spring.factories(已配置自动加载)
4. application.properties内容
app.dashboard.path=/convy app.dashboard.username=convy app.dashboard.password=vycon app.dashboard.enabled=true spring.thymeleaf.prefix=classpath:/convy/templates/ spring.thymeleaf.suffix=.html
解决方案
1. 解决依赖未传递问题
构件pom.xml中所有依赖都添加了<optional>true</optional>,这会阻止Maven将这些依赖传递给主应用。需移除该属性,让依赖自动传递:
<!-- 修改后的依赖示例 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>2.7.2</version> <!-- 移除optional=true --> </dependency>
2. 解决配置未加载问题
Spring Boot默认会扫描jar包内的application.properties,但为避免与主应用配置冲突,建议将构件配置文件重命名为application-dashboard.properties,然后在主应用的application.properties中激活该配置文件:
# 主应用配置中激活构件的配置文件 spring.profiles.include=dashboard
同时推荐使用@ConfigurationProperties绑定构件专属配置,增强配置可读性与类型安全:
@ConfigurationProperties(prefix = "app.dashboard") public class DashboardProperties { private String path = "/convy"; private String username = "convy"; private String password = "vycon"; private boolean enabled = true; // getter和setter方法 }
在配置类中引入该配置类:
@ConditionalOnProperty(name = "app.dashboard.enabled", havingValue = "true", matchIfMissing = true) @Configuration @EnableConfigurationProperties(DashboardProperties.class) public class DashboardConfiguration { // 可直接注入DashboardProperties使用配置 }
3. 满足版本优先需求
为让构件优先使用主应用的Spring Boot版本,需在构件pom.xml中导入Spring Boot的BOM(物料清单),而非硬编码版本号:
<dependencyManagement> <dependencies> <!-- 导入Spring Boot BOM --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>2.7.2</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
此时构件的依赖可不再指定版本,自动继承BOM或主应用的版本:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
最终效果
主应用引入构件后:
- 构件的依赖自动传递,Thymeleaf相关类可正常访问
- 构件的配置文件被加载,可通过
app.dashboard.*配置项控制构件行为 - Spring Boot版本自动对齐主应用,避免版本冲突
内容的提问来源于stack exchange,提问作者Mohamed Nabli
相关产品推荐
相关产品推荐

