Spring AOP 的 BeanNotOfRequiredTypeException
我正在尝试使用 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 配置文件中注释
元素,它会完美运行..
为什么会发生这种情况?
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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
默认情况下,Spring 通过使用代理类来应用 AOP。动态创建代理类来实现许多接口。您向其传递一个“处理程序”对象,然后在调用其中任何接口方法时调用该对象。您可以在 此处阅读代理对象的 Javadoc 。
在应用程序上下文中的所有 bean 都已初始化后,Spring 将执行任何必要的后处理。这包括应用 AOP 建议。 Spring 会将名为
eddie
的 bean 替换为代理对象,在上面的示例中,该代理对象在将调用传递给原始对象之前调用另一个对象上的方法。每当您请求名为eddie
的 bean 时,您将获得代理对象而不是真实对象。我找不到上面堆栈跟踪底部提到的
Main
类的源代码,但我确实找到了其余大部分代码 此处。无论如何,在 Main 类中,您似乎正在执行类似Spring 应用程序上下文的 getBean(String, Class) 方法将检查返回的 bean 是否属于指定的类,如果没有,则抛出异常。这就是您上面的示例中发生的情况。代理对象不是
Instrumentalist
的实例,而是其自己的名为$Proxy4
的代理类的实例。 (此代理类不能是Instrumentalist
的子类,因为所有代理类都扩展java.lang.reflect.Proxy
)。代理类将始终实现它们创建时使用的所有接口。 Spring 会注意到
Instrumentalist
实现了Performer
,因此它创建的代理类也将实现Performer
。您可以将上面的行替换为and,只要您只需要调用
eddie
上的perform()
方法,您的代码就应该可以工作。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 nameeddie
, 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 theMain
class, it seems you are doing something likeThe
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 ofInstrumentalist
, it's an instance of its own proxy class called$Proxy4
. (This proxy class can't be a subclass ofInstrumentalist
because all proxy classes extendjava.lang.reflect.Proxy
).Proxy classes will always implement all interfaces they were created with. Spring will notice that
Instrumentalist
implementsPerformer
, so the proxy class it creates will also implementPerformer
. You could replace the above line withand, provided you only need to call the
perform()
method oneddie
, your code should work.