Spring AOP介绍中原始接口丢失

Mad*_*ram 4 java spring spring-aop

这是我的 Spring AOP 配置。

<bean id="myObject" class="com.madzone.learn.spring.aop.OriginalClass"></bean>
<bean id="aspect" class="com.madzone.learn.spring.aop.AspectClass"></bean>
<aop:config>
    <aop:aspect ref="aspect">
        <aop:declare-parents
            types-matching="com.madzone.learn.spring.aop.OriginalClass+"
            implement-interface="com.madzone.learn.spring.aop.IntroducedInterface"
            default-impl="com.madzone.learn.spring.aop.IntroducedInterfaceImpl" />
    </aop:aspect>
Run Code Online (Sandbox Code Playgroud)

ApplicationContext context = new ClassPathXmlApplicationContext("myApp.xml");
Object myObject = context.getBean("myObject");
if (myObject instanceof OriginalClass) {
    System.out.println("This is OriginalClass");
}
if(myObject instanceof IntroducedInterface) {
    System.out.println("This is IntroducedInterface");
}
Run Code Online (Sandbox Code Playgroud)

通过这个介绍,我能够调用IntroducedInterface 中的方法。但是,我无法访问 OriginalClass 的方法。在上面的代码片段中,我从未打印出“This is OriginalClass”。

根据“介绍”的定义,我了解到实现新接口的代理将从 OriginalClass 扩展并使其方法也可访问。

我在这里错过了什么吗?如果有的话,有人可以解释原因吗?

PS:以下是Spring in Action(第3版)中描述的图片。 调用者可以访问接口“现有方法”和“引入方法”吗?

Rya*_*art 6

根据“介绍”的定义,我了解到实现新接口的代理将从 OriginalClass 扩展并使其方法也可访问。

我不确定你从哪里得到这种印象。默认情况下,所有 Spring AOP 都构建在JDK 动态代理上,仅适用于接口。代理一个具体的类是不可能的。还有支持Spring为以代理类,而不是使用CGLIB代理,但它的使用是由参考指南鼓励有利于面向接口编程,以减少耦合。

  • 您添加的图表是准确的。使用 AOP 时,所有调用都转到代理实例,代理实例决定如何处理它们。作为 JDK 动态代理的代理实例只能实现接口,不能扩展类。因此,代理不能拥有您尝试调用的方法,因为它们在一个类上。简单地向您的代理类添加一个接口可以缓解这个问题。代理系统会看到接口并将其添加到代理实现的接口中。 (2认同)