【问题标题】:BeanNotOfRequiredTypeException with Spring AOP带有 Spring AOP 的 BeanNotOfRequiredTypeException
【发布时间】:2015-09-21 02:46:44
【问题描述】:

我正在尝试使用 spring aop 和 spring 配置文件:

<?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:context="http://www.springframework.org/schema/context"
    xmlns:util="http://www.springframework.org/schema/util" xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd
        http://www.springframework.org/schema/aop  http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">

    <bean id="eddie" class="com.springinaction.Instrumentalist">
        <property name="instrument" ref="violin"></property>
        <property name="song" value="Samarame"></property>

    </bean>


    <bean id="kenny" class="com.springinaction.Instrumentalist">
        <property name="song" value="SAMARAME "></property>
        <property name="instrument" ref="saxopone"></property>
    </bean>

    <bean id="hank" class="com.springinaction.OneManBand">
        <property name="instruments">
            <props>
                <prop key="GUITAR">STRUM STRUM STRUM</prop>
                <prop key="CYMBAL">CRASH CRASH CRASH CRASH</prop>
                <prop key="HARMONICA">HUM HUM HUM</prop>
            </props>
        </property>
    </bean>

    <bean id="guitar" class="com.springinaction.Guitar">
    </bean>

    <bean id="violin" class="com.springinaction.Violin">
    </bean>

    <bean id="tabala" class="com.springinaction.Tabala">
    </bean>

    <bean id="saxopone" class="com.springinaction.Saxophone">
    </bean>

    <bean id="audience" class="com.springinaction.Audience"></bean>

    <aop:config>

        <aop:aspect ref="audience">

            <aop:before pointcut="execution(* com.springinaction.Performer.perform(..))" method="takeSeats()"/>
        </aop:aspect>
    </aop:config>

</beans>

当我运行代码时,我收到错误消息:

线程“main”中的异常 org.springframework.beans.factory.BeanNotOfRequiredTypeException: 名为 'eddie' 的 Bean 必须是类型 [com.springinaction.Instrumentalist], 但实际上是 [$Proxy4] 类型 org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:348) 在 org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193) 在 org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1008) 在 com.springinaction.Main.main(Main.java:12)

如果我在 spring 配置文件中评论 &lt;aop:config&gt; 元素,它运行完美..

为什么会这样?

【问题讨论】:

    标签: java spring spring-aop


    【解决方案1】:

    默认情况下,Spring 使用 代理类 应用 AOP。代理类是动态创建的以实现多个接口。您将传递给它一个“处理程序”对象,然后在调用任何这些接口方法时调用该对象。您可以阅读代理对象的 Javadoc here

    在应用程序上下文中的所有 bean 都已初始化后,Spring 将执行任何必要的后处理。这包括应用 AOP 建议。 Spring 将使用代理对象替换名称为 eddie 的 bean,在上面的示例中,该代理对象在将调用传递给原始对象之前调用另一个对象的方法。每当您请求名称为 eddie 的 bean 时,您将获得代理对象而不是真实对象。

    我找不到上面堆栈跟踪底部提到的Main 类的源代码,但我确实找到了大部分代码here。无论如何,在Main 类中,您似乎正在做类似的事情

    Instrumentalist eddie = (Instrumentalist) appContext.getBean("eddie", Instrumentalist.class);
    

    Spring 应用上下文的getBean(String, Class) 方法将检查返回的bean 是否属于指定的类,如果不是,则抛出异常。这就是您上面的示例中发生的情况。代理对象不是Instrumentalist 的实例,它是它自己的代理类的实例,称为$Proxy4。 (这个代理类不能是Instrumentalist的子类,因为所有代理类都扩展java.lang.reflect.Proxy)。

    代理类将始终实现它们创建时使用的所有接口。 Spring 会注意到Instrumentalist 实现了Performer,因此它创建的代理类也将实现Performer。您可以将上面的行替换为

    Performer eddie = (Performer) appContext.getBean("eddie", Performer.class);
    

    并且,如果您只需要在 eddie 上调用 perform() 方法,您的代码应该可以工作。

    【讨论】:

    • 感谢 Pourquoi Litytestdata 的详细回答...看来您对 SpringIdol 比赛了解很多 :) 我想我需要了解代理类...再次感谢您的澄清...跨度>
    猜你喜欢
    • 2018-09-11
    • 2019-08-19
    • 1970-01-01
    • 1970-01-01
    • 2022-12-23
    • 2020-09-17
    • 2011-12-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多