If the class hierarchy is not linear, the aspect does not start when defined on the base interface.
The most interesting thing: when you add implementation delegation (see the last block of code) to the parent implementation class, the test turns green (Aspect starts as expected).
Question: Why does it not work, as described in the example, and why does it work with delegation of implementation?
Example (sorry, no shorter example found):
Test:
@Autowired private TheInterface underTest; private static boolean aspectCalled; private static boolean implementationCalled; @Test public void aspectTest() throws Exception { aspectCalled = false; implementationCalled = false; underTest.doSomething(); assertTrue("Implementation not called!", implementationCalled); assertTrue("Aspect not called!", aspectCalled); }
Format:
@Aspect @Component public static class MyAspect { @Before("execution(* *..SpecializedInterface+.doSomething())") public void applyAspect() { aspectCalled = true; } }
Interfaces:
public static interface TheInterface { void doSomething(); } public static interface SpecializedInterface extends TheInterface {
Abstract implementations (template template):
public static abstract class BaseTemplate implements TheInterface { abstract void doOneStep(); @Override public void doSomething() {
Bean implementation:
@Component public static class TemplateImplementation extends SpecializedTemplate { @Override void doOneStep() { implementationCalled = true; } }
(If you are interested: setup :)
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = MyConfig.class) public class AopTest { @Configuration @EnableAspectJAutoProxy @ComponentScan(basePackageClasses = AopTest.class) public static class MyConfig { } ...
Awful workaround: add this snippet to SpecializedTemplate
@Override public void doSomething() { super.doSomething(); }
So why is this workaround necessary?