默认情况下,Spring 通过以下方式应用 AOP代理类。动态创建代理类来实现许多接口。您向其传递一个“处理程序”对象,然后在调用其中任何接口方法时调用该对象。您可以阅读代理对象的 Javadochere http://download-llnw.oracle.com/javase/6/docs/api/java/lang/reflect/Proxy.html.
在应用程序上下文中的所有 bean 都已初始化后,Spring 将执行任何必要的后处理。这包括应用 AOP 建议。 Spring将用名称替换beaneddie
在上面的示例中,使用代理对象,该代理对象在将调用传递给原始对象之前调用另一个对象上的方法。每当你询问有名字的豆子时eddie
,您将获得代理对象而不是真实对象。
我找不到源Main
上面堆栈跟踪底部提到的类,但我确实找到了其余大部分代码here http://trac.emma-soft.com/SiA/browser/trunk。无论如何,在Main
班级,看来你正在做类似的事情
Instrumentalist eddie = (Instrumentalist) appContext.getBean("eddie", Instrumentalist.class);
The getBean(String, Class)
Spring应用程序上下文的方法将检查返回的bean是否属于指定的类,如果不是,则抛出异常。这就是您上面的示例中发生的情况。代理对象不是以下对象的实例Instrumentalist
,它是它自己的代理类的一个实例,称为$Proxy4
。 (这个代理类不能是Instrumentalist
因为所有代理类都扩展java.lang.reflect.Proxy
).
代理类将始终实现它们创建时使用的所有接口。春天会注意到Instrumentalist
实施Performer
,所以它创建的代理类也会实现Performer
。您可以将上面的行替换为
Performer eddie = (Performer) appContext.getBean("eddie", Performer.class);
并且,只要您只需要致电perform()
方法上eddie
,你的代码应该可以工作。