Thursday, November 12, 2020

Aspect-Oriented Programming (AOP) with Adobe Experience Manager(AEM)

What is AOP?



Aspect-oriented programming (AOP) is a programming paradigm that aims to increase modularity by allowing the separation of cross-cutting concerns. It does so by adding additional behavior to the existing code (an advice) without modifying the code itself, instead separately specifying which code is modified via a “pointcut” specification, such as “log all function calls when the function’s name begins with ‘set’”. This allows behaviors that are not central to the business logic (such as logging) to be added to a program without cluttering the code, core to the functionality.

Aspect-Oriented Programming provides a solution to implement Cross-Cutting Concerns.
Implement the cross-cutting concern as an aspect.
Define pointcuts to indicate where the aspect has to be applied.

This ensures that the cross-cutting concerns are defined in a centralized component and can be applied as needed.

This enables some of the below benefits
  • Reusable code
  • Cleaner code
  • Write less code
  • Less boilerplate code
  • Easy to maintain

Let us quickly see some of the definitions

  • Advice — Define what needs to be applied and when
  • Jointpoint — Where the Advice is applied
  • Pointcut — a combination of different Jointpoints where the advice needs to be applied.
  • Aspect — applying the advice at the pointcuts

Types of Advice:


  • Before Advice — the advice runs before the method execution
  • After Advice — the advice runs after the method execution
  • After Returning Advice — the advice runs after the method executes successfully
  • Around Advice — the advice can run before and after the method execution
  • Throws Advice — ensures the advice runs if the method throws an exception

AspectJ


AspectJ is an aspect-oriented extension to the Java programming language. AspectJ AOP implementation provides many annotations to support AOP programming in Java.

  • @Aspect — declares the class as an aspect.
  • @Pointcut — declares the pointcut expression.

The annotations used to create advices are given below:
  • @Before declares the before advice. It is applied before calling the actual method.
  • @After declares the after advice.
  • @AfterReturning declares the after returning advice.
  • @Around declares the around advice.
  • @AfterThrowing declares the throws advice.

AspectJ offers different required dependencies in the Maven Central repository under group org.aspectj.

AspectJ with AEM


Let us now see how to enable the AspectJ with AEM

As a first step enables the below plugin in core module pom.xml(the plugins and dependency versions are added based on Java 1.8, change based on your Java version )

<plugin>
   <groupId>org.codehaus.mojo</groupId>
   <artifactId>aspectj-maven-plugin</artifactId>
   <version>1.11</version>
   <configuration>
      <complianceLevel>1.8</complianceLevel>
      <source>1.8</source>
      <target>1.8</target>
      <encoding>UTF-8</encoding>
   </configuration>
   <executions>
      <execution>
         <goals>
            <goal>compile</goal>
         </goals>
      </execution>
   </executions>
</plugin>


Enable the AspectJ dependencies to the Core module Pom.xml

<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjrt -->

<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.8.13</version>
</dependency>

<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjtools -->

<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjtools</artifactId>
<version>1.8.13</version>
</dependency>


Embed the AspectJ runtime dependency to Core bundle — enable the below configuration changes to core module pom.xml

<plugin>
<groupId>biz.aQute.bnd</groupId>
<artifactId>bnd-maven-plugin</artifactId>
<executions>
<execution>
<id>bnd-process</id>
<goals>
<goal>bnd-process</goal>
</goals>
<configuration>
<bnd><![CDATA[
Import-Package: javax.annotation;version=0.0.0,*
-includeresource: aspectjrt-1.8.13.jar;lib:=true
]]></bnd>
</configuration>
</execution>
</executions>
</plugin>


Now define the Aspect — the aspect is going to execute After, Before, and Around advice.





execution(* com.aspectj.core.servlets.*.doGet(..)) — Defines the PointCut, the advice will be run for the doGet method on the servlets under com.aspectj.core.servlets package

  • The first wildcard — matches any return value
  • com.aspectj.core.servlets.*.doGet — doGet method on the servlets under com.aspectj.core.servlets package
  • (…) — any number of parameters (zero or more)

logExecutionTime — Around advice, log the method execution time for all Servlet “GET” requests

logRequestHeader — Before advice, log the HTTP request headers for all Servlet “GET ”requests. Mapping the input variable req(the variable should be defined in the same order as the actual method signature) for using inside the Advice , args(req,…) — req as a first parameter followed by zero or more parameter

addCustomHeader — Before advice, add custom HTTP headers for all Servlet “GET ”responses. Mapping the input variable resp(the variable should be defined in the same order as the actual method signature) for using inside the Advice, args(…,resp) — resp as the last parameter

Now while invoking the servlets under com.aspectj.core.servlets through the “GET” method, the logExecutionTime, logRequestHeader and addCustomHeader Advice run and perform the appropriate operations.

The AOP will help us to address the cross-cut concerns in Java e.g. logging in all methods, this helps us to write clean code with better maintainability. The common concerns across the project can be maintained separately as an Advice and executed runtime based on the PointCut configuration.

Demo Project —https://github.com/techforum-repo/youttubedata/tree/master/aspectj


Thanks for reading, feel free to add your comments



No comments:

Post a Comment