Invalid value type for attribute ‘factoryBeanObjectType‘: java.lang.String 的解决办法

2024-12-29 0 580

问题概述

关于这个问题,博主是在跑单元测试的时候遇到的,本篇文章可能较长,如果只想解决问题本身,可只关注结果,跳过过程!

环境:

spring-boot 3.2.1
jdk 17

报错:“ Caused by: java.lang.IllegalArgumentException: Invalid value type for attribute 'factoryBeanObjectType': java.lang.String

莫名的参数类型错误,

如下图:

Invalid value type for attribute ‘factoryBeanObjectType‘: java.lang.String 的解决办法

具体信息如下:

java.lang.IllegalStateException: Failed to load ApplicationContext for [WebMergedContextConfiguration@4b74b35 testClass = ...ApplicationTests, locations = [], classes = [com...Application], contextInitializerClasses = [], activeProfiles = [], propertySourceDescriptors = [], propertySourceProperties = ["org.springframework.boot.test.context.SpringBootTestContextBootstrapper=true"], contextCustomizers = [org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer@7bd4937b, org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer@741a8937, org.springframework.boot.test.mock.mockito.MockitoContextCustomizer@0, org.springframework.boot.test.web.client.TestRestTemplateContextCustomizer@2ea41516, org.springframework.boot.test.autoconfigure.actuate.observability.ObservabilityContextCustomizerFactory$DisableObservabilityContextCustomizer@1f, org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer@0, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizer@4b0d79fc, org.springframework.boot.test.context.SpringBootTestAnnotation@4a86e4f0], resourceBasePath = "src/main/webapp", contextLoader = org.springframework.boot.test.context.SpringBootContextLoader, parent = null]

	at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:180)
	at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:130)
	at org.springframework.test.context.web.ServletTestExecutionListener.setUpRequestContextIfNecessary(ServletTestExecutionListener.java:191)
	at org.springframework.test.context.web.ServletTestExecutionListener.prepareTestInstance(ServletTestExecutionListener.java:130)
	at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:260)
	at org.springframework.test.context.junit.jupiter.SpringExtension.postProcessTestInstance(SpringExtension.java:163)
	at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
	at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:179)
	at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1625)
	at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509)
	at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
	at java.base/java.util.stream.StreamSpliterators$WrappingSpliterator.forEachRemaining(StreamSpliterators.java:310)
	at java.base/java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:735)
	at java.base/java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:734)
	at java.base/java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:762)
	at java.base/java.util.Optional.orElseGet(Optional.java:364)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
Caused by: java.lang.IllegalArgumentException: Invalid value type for attribute 'factoryBeanObjectType': java.lang.String
	at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.getTypeForFactoryBeanFromAttributes(FactoryBeanRegistrySupport.java:86)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.getTypeForFactoryBean(AbstractAutowireCapableBeanFactory.java:836)
	at org.springframework.beans.factory.support.AbstractBeanFactory.isTypeMatch(AbstractBeanFactory.java:620)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.doGetBeanNamesForType(DefaultListableBeanFactory.java:575)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanNamesForType(DefaultListableBeanFactory.java:534)
	at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:138)
	at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:789)
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:606)
	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:762)
	at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:464)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:334)
	at org.springframework.boot.test.context.SpringBootContextLoader.lambda$loadContext$3(SpringBootContextLoader.java:137)
	at org.springframework.util.function.ThrowingSupplier.get(ThrowingSupplier.java:58)
	at org.springframework.util.function.ThrowingSupplier.get(ThrowingSupplier.java:46)
	at org.springframework.boot.SpringApplication.withHook(SpringApplication.java:1458)
	at org.springframework.boot.test.context.SpringBootContextLoader$ContextLoaderHook.run(SpringBootContextLoader.java:552)
	at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:137)
	at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:108)
	at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:225)
	at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:152)
	... 17 more


Process finished with exit code -1

解决办法

根据错误信息,参数类型错误

参考【mybatis-spring-issues 855】得知:

在 Spring Boot 3.0后的 版本中FactoryBeanRegistrySupport#getTypeForFactoryBeanFromAttributes方法已变更,如果 factoryBeanObjectType 不是 ResolvableType 或 Class 类型会抛出 IllegalArgumentException 异常。

此时因为 factoryBeanObjectType 是 String 类型,不符合条件而抛出异常。

如下图:

Invalid value type for attribute ‘factoryBeanObjectType‘: java.lang.String 的解决办法

项目中使用的 mybatis-plus-boot-starter 是当前最新版本 3.5.5,但 mybatis-spring 为2.1.2 

如下图:

Invalid value type for attribute ‘factoryBeanObjectType‘: java.lang.String 的解决办法

但版本已不兼容,

兼容对照表:

MyBatis-Spring-Boot-Starter、MyBatis-Spring、Spring Boot、Java 版本兼容对照如下表:

Invalid value type for attribute ‘factoryBeanObjectType‘: java.lang.String 的解决办法

好了,问题分析清楚了,

可以解决问题了,

第一步:排除 mybatis-plus-boot-starter 中的旧版本 mybatis-spring

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

第二步:引入 mybatis-spring 3.0.3 版本

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

完整内容:

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

第三步:测试

再次跑单元测试,就成功执行了,如下图:

Invalid value type for attribute ‘factoryBeanObjectType‘: java.lang.String 的解决办法

源码扩展,可忽略:

Springboot Version 3.2.0-M2,spring-boot-starter 3.0.2 在这个版本中,FactoryBeanRegistrySupport.getTypeForFactoryBeanFromAttributes()方法已经改变,当“factoryBeanObjectType”不是ResolvableType或者Class类型时抛出一个IllegalArgumentException,

如下图:

Invalid value type for attribute ‘factoryBeanObjectType‘: java.lang.String 的解决办法

org.springframework.beans.factory.support.FactoryBeanRegistrySupport.getTypeForFactoryBeanFromAttributes

通过检查FactoryBean的属性来确定FactoryBean的bean类型
从ResolvableType中提取属性或者ResolvableType.NONE,
很遗憾,从ResolvableType中未找到FactoryBean的属性或者ResolvableType.NONE,

但是在 org.mybatis.spring.mapper.ClassPathMapperScanner.processBeanDefinitions()方法(第254行)设置一了个字符串类型beanClassName,

如下图:

Invalid value type for attribute ‘factoryBeanObjectType‘: java.lang.String 的解决办法

在 mybatis-spring-3.0.3 通过反射创建一个Class类:

      String beanClassName = definition.getBeanClassName();
      LOGGER.debug(() -> "Creating MapperFactoryBean with name '" + holder.getBeanName() + "' and '" + beanClassName
          + "' mapperInterface");

      // the mapper interface is the original class of the bean
      // but, the actual class of the bean is MapperFactoryBean
      definition.getConstructorArgumentValues().addGenericArgumentValue(beanClassName); // issue #59
      try {
        Class<?> beanClass = Resources.classForName(beanClassName);
        // Attribute for MockitoPostProcessor
        // https://github.com/mybatis/spring-boot-starter/issues/475
        definition.setAttribute(FACTORY_BEAN_OBJECT_TYPE, beanClass);
        // for spring-native
        definition.getPropertyValues().add("mapperInterface", beanClass);
      } catch (ClassNotFoundException ignore) {
        // ignore
      }

如下图:

Invalid value type for attribute ‘factoryBeanObjectType‘: java.lang.String 的解决办法

 到这里,就可以成功识别到Class类型了:

Invalid value type for attribute ‘factoryBeanObjectType‘: java.lang.String 的解决办法

自此,问题就解决了,项目的单元测试模块跑通了,如下图:

Invalid value type for attribute ‘factoryBeanObjectType‘: java.lang.String 的解决办法

其它补充:


好了,关于 Invalid value type for attribute ‘factoryBeanObjectType‘: java.lang.String 的解决办法  就写到这儿了,如果还有什么疑问或遇到什么问题欢迎扫码提问,也可以给我留言哦,我会一一详细的解答的。 
歇后语:“ 共同学习,共同进步 ”,也希望大家多多关注CSND的IT社区。


作       者: 华    仔
联系作者: who.seek.me@java98k.vip
来        源: CSDN (Chinese Software Developer Network)
原        文: https://blog.csdn.net/Hello_World_QWP/article/details/135771075
版权声明: 本文为博主原创文章,请在转载时务必注明博文出处!

平台声明:以上文章转载于《CSDN》,文章全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,仅作参考。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

原文链接:https://blog.csdn.net/Hello_World_QWP/article/details/135771075

遇见资源网 JAVA Invalid value type for attribute ‘factoryBeanObjectType‘: java.lang.String 的解决办法 http://www.ox520.com/157560.html

常见问题

相关文章

发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务