SpringBoot应用启动失败:无法创建UserRegisterMapper Bean
问题描述
启动SpringBoot应用时抛出异常,提示com.placement.portal.repository.dao.UserRegisterDao中的userRegisterMapper字段需要com.placement.portal.repository.mapper.UserRegisterMapper类型的Bean,但未找到匹配的候选Bean。
报错日志
May 28, 2023 2:26:11 PM org.hibernate.dialect.Dialect <init> INFO: HHH000400: Using dialect: org.hibernate.dialect.MySQL8Dialect May 28, 2023 2:26:11 PM org.hibernate.engine.transaction.jta.platform.internal.JtaPlatformInitiator initiateService INFO: HHH000490: Using JtaPlatform implementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform] [main] INFO org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean - Initialized JPA EntityManagerFactory for persistence unit 'default' [main] WARN org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext - Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'userRegisterController': Unsatisfied dependency expressed through field 'restProcessor'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'restProcessor': Unsatisfied dependency expressed through field 'placementPortalCatalogue'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'placementPortalCatalogue': Unsatisfied dependency expressed through field 'userRegisterChain'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'userRegisterChain': Unsatisfied dependency expressed through field 'insertUserRegisterOrder'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'insertUserRegisterOrder': Unsatisfied dependency expressed through field 'userRegisterDao'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'userRegisterDao': Unsatisfied dependency expressed through field 'userRegisterMapper'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.placement.portal.repository.mapper.UserRegisterMapper' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)} [main] INFO org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean - Closing JPA EntityManagerFactory for persistence unit 'default' [main] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Shutdown initiated... [main] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Shutdown completed. May 28, 2023 2:26:11 PM org.apache.catalina.core.StandardService stopInternal INFO: Stopping service [Tomcat] [main] INFO org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListener - Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled. [main] ERROR org.springframework.boot.diagnostics.LoggingFailureAnalysisReporter - *************************** APPLICATION FAILED TO START *************************** Description: Field userRegisterMapper in com.placement.portal.repository.dao.UserRegisterDao required a bean of type 'com.placement.portal.repository.mapper.UserRegisterMapper' that could not be found.
相关代码片段
InsertUserRegisterOrder类
package com.placement.portal.service.commands; import com.placement.portal.common.ChainContext; import com.placement.portal.common.order.UserRegisterOrder; import com.placement.portal.repository.dao.UserRegisterDao; import lombok.extern.slf4j.Slf4j; import org.apache.commons.chain.Context; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @Component @Slf4j public class InsertUserRegisterOrder extends CommandWrapper{ @Autowired UserRegisterDao userRegisterDao; @Override public boolean execute(Context context) throws Exception { try { ChainContext chainContext = (ChainContext) context; UserRegisterOrder userRegisterOrder = chainContext.getUserRegisterOrder(); userRegisterDao.insertUserRegisterOrder(userRegisterOrder); return super.invokeTarget(context); } finally { } } }
启动类PlacementPortalStudentApplication
package com.placement.portal; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class PlacementPortalStudentApplication { public static void main(String[] args) { SpringApplication.run(PlacementPortalStudentApplication.class, args); } }
UserRegisterDao类
package com.placement.portal.repository.dao; import com.placement.portal.common.order.UserRegisterOrder; import com.placement.portal.repository.mapper.UserRegisterMapper; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Repository; import java.sql.SQLException; @Slf4j @Repository public class UserRegisterDao { @Autowired UserRegisterMapper userRegisterMapper; public void insertUserRegisterOrder(UserRegisterOrder userRegisterOrder) throws SQLException { if (null == userRegisterOrder){ log.error("User Register Order is null"); return; } userRegisterMapper.insertUserRegisterOrder(userRegisterOrder); } }
UserRegisterMapper接口
package com.placement.portal.repository.mapper; import com.placement.portal.common.order.UserRegisterOrder; import org.apache.ibatis.annotations.Insert; import org.apache.ibatis.annotations.Mapper; import java.sql.SQLException; @Mapper public interface UserRegisterMapper { @Insert("insert into user(user_id,request_id) values (#{userId},#{requestId}") void insertUserRegisterOrder(UserRegisterOrder userRegisterOrder) throws SQLException; }
Maven依赖配置(pom.xml)
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.5.5</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.amiya</groupId> <artifactId>placement-portal-student</artifactId> <version>1.0.0-SNAPSHOT</version> <name>Placement-Portal</name> <description>Placement Portal Student</description> <properties> <java.version>11</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-logging</artifactId> </dependency> <!-- Dependency for MySQL Database --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> <version>8.0.33</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> </dependency> <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 --> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.12.0</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>2.0.5</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-simple</artifactId> <version>2.0.5</version> </dependency> <dependency> <groupId>javax.xml.bind</groupId> <artifactId>jaxb-api</artifactId> <version>2.3.1</version> </dependency> <dependency> <groupId>commons-chain</groupId> <artifactId>commons-chain</artifactId> <version>1.2</version> </dependency> <!-- https://mvnrepository.com/artifact/org.mybatis.spring.boot/mybatis-spring-boot-starter --> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>3.0.1</version> </dependency> <!-- https://mvnrepository.com/artifact/org.apache.shardingsphere/sharding-jdbc-spring-boot-starter --> <dependency> <groupId>org.apache.shardingsphere</groupId> <artifactId>sharding-jdbc-spring-boot-starter</artifactId> <version>4.1.1</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> <version>6.0.9</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-jdbc --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> <version>3.1.0</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <excludes> <exclude> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </exclude> </excludes> </configuration> </plugin> </plugins> </build> </project>
解决方案
1. 修复MyBatis Spring Boot Starter版本兼容性问题
你的SpringBoot版本是2.5.5,而引入的MyBatis Spring Boot Starter是3.0.1——3.0.x版本的MyBatis Starter仅兼容SpringBoot 3.0及以上版本,和当前的SpringBoot 2.5.5完全不兼容,这会导致MyBatis的自动配置失效,无法将@Mapper注解的接口创建为Spring Bean。
修改pom.xml中的MyBatis依赖版本为兼容2.5.x SpringBoot的版本,比如2.2.2:
<dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.2.2</version> </dependency>
2. 确保Mapper接口被Spring扫描到
虽然Mapper接口加了@Mapper注解,且包路径com.placement.portal.repository.mapper在启动类com.placement.portal的扫描范围内,但可以显式添加@MapperScan注解到启动类,确保扫描生效:
package com.placement.portal; import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication @MapperScan("com.placement.portal.repository.mapper") public class PlacementPortalStudentApplication { public static void main(String[] args) { SpringApplication.run(PlacementPortalStudentApplication.class, args); } }
3. 修复SQL语句语法错误
UserRegisterMapper中的Insert语句缺少右括号,会导致后续执行SQL时抛出异常,修正为:
@Insert("insert into user(user_id,request_id) values (#{userId},#{requestId})") void insertUserRegisterOrder(UserRegisterOrder userRegisterOrder) throws SQLException;
4. 清理依赖冲突
你同时引入了spring-boot-starter-data-jpa、spring-boot-starter-jdbc和MyBatis,三者都是持久层框架,可能存在依赖冲突。如果使用MyBatis作为主要持久层,可以考虑移除JPA依赖,避免不必要的冲突。
内容的提问来源于stack exchange,提问作者Shubham Singh

