4

Here is my Spring AOP configuration.

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

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");
}

With this introduction I was able to call the methods in the IntroducedInterface. But, I was not able to access the OriginalClass' methods. In the code snippet above, I never got the 'This is OriginalClass' printed out.

From the definition of 'Introduction' I understood that the proxy that implements the new interface will extend from OriginalClass and make its' methods accessible too.

Am I missing something here? Can someone explain the reasons, if any?

PS: The following is a picture from Spring in Action (3rd Edition) that depicts this. Can the caller access both the interfaces 'Existing method' and 'Introduced method'?

1 Answers1

6

From the definition of 'Introduction' I understood that the proxy that implements the new interface will extend from OriginalClass and make its' methods accessible too.

I'm not sure where you got that impression from. All of Spring AOP is built, by default, on JDK dynamic proxies, which only work for interfaces. It's impossible to proxy a concrete class. There is support in Spring for using CGLIB proxies in order to proxy classes instead, but its use is discouraged by the reference guide in favor of programming to interfaces to reduce coupling.

Ryan Stewart
  • 126,015
  • 21
  • 180
  • 199
  • I'm reading Spring in Action and there is a picture depicting this (Figure 4.7 in 3rd edition). Without reading further intricacies I wrote that program with a wrong expectation that failed. – Madhusuthanan Seetharam Dec 30 '12 at 09:41
  • Further reading into annotated aspects I found the following "When it discovers a bean annotated with @Aspect, it’ll automatically create a proxy that delegates calls to either the prox-ied bean or to the introduction implementation, depending on whether the method called belongs to the proxied bean or to the introduced interface." Am I missing something, still? That apart, my test (in the annotated version) confirms that only the introduced interface is accessible and not the original prox-ied bean. – Madhusuthanan Seetharam Dec 30 '12 at 12:55
  • 2
    The diagram you added is accurate. When using AOP, all calls go to the proxy instance, and the proxy instance decides what to do with them. Proxy instances that are JDK dynamic proxies can only implement interfaces, not extend classes. Therefore the proxy can't have the methods that you're trying to call because they're on a class. Simply adding an interface to your proxied class would alleviate this problem. The proxying system would see the interface and add it to the interfaces implemented by the proxy. – Ryan Stewart Dec 30 '12 at 17:08