Hi,
I was playing little bit with @DeclareParents annotation and I found some strange thing, which I don't understand: by using @DeclareParents I was able to call different implementation instead of final method. I don't know whether this is feature or bug... Can anybody explain this to me?
This is what I did:
I've created FooBar interface and one implementation with final method.
FooBar interfaceFooBarImpl classCode:package spring.example.aop.introduction; public interface FooBar { public int foo(int bar); }
Main classCode:package spring.example.aop.introduction; public class FooBarFinalImpl implements FooBar { public final int foo(int bar) { return bar+3; } }
app-context.xmlCode:package spring.example.aop.introduction; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class ApplicationRunner { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("app-context.xml"); FooBar fooBar = (FooBar)context.getBean("foobar"); System.out.println(fooBar.foo(5)); } }
When I ran the application, I got output: 8HTML Code:<?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: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/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"> <bean name="foobar" class="spring.example.aop.introduction.FooBarFinalImpl"/> <aop:aspectj-autoproxy/> </beans>
which is 5 + 3... that's ok
Then I created another implementation of the FooBar interface
Also I created another interface called ZigZag with only one method foo(int) with same signature as in FooBar interfaceCode:package spring.example.aop.introduction; public class FooBarAnotherImpl implements FooBar { public int foo(int bar) { return 0; } }
Finally, I created FooBar introduction and annotated it with @DeclareParents:Code:package spring.example.aop.introduction; public interface ZigZag { public int foo(int bar); }
And also I updated config file and main class:Code:package spring.example.aop.introduction; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.DeclareParents; @Aspect public class FooBarIntroduction { @DeclareParents( value="spring.example.aop.introduction.FooBarFinalImpl", defaultImpl = FooBarAnotherImpl.class ) public ZigZag zigZag; //this is by purpose }
HTML Code:<?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: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/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"> <bean name="foobar" class="spring.example.aop.introduction.FooBarFinalImpl"/> <bean class="spring.example.aop.introduction.FooBarIntroduction"/> <aop:aspectj-autoproxy/> </beans>Now when I run the application, I will get following output:Code:package spring.example.aop.introduction; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class ApplicationRunner { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("META-INF/spring/aop-int-context.xml"); FooBar fooBar = (FooBar)context.getBean("foobar"); System.out.println(fooBar.foo(5)); ZigZag zigZag = (ZigZag)fooBar; System.out.println(zigZag.foo(99)); } }
0
0
So this means that it was executed foo() method implemented in FooBarAnotherImpl even the foo() method in FooBarFinalImpl is final.
If I replace ZigZag in FooBarIntroduction class with FooBar, it works differently... I will get output 8... final method is executed by proxy.
Is this feature? Why it works like this?
Thanks
Peter


Reply With Quote
