使用Spring AOP的BeanNotOfRequiredTypeException [英] BeanNotOfRequiredTypeException with Spring AOP

查看:113
本文介绍了使用Spring AOP的BeanNotOfRequiredTypeException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在春天aop和春天配置文件下面尝试我的手:

 <?xml version =1.0 encoding =UTF-8?> 
< beans xmlns =http://www.springframework.org/schema/beans
xmlns:xsi =http://www.w3.org/2001/XMLSchema-instancexmlns :context =http://www.springframework.org/schema/context
xmlns:util =http://www.springframework.org/schema/utilxmlns: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 =eddieclass =com.springinaction.Instrumentalist>
< property name =instrumentref =violin>< / property>
< property name =songvalue =Samarame>< / property>

< / bean>


< bean id =kennyclass =com.springinaction.Instrumentalist>
< property name =songvalue =SAMARAME>< / property>
< property name =instrumentref =saxopone>< / property>
< / bean>

< bean id =hankclass =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 =guitarclass =com.springinaction.Guitar>
< / bean>

< bean id =violinclass =com.springinaction.Violin>
< / bean>

< bean id =tabalaclass =com.springinaction.Tabala>
< / bean>

< bean id =saxoponeclass =com.springinaction.Saxophone>
< / bean>

< bean id =audienceclass =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)
at
org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
at
org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1008 )
at
com.springinaction.Main.main(Main.java:12)


如果我发表评论弹簧配置文件中的< aop:config> 元素运行得很好..



为什么会发生这种情况?

解决方案

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



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



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

 乐器演奏家eddie =(乐器演奏家)appContext.getBean(eddie,Instrumentalist.class); 

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



代理类将始终实现它们创建的所有接口。 Spring会注意到 Instrumentalist 实现 Performer ,因此它创建的代理类也将实现 Performer 。您可以用



替换上面的行

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

并且,如果您只需要调用 perform() eddie 上的c $ c>方法,您的代码应该有效。


I am trying my hands at spring aop and below the spring config file:

<?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>

when i run the code i am getting error saying:

Exception in thread "main" org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'eddie' must be of type [com.springinaction.Instrumentalist], but was actually of type [$Proxy4] at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:348) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193) at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1008) at com.springinaction.Main.main(Main.java:12)

If i comment <aop:config> element in spring config file it is running perfectly..

Why it is happening?

解决方案

By default, Spring applies AOP by using proxy classes. A proxy class is created dynamically to implement a number of interfaces. You pass it a 'handler' object which it then calls when any of these interface methods are invoked on it. You can read the Javadoc for proxy objects here.

After all the beans in the application context have been initialised, Spring will then do any post-processing necessary. This includes applying AOP advice. Spring will replace the bean with name eddie with a proxy object that, in your example above, calls a method on another object before passing the call on to the original object. Whenever you ask for the bean with name eddie, you'll get the proxy object instead of the real object.

I couldn't find the source to the Main class mentioned at the bottom of the stacktrace above, but I did find most of the rest of the code here. Anyway, in the Main class, it seems you are doing something like

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

The getBean(String, Class) method of the Spring application context will check that the bean returned is of the class specified, and if not, throw an exception. This is what has happened in your example above. The proxy object isn't an instance of Instrumentalist, it's an instance of its own proxy class called $Proxy4. (This proxy class can't be a subclass of Instrumentalist because all proxy classes extend java.lang.reflect.Proxy).

Proxy classes will always implement all interfaces they were created with. Spring will notice that Instrumentalist implements Performer, so the proxy class it creates will also implement Performer. You could replace the above line with

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

and, provided you only need to call the perform() method on eddie, your code should work.

这篇关于使用Spring AOP的BeanNotOfRequiredTypeException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆