Skip to content

spring boot3.2集成mybatis-plus踩坑日记

引入依赖

xml
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.5.4.1</version>
</dependency>

通常引入mybatis-plus的以来后就不需要引入mybatis的依赖的,但是在spring boot3.2中引入mybatis-plus后会有一系列问题。

相关问题

项目启动报:

java.lang.IllegalArgumentException: Invalid value type for attribute 'factoryBeanObjectType': java.lang.String

text
java.lang.IllegalArgumentException: Invalid value type for attribute 'factoryBeanObjectType': java.lang.String
        at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.getTypeForFactoryBeanFromAttributes(FactoryBeanRegistrySupport.java:86) ~[spring-beans-6.1.1.jar:6.1.1]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.getTypeForFactoryBean(AbstractAutowireCapableBeanFactory.java:838) ~[spring-beans-6.1.1.jar:6.1.1]
        at org.springframework.beans.factory.support.AbstractBeanFactory.isTypeMatch(AbstractBeanFactory.java:620) ~[spring-beans-6.1.1.jar:6.1.1]
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.doGetBeanNamesForType(DefaultListableBeanFactory.java:573) ~[spring-beans-6.1.1.jar:6.1.1]
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanNamesForType(DefaultListableBeanFactory.java:532) ~[spring-beans-6.1.1.jar:6.1.1]
        at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:138) ~[spring-context-6.1.1.jar:6.1.1]
        at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:775) ~[spring-context-6.1.1.jar:6.1.1]
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:597) ~[spring-context-6.1.1.jar:6.1.1]
        at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146) ~[spring-boot-3.2.0.jar:3.2.0]
        at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:753) ~[spring-boot-3.2.0.jar:3.2.0]
        at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:455) ~[spring-boot-3.2.0.jar:3.2.0]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:323) ~[spring-boot-3.2.0.jar:3.2.0]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1342) ~[spring-boot-3.2.0.jar:3.2.0]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1331) ~[spring-boot-3.2.0.jar:3.2.0]
        at com.lautrans.LautransApiApplication.main(LautransApiApplication.java:13) ~[classes/:na]

查找问题

通过查看错误日志我们可以看到是在FactoryBeanRegistrySupport类中抛出的异常进入源码可以看到以下信息

java
ResolvableType getTypeForFactoryBeanFromAttributes(AttributeAccessor attributes) {
    Object attribute = attributes.getAttribute(FactoryBean.OBJECT_TYPE_ATTRIBUTE);
    if (attribute == null) {
        return ResolvableType.NONE;
    }
    if (attribute instanceof ResolvableType resolvableType) {
        return resolvableType;
    }
    if (attribute instanceof Class<?> clazz) {
        return ResolvableType.forClass(clazz);
    }
    throw new IllegalArgumentException("Invalid value type for attribute '" +
            FactoryBean.OBJECT_TYPE_ATTRIBUTE + "': " + attribute.getClass().getName());
}

在异常抛出处打断点debug

java
throw new IllegalArgumentException("Invalid value type for attribute '" +
				FactoryBean.OBJECT_TYPE_ATTRIBUTE + "': " + attribute.getClass().getName());

查看到是

解决问题

由于我们只引入了mybatis-plus-boot-starter的依赖所以通过查看mybatis-plus依赖解析可以看到传递过来的mybatis是2.1.1版本的。

而mybatis2.1.1是不兼容spring boot3.2的因此可以判断是mybatis-plus中mybatis依赖问题 所以可以将mybatis-plus中的mybatis排除并引入mybatis3.0.3的依赖。如下:

xml
<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>3.0.3</version>
</dependency>

<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.5.4.1</version>
    <exclusions>
        <exclusion>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
        </exclusion>
    </exclusions>
</dependency>

最终依赖解析如下:

大功告成

生成器流程和原理

MyBatis-Plus 代码生成器的本质是读取数据库表结构,根据模板生成 Entity、Mapper、Service、Controller 等文件。

mermaid
flowchart TD
    A["读取数据库表结构"] --> B["生成元数据"]
    B --> C["套用模板"]
    C --> D["输出 Java / XML 文件"]
    D --> E["开发者二次调整"]

为什么不能把生成代码当最终设计:生成器只能根据表结构猜测代码结构,不知道业务边界、事务边界、DTO、权限和校验规则。如果直接上线,容易出现 Controller 过度暴露、Entity 直接返回接口、Service 只有空壳等问题。

Demo 建议

生成后至少检查:

  1. Entity 是否需要脱敏字段。
  2. Controller 是否应该返回 DTO。
  3. Service 是否补充事务和业务校验。
  4. Mapper XML 是否需要补充复杂查询。
  5. 生成文件是否覆盖了手写代码。