【问题标题】:Error: for property 'guitarist': no matching editors or conversion strategy found错误:对于属性“吉他手”:找不到匹配的编辑器或转换策略
【发布时间】:2021-09-05 18:50:06
【问题描述】:

This is the example I'm working on

问题是我从这段代码中得到错误,例如:

线程“main”中的异常 org.springframework.beans.factory.BeanCreationException:在类路径资源中定义名称为“documentaristOne”的 bean 创建时出错 .... 对于属性“guitarist”:找不到匹配的编辑器或转换策略 在 org.springframework.beans.factory.support...

界面:

public interface Singer {
    public void sing();    
}

类:

public class GrammyGuitarist implements Singer{

@Override
public void sing() {

    System.out.println("sing: Gravity is working against me\n" +
            "And gravity wants to bring me down");
}

public void sing(Guitar guitar) {
    System.out.println("play: " + guitar.play());
}

public void talk(){
    System.out.println("talk");
}

}
public class Documentarist {

protected GrammyGuitarist guitarist;

public void execute() {
    guitarist.sing();
    guitarist.talk();
}

public void setGuitarist(GrammyGuitarist guitarist) {
    this.guitarist = guitarist;
}
}
public class ProxyFactoryBeanDemo {
public static void main(String... args) {
    GenericXmlApplicationContext ctx = new GenericXmlApplicationContext();
    ctx.load("spring/app-context-xml.xml");
    ctx.refresh();

    Documentarist documentaristOne = ctx.getBean("documentaristOne", Documentarist.class);
    Documentarist documentaristTwo = ctx.getBean("documentaristTwo", Documentarist.class);

    System.out.println("Documentarist One >>");
    documentaristOne.execute();

    System.out.println("\nDocumentarist Two >> ");
    documentaristTwo.execute();
}
}

app-xml 文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:util="http://www.springframework.org/schema/util"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/util
        http://www.springframework.org/schema/util/spring-util.xsd">

    <bean id="johnMayer" class="com.apress.prospring5.ch5.GrammyGuitarist"/>
    <bean id="advice" class="com.apress.prospring5.ch5.AuditAdvice"/>

    <bean id="documentaristOne" class="com.apress.prospring5.ch5.Documentarist"
          p:guitarist-ref="proxyOne"/>

    <bean id="proxyOne" class="org.springframework.aop.framework.ProxyFactoryBean"
          p:target-ref="johnMayer" p:interceptorNames-ref="interceptorAdviceNames"/>

    <util:list id="interceptorAdviceNames">
        <value>advice</value>
    </util:list>


    <bean id="documentaristTwo" class="com.apress.prospring5.ch5.Documentarist"
          p:guitarist-ref="proxyTwo"/>

    <bean id="proxyTwo" class="org.springframework.aop.framework.ProxyFactoryBean"
          p:target-ref="johnMayer" p:interceptorNames-ref="interceptorAdvisorNames">
    </bean>

    <util:list id="interceptorAdvisorNames">
        <value>advisor</value>
    </util:list>

    <bean id="advisor" class="org.springframework.aop.support.DefaultPointcutAdvisor"
          p:advice-ref="advice">
        <property name="pointcut">
            <bean class="org.springframework.aop.aspectj.AspectJExpressionPointcut"
                  p:expression="execution(* sing*(..))"/>
        </property>
    </bean>

</beans>

正如我所见,问题在于尝试初始化 GenericXmlApplicationContext 在 app-xml 中的行:

<bean id="documentaristOne" class="com.apress.prospring5.ch5.Documentarist"
      p:guitarist-ref="proxyOne"/>

尝试创建 DocumentaristdocumentaristOne 实例,但对于属性 guitarist 我们不提供 GrammyGuitarist 的 bean 实例> 而是一个代理。是的,proxyOne 通过“johnMayer”引用了 GrammyGuitarist

<bean id="proxyOne" class="org.springframework.aop.framework.ProxyFactoryBean"
      p:target-ref="johnMayer" p:interceptorNames-ref="interceptorAdviceNames"/>

但正如我所见,JAVA/Spring 不想接受它。是否有可能以某种方式将类型代理转换为目标类型?如果没有,那要怎么做才能使这段代码正常工作?

下面的完整堆栈:

 org.springframework.context.support.AbstractApplicationContext refresh
WARNING: Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'documentaristOne' defined in class path resource [ch5/ProxyFactoryBeanDemo/app-context-xml.xml]: Initialization of bean failed; nested exception is org.springframework.beans.ConversionNotSupportedException: Failed to convert property value of type 'com.sun.proxy.$Proxy7 implementing ch5.ProxyFactoryBeanDemo.Singer,org.springframework.aop.SpringProxy,org.springframework.aop.framework.Advised,org.springframework.core.DecoratingProxy' to required type 'ch5.ProxyFactoryBeanDemo.GrammyGuitarist' for property 'guitarist'; nested exception is java.lang.IllegalStateException: Cannot convert value of type 'com.sun.proxy.$Proxy7 implementing ch5.ProxyFactoryBeanDemo.Singer,org.springframework.aop.SpringProxy,org.springframework.aop.framework.Advised,org.springframework.core.DecoratingProxy' to required type 'ch5.ProxyFactoryBeanDemo.GrammyGuitarist' for property 'guitarist': no matching editors or conversion strategy found
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'documentaristOne' defined in class path resource [ch5/ProxyFactoryBeanDemo/app-context-xml.xml]: Initialization of bean failed; nested exception is org.springframework.beans.ConversionNotSupportedException: Failed to convert property value of type 'com.sun.proxy.$Proxy7 implementing ch5.ProxyFactoryBeanDemo.Singer,org.springframework.aop.SpringProxy,org.springframework.aop.framework.Advised,org.springframework.core.DecoratingProxy' to required type 'ch5.ProxyFactoryBeanDemo.GrammyGuitarist' for property 'guitarist'; nested exception is java.lang.IllegalStateException: Cannot convert value of type 'com.sun.proxy.$Proxy7 implementing ch5.ProxyFactoryBeanDemo.Singer,org.springframework.aop.SpringProxy,org.springframework.aop.framework.Advised,org.springframework.core.DecoratingProxy' to required type 'ch5.ProxyFactoryBeanDemo.GrammyGuitarist' for property 'guitarist': no matching editors or conversion strategy found
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:603)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:517)
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:323)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:321)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:879)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:878)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:550)
    at ch5.ProxyFactoryBeanDemo.ProxyFactoryBeanDemo.main(ProxyFactoryBeanDemo.java:14)
Caused by: org.springframework.beans.ConversionNotSupportedException: Failed to convert property value of type 'com.sun.proxy.$Proxy7 implementing ch5.ProxyFactoryBeanDemo.Singer,org.springframework.aop.SpringProxy,org.springframework.aop.framework.Advised,org.springframework.core.DecoratingProxy' to required type 'ch5.ProxyFactoryBeanDemo.GrammyGuitarist' for property 'guitarist'; nested exception is java.lang.IllegalStateException: Cannot convert value of type 'com.sun.proxy.$Proxy7 implementing ch5.ProxyFactoryBeanDemo.Singer,org.springframework.aop.SpringProxy,org.springframework.aop.framework.Advised,org.springframework.core.DecoratingProxy' to required type 'ch5.ProxyFactoryBeanDemo.GrammyGuitarist' for property 'guitarist': no matching editors or conversion strategy found
    at org.springframework.beans.AbstractNestablePropertyAccessor.convertIfNecessary(AbstractNestablePropertyAccessor.java:590)
    at org.springframework.beans.AbstractNestablePropertyAccessor.convertForProperty(AbstractNestablePropertyAccessor.java:604)
    at org.springframework.beans.BeanWrapperImpl.convertForProperty(BeanWrapperImpl.java:219)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.convertForProperty(AbstractAutowireCapableBeanFactory.java:1748)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1704)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1444)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:594)
    ... 9 more
Caused by: java.lang.IllegalStateException: Cannot convert value of type 'com.sun.proxy.$Proxy7 implementing ch5.ProxyFactoryBeanDemo.Singer,org.springframework.aop.SpringProxy,org.springframework.aop.framework.Advised,org.springframework.core.DecoratingProxy' to required type 'ch5.ProxyFactoryBeanDemo.GrammyGuitarist' for property 'guitarist': no matching editors or conversion strategy found
    at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:262)
    at org.springframework.beans.AbstractNestablePropertyAccessor.convertIfNecessary(AbstractNestablePropertyAccessor.java:585)
    ... 15 more
Command execution failed.
org.apache.commons.exec.ExecuteException: Process exited with an error: 1 (Exit value: 1)
    at org.apache.commons.exec.DefaultExecutor.executeInternal (DefaultExecutor.java:404)
    at org.apache.commons.exec.DefaultExecutor.execute (DefaultExecutor.java:166)
    at org.codehaus.mojo.exec.ExecMojo.executeCommandLine (ExecMojo.java:764)
    at org.codehaus.mojo.exec.ExecMojo.executeCommandLine (ExecMojo.java:711)
    at org.codehaus.mojo.exec.ExecMojo.execute (ExecMojo.java:289)
    at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo (DefaultBuildPluginManager.java:137)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:210)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:156)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:148)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:117)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:81)
    at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build (SingleThreadedBuilder.java:56)
    at org.apache.maven.lifecycle.internal.LifecycleStarter.execute (LifecycleStarter.java:128)
    at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:305)
    at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:192)
    at org.apache.maven.DefaultMaven.execute (DefaultMaven.java:105)
    at org.apache.maven.cli.MavenCli.execute (MavenCli.java:957)
    at org.apache.maven.cli.MavenCli.doMain (MavenCli.java:289)
    at org.apache.maven.cli.MavenCli.main (MavenCli.java:193)
    at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0 (Native Method)
    at jdk.internal.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:64)
    at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke (Method.java:564)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced (Launcher.java:282)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launch (Launcher.java:225)
    at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode (Launcher.java:406)
    at org.codehaus.plexus.classworlds.launcher.Launcher.main (Launcher.java:347)

【问题讨论】:

  • 您能否发布完整的错误堆栈跟踪,而不是其中的一些...?
  • 我已经添加了完整的堆栈。可以看看吗?
  • 您还有一个接口Singer,在您发布的代码中没有使用,但是在您发布的Failed to convert property value of type 'com.sun.proxy.$Proxy7 implementing ch5.ProxyFactoryBeanDemo.Singer... 的堆栈跟踪中提到了它。您确定发布的代码是您要运行的代码吗?
  • GrammyGuitarist 实现了它。我编辑了,不知道为什么错过了。
  • 我克隆了示例存储库并运行了应用程序。它工作得很好。您必须更改某些内容才能破坏它。

标签: java spring aop


【解决方案1】:

根本原因是,如果目标类实现了接口,则 Spring Core(不是 Spring Boot)默认创建 JDK 代理。对于您尝试修改的 ProxyFactoryBean 示例也是如此。即,一旦您使GrammyGuitarist 实现Singer,您将不再获得CGLIB 代理而是JDK 代理。 JDK 代理不是GrammyGuitarist 的子类,这意味着它不能强制转换为该类,但代码和配置显式引用该类,而不仅仅是Singer。因此,

  • 要么你需要使bean类型Singer
  • 或者您将 Spring 配置为使用代理工厂 bean 在 &lt;beans&gt; 部分中使用 &lt;aop:aspectj-autoproxy proxy-target-class="true"/&gt; 和在两个 bean 配置中使用 p:proxyTargetClass="true" 创建 CGLIB 代理。

我正在向您展示如何更改XML configuration

这是差异:

diff --git a/chapter05/proxyfactorybean/src/main/java/com/apress/prospring5/ch5/GrammyGuitarist.java b/chapter05/proxyfactorybean/src/main/java/com/apress/prospring5/ch5/GrammyGuitarist.java
--- a/chapter05/proxyfactorybean/src/main/java/com/apress/prospring5/ch5/GrammyGuitarist.java   (revision Staged)
+++ b/chapter05/proxyfactorybean/src/main/java/com/apress/prospring5/ch5/GrammyGuitarist.java   (date 1630836290986)
@@ -1,11 +1,12 @@
 package com.apress.prospring5.ch5;
 
 import com.apress.prospring5.ch2.common.Guitar;
+import com.apress.prospring5.ch2.common.Singer;
 
 /**
  * Created by iuliana.cosmina on 4/9/17.
  */
-public class GrammyGuitarist {
+public class GrammyGuitarist implements Singer {
    public void sing() {
        System.out.println("sing: Gravity is working against me\n" +
                "And gravity wants to bring me down");
diff --git a/chapter05/proxyfactorybean/src/main/resources/spring/app-context-xml.xml b/chapter05/proxyfactorybean/src/main/resources/spring/app-context-xml.xml
--- a/chapter05/proxyfactorybean/src/main/resources/spring/app-context-xml.xml  (revision Staged)
+++ b/chapter05/proxyfactorybean/src/main/resources/spring/app-context-xml.xml  (date 1630838376150)
@@ -2,12 +2,17 @@
 
 <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xmlns:aop="http://www.springframework.org/schema/aop"
        xmlns:p="http://www.springframework.org/schema/p"
        xmlns:util="http://www.springframework.org/schema/util"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans.xsd
         http://www.springframework.org/schema/util
-        http://www.springframework.org/schema/util/spring-util.xsd">
+        http://www.springframework.org/schema/util/spring-util.xsd
+        http://www.springframework.org/schema/aop
+        http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
+
+    <aop:aspectj-autoproxy proxy-target-class="true"/>
 
     <bean id="johnMayer" class="com.apress.prospring5.ch5.GrammyGuitarist"/>
     <bean id="advice" class="com.apress.prospring5.ch5.AuditAdvice"/>
@@ -16,7 +21,8 @@
           p:guitarist-ref="proxyOne"/>
 
     <bean id="proxyOne" class="org.springframework.aop.framework.ProxyFactoryBean"
-          p:target-ref="johnMayer" p:interceptorNames-ref="interceptorAdviceNames"/>
+          p:target-ref="johnMayer" p:interceptorNames-ref="interceptorAdviceNames"
+          p:proxyTargetClass="true"/>
 
     <util:list id="interceptorAdviceNames">
         <value>advice</value>
@@ -27,7 +33,8 @@
           p:guitarist-ref="proxyTwo"/>
 
     <bean id="proxyTwo" class="org.springframework.aop.framework.ProxyFactoryBean"
-          p:target-ref="johnMayer" p:interceptorNames-ref="interceptorAdvisorNames">
+          p:target-ref="johnMayer" p:interceptorNames-ref="interceptorAdvisorNames"
+          p:proxyTargetClass="true">
     </bean>
 
     <util:list id="interceptorAdvisorNames">

这是完整的 XML 配置:

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:util="http://www.springframework.org/schema/util"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/util
        http://www.springframework.org/schema/util/spring-util.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">

    <aop:aspectj-autoproxy proxy-target-class="true"/>

    <bean id="johnMayer" class="com.apress.prospring5.ch5.GrammyGuitarist"/>
    <bean id="advice" class="com.apress.prospring5.ch5.AuditAdvice"/>

    <bean id="documentaristOne" class="com.apress.prospring5.ch5.Documentarist"
          p:guitarist-ref="proxyOne"/>

    <bean id="proxyOne" class="org.springframework.aop.framework.ProxyFactoryBean"
          p:target-ref="johnMayer" p:interceptorNames-ref="interceptorAdviceNames"
          p:proxyTargetClass="true"/>

    <util:list id="interceptorAdviceNames">
        <value>advice</value>
    </util:list>


    <bean id="documentaristTwo" class="com.apress.prospring5.ch5.Documentarist"
          p:guitarist-ref="proxyTwo"/>

    <bean id="proxyTwo" class="org.springframework.aop.framework.ProxyFactoryBean"
          p:target-ref="johnMayer" p:interceptorNames-ref="interceptorAdvisorNames"
          p:proxyTargetClass="true">
    </bean>

    <util:list id="interceptorAdvisorNames">
        <value>advisor</value>
    </util:list>

    <bean id="advisor" class="org.springframework.aop.support.DefaultPointcutAdvisor"
          p:advice-ref="advice">
        <property name="pointcut">
            <bean class="org.springframework.aop.aspectj.AspectJExpressionPointcut"
                  p:expression="execution(* sing*(..))"/>
        </property>
    </bean>

</beans>

【讨论】:

  • 我认为设置p:proxyTargetClass="true" 就足够了,不需要aop namespace。至少这对我有用。 Ref: If the proxyTargetClass property of the ProxyFactoryBean has been set to true, then a CGLIB-based proxy will be created.。 ----- (另外,尽量不要直接在这个github项目上运行代码。创建自己的项目并将必要的文件复制到自己的项目中。gitbub的原始项目只是不断抛出错误。)
  • 对不起,但我当然在 GitHub 上修复了该项目,因为这是 OP 询问的内容。我完全按照这里的解释修复了它。它可以工作并且不会对我的 PR 抛出任何错误。如果你的经历有任何不同,要么你有另一个项目,要么没有按照我的指示。所以你的评论不是很有帮助,因为我的回答是正确的。我没有猜测,但我尝试过。我不必像你一样说“我认为”。就像我说的那样,效果很好。
【解决方案2】:

我相信你必须让spring beans知道你正在使用哪些组件。 尝试在 Documentarist GrammyGuitarist 类初始化上方添加 @Component() 注释

【讨论】:

  • 嗯...不,它没有帮助。但最有趣的是它如何为其他人工作?我的意思是这段代码来自书本,应该可以工作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-09-21
  • 2018-01-06
  • 1970-01-01
  • 2014-10-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多