繁体   English   中英

使用Spring AOP的BeanNotOfRequiredTypeException

[英]BeanNotOfRequiredTypeException with Spring AOP

我在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]类型,但实际上是org.springframework.beans.factory类型为[$ Proxy4]的类型.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配置文件中注释<aop:config>元素,它运行完美..

为什么会这样?

默认情况下,Spring通过使用代理类来应用AOP。 动态创建代理类以实现许多接口。 你传递一个'handler'对象,然后在调用任何这些接口方法时调用它。 您可以在此处阅读代理对象的Javadoc。

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

我无法找到上面stacktrace底部提到的Main类的源代码,但我确实在这里找到了大部分代码。 无论如何,在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()方法,那么您的代码应该可以工作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM