Search code examples
javaaopaspect

Does Aspect Oriented Programming require recompilation whenever an aspect changes?


One important design principle is the OCP, which states that we would like our modules to be open for extension but closed to modification.

When we use Aspect Oriented Programming, we impact the whole project meaning that any change in an aspect may change the behavior of every function in the project. I wanted to understand if this implies that every time we change an aspect, we must recompile the whole project. This seems contradictory to the OCP. If this is not the case, how does the AOP weaving manage to add the behavior into the compiled code?

Edit: following the comment from @kriegaex, I am interested specifically in Java and with AspectJ. I am teaching Software design and I give AOP as an example of using frameworks for better design. As I teach the SOLID design principles, I want to understand the impact of AOP on these principles. If there is any AOP framework that does not violate OCP (meaning that changing an aspect does not require recompiling the whole project), please tell me about it.


Solution

  • Usage scenarios

    There are multiple cases:

    Load-time / run-time weaving

    • Native AspectJ with load-time weaving (LTW) uses byte code instrumentation during class-loading.
    • Spring AOP creates dynamic proxies wired into your Spring beans at runtime.

    In both cases, there is no need to recompile any code after you change your aspects, because all aspect weaving is done during runtime. Your original bytecode stays intact, but you have the weaving overhead during application start for both options. After weaving, AspectJ performs exactly like compile-time or binary (post-compile) woven aspects. Spring AOP will always be slower due to the proxying overhead for every method call.

    Compile-time weaving (CTW)

    When using the AspectJ compiler when compiling your aspect and application code, every aspect change requires core code recompilation, because an aspect can potentially affect any number of target classes. The advantage however is that you do not need to set up any weaving agents like for LTW and there is no application start-up penalty.

    Binary, post-compile weaving

    This is similar to CTW, but used if you want to weave existing class files, e.g. from third-party libraries without resort to LTW. This will modify your existing byte code, and you might need to replace existing JARs by newly packaged ones containing the woven classes.

    Software engineering perspective

    In each of these scenarios, the advantages of cleanly modularising and encapsulating cross-cutting concerns and unburdening the core source code from scattering and tangling by far outweigh any effects which for classical OOP you might want to avoid, such as OCP. IMO, you do not really violate OCP here anyway, because you are not modifying the core classes as such, but rather decorating them with additional behaviours, which is cleanly modularised inside an aspect. Call it a Decorator pattern on steroids, i.e. without all the ceremony and boilerplate that you would need in OOP. For me, AOP is a tool supporting clean code and better application design by means unavailable in pure OOP, without the need to resort to nightmarish stuff like multiple inheritance.