Spring Boot+Gradle构建JAR运行失败:Bean定义缺失异常排查
问题:Spring Boot + Gradle项目打包JAR后无法找到Repository Bean
我有一个基于Spring Boot和Gradle开发的API项目,IDE中运行正常,但编译构建为JAR包后无法运行,抛出如下错误:
补充说明:项目采用多租户架构,使用Lombok简化代码。
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'edu.uoc.dslab.api.infrastructure.jpa.SpringDataUsuariRepository' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {} at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1812) at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1371) at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1325) at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:885) at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:789) ... 60 common frames omitted
部分代码展示
build.gradle
plugins { id 'java' id 'org.springframework.boot' version '3.0.2' id 'io.spring.dependency-management' version '1.1.0' } group = 'edu.uoc.dslab' version = '0.0.1-SNAPSHOT' repositories { mavenCentral() } dependencies { implementation 'mysql:mysql-connector-java:8.0.32' implementation 'org.springframework.boot:spring-boot-starter-data-jpa' implementation 'org.springframework.boot:spring-boot-starter-oauth2-resource-server' implementation 'org.springframework.boot:spring-boot-starter-security' implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'commons-io:commons-io:2.11.0' implementation 'org.apache.httpcomponents:httpcore:4.4.15' implementation 'org.apache.httpcomponents:httpclient:4.5.14' implementation 'org.apache.httpcomponents:httpmime:4.5.14' implementation(group: 'org.dom4j', name: 'dom4j', version: "2.1.4") { exclude group: "pull-parser", module: "pull-parser" } developmentOnly 'org.springframework.boot:spring-boot-devtools' testImplementation 'org.springframework.boot:spring-boot-starter-test' testImplementation 'org.springframework.security:spring-security-test' } tasks.named('test') { useJUnitPlatform() } jar { manifest { attributes( 'Main-Class': 'edu.uoc.dslab.api.DSLabApiApplication' ) } from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } } }
启动类
@SpringBootApplication @ComponentScan(excludeFilters={@ComponentScan.Filter(type= FilterType.ASSIGNABLE_TYPE, value={DataSourceAutoConfiguration.class})}) public class DSLabApiApplication { public static void main(String[] args) { SpringApplication.run(DSLabApiApplication.class, args); } }
API Controller
@RequiredArgsConstructor(onConstructor = @__(@Autowired)) @RestController @Transactional @RequestMapping("/endpoint") public class APIController { private final PermissosService permissosService; private final ProjecteService projecteService;
Service实现类
@RequiredArgsConstructor(onConstructor = @__(@Autowired)) @Service public class PermissosServiceImpl implements PermissosService { private final UsuariService usuariService;
Entity类
@Entity @Getter @Setter @EqualsAndHashCode @Builder @NoArgsConstructor @AllArgsConstructor @Table(name = "user") public class User { @Id @Column(name = "id") @GeneratedValue(strategy = GenerationType.AUTO) private Long id;
Repository接口
@Repository public interface SpringDataUsuariRepository extends JpaRepository<User, Long> { }
解决方案
核心原因
自定义的jar任务不符合Spring Boot可执行JAR的打包规范,它只是简单打包了项目代码和依赖,没有正确处理Spring Boot的自动配置、Bean扫描逻辑,导致JPA Repository这类需要Spring动态代理生成的Bean无法被初始化。
修复步骤
移除自定义的
jar任务配置
删除build.gradle中以下代码块:jar { manifest { attributes( 'Main-Class': 'edu.uoc.dslab.api.DSLabApiApplication' ) } from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } } }使用Spring Boot官方的
bootJar任务构建可执行JAR
执行以下Gradle命令构建JAR:./gradlew bootJar构建完成后,可执行JAR位于
build/libs目录下,运行命令:java -jar build/libs/DSLabApi-0.0.1-SNAPSHOT.jar补充Lombok依赖(关键遗漏)
当前build.gradle中未添加Lombok依赖,IDE可能通过插件支持,但打包时必须显式添加,否则Lombok注解无法生效:dependencies { // 原有依赖... compileOnly 'org.projectlombok:lombok:1.18.28' annotationProcessor 'org.projectlombok:lombok:1.18.28' testCompileOnly 'org.projectlombok:lombok:1.18.28' testAnnotationProcessor 'org.projectlombok:lombok:1.18.28' }可选:确认Bean扫描范围
启动类DSLabApiApplication位于edu.uoc.dslab.api,Repository在edu.uoc.dslab.api.infrastructure.jpa(子包),默认@SpringBootApplication会扫描启动类所在包及子包,所以无需额外配置。如果Repository在其他包,需在启动类添加:@EnableJpaRepositories(basePackages = "edu.uoc.dslab.api.infrastructure.jpa")
内容的提问来源于stack exchange,提问作者Devid
相关产品推荐
相关产品推荐

