我正在春天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>
当我运行代码时我收到错误说:
如果我发表评论弹簧配置文件中的< aop:config>
元素运行得很好..
为什么会发生这种情况?
解决方案默认情况下,Spring使用代理类来应用AOP。动态创建代理类以实现许多接口。您传递一个处理程序对象,然后在调用任何这些接口方法时调用该对象。您可以在。
在初始化应用程序上下文中的所有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:
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的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!