Spring (Java): Aspect not starting in non-linear class hierarchy

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 { // inherits doSomething // defines some other methods } 

Abstract implementations (template template):

 public static abstract class BaseTemplate implements TheInterface { abstract void doOneStep(); @Override public void doSomething() { // do some stuff and doOneStep(); } } public static abstract class SpecializedTemplate extends BaseTemplate implements SpecializedInterface { // some other methods } 

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?

+5
source share
1 answer

Thomas Stets has already explained the bytecode and JVM stuff, so I will just put a solution to your problem, see also my answer to a very similar question.

 @Aspect public static class MyAspect { @Before("execution(* *..TheInterface+.doSomething()) && target(specializedInterface)") public void applyAspect(SpecializedInterface specializedInterface) { aspectCalled = true; } } 

those. your pointcut targets the base interface, which actually defines the method, then you limit the target to the specialized sub-interface of your choice. This should make your test green.

0
source

Source: https://habr.com/ru/post/1212603/


All Articles