In this tutorial series, you are going to learn.
a.
Introduction to Aspect Oriented Programming
b.
Installing AspectJ
c.
Aspectj: Hello World Application
d.
Troubleshooting
Introduction to Aspect Oriented Programming
Aspect oriented programming complements the Object
Oriented programming by adding aspects to it. In OOP, class is the key unit,
where as in AOP (Aspect Oriented Programming), aspect is the key entity.
AOP mainly addresses the cross cutting problems faced by
industries while developing complex applications. By using Aspects, you can
separate these cross cutting concerns from the core business logic.
What is cross cutting
concern?
While developing any enterprise application, you can see
logging, authorization, pooling, caching, monitoring and transaction management
is everywhere. Ideally logging,
authorization is nothing to do with core business logic. By using Aspects, we
can move these cross cutting concerns out of the core business logic.
Instead of integrating authorization checks in every API
code, you can annotate a service method with a marker that tells who can call
it, and let some AOP advice decide whether to allow the method call or not.
By implementing logging as AOP advice, you can change
what gets logged by changing a join point.
Installing Aspectj
Below step by step procedure explains how to install
Aspectj.
Step 1: Go to
below location and download latest version of aspectj.
At the time of writing this article, 1.8.13 is the latest
stable version of Aspectj.
Step 2: Go the the
location of aspectj jar file and run below command.
java -jar <PATH_TO_DOWNLOADED_ASPECTJ_JAR>
When you ran above command, it opens gui window to
install AspectJ 8 development kit.
Press Next.
It selects the jre installed in your machine. If you want
to choose different jre, use the Browse button.
Press the button ‘Install’.
Once the installation is successful, you can able to see
below window.
Once you press Next, it opens below window that shows
important steps to perform while executing aspectj programs.
Add aspectjrt.jar to your classpath. And add aspectj bin
to your system path.
Aspectj: Hello World
Application
I
hope you setup the aspecj in your system.
ResourceUtil.java
public class ResourceUtil{ public void sendResource(String senderName, String receiverName){ System.out.println("Sending resource from " + senderName + " to " + receiverName); } }
Test.java
public class Test{ public static void main(String args[]){ ResourceUtil resourceUtil = new ResourceUtil(); resourceUtil.sendResource("S01", "R01"); } }
Compile the classes using the command 'javac -classpath .
Test.java'.
Run the classes using the command 'java -classpath .
Test'
you can able to see below output.
Sending resource from S01 to R01
Now let’s try to add authorization logic to the
‘sendResource’ method. I created ‘AuthorizationUtil.java’ class, it checks whether
the sender and receiver are authorized to send and receive the information.
My program structure changed like below.
AuthorizationUtil.java
public class AuthorizationUtil{ public boolean amIAuthorizedToSend(String senderName){ if("S01".equals(senderName)){ System.out.println(senderName + " is authorized to send"); return true; } throw new RuntimeException(senderName + " is not authorized to send"); } public boolean amIAuthorizedToReceive(String receiverName){ if("R01".equals(receiverName)){ System.out.println(receiverName + " is authorized to receive"); return true; } throw new RuntimeException(receiverName + " is not authorized to receive"); } }
ResourceUtil.java
public class ResourceUtil{ public void sendResource(String senderName, String receiverName){ /* Checking the authorization of sender and receiver */ AuthorizationUtil authUtil = new AuthorizationUtil(); authUtil.amIAuthorizedToSend(senderName); authUtil.amIAuthorizedToReceive(receiverName); System.out.println("Sending resource from " + senderName + " to " + receiverName); } }
Test.java
public class Test{ public static void main(String args[]){ ResourceUtil resourceUtil = new ResourceUtil(); resourceUtil.sendResource("S01", "R01"); } }
Compile the classes using the command 'javac -classpath .
Test.java'.
Run the classes using the command 'java -classpath .
Test'
you can able to see below output.
S01 is authorized to send
R01 is authorized to receive
Sending resource from S01 to R01
As you closely observe, ‘sendResource’ method of
ResourceUtil class, it is tightly coupled with authorization checks inaddition
to core business logic.
public void
sendResource(String senderName, String receiverName){
/*
Checking the authorization of sender and receiver */
AuthorizationUtil
authUtil = new AuthorizationUtil();
authUtil.amIAuthorizedToSend(senderName);
authUtil.amIAuthorizedToReceive(receiverName);
System.out.println("Sending
resource from " + senderName + " to " + receiverName);
}
What if there are 100 methods that require authorization
checks, before executing actual business logic. You will end up in keeping the
same authorization checks everywhere.
By using aspects, you can move these cross cutting tasks
outside of core business logic.
Find the below working application.
Step 1: Define AuthorizationUtil
class.
AuthorizationUtil.java
public class AuthorizationUtil{ public boolean amIAuthorizedToSend(String senderName){ if("S01".equals(senderName)){ System.out.println(senderName + " is authorized to send"); return true; } throw new RuntimeException(senderName + " is not authorized to send"); } public boolean amIAuthorizedToReceive(String receiverName){ if("R01".equals(receiverName)){ System.out.println(receiverName + " is authorized to receive"); return true; } throw new RuntimeException(receiverName + " is not authorized to receive"); } }
Step 2: Define
ResourceUtil class.
ResourceUtil.java
public class ResourceUtil{ public void sendResource(String senderName, String receiverName){ System.out.println("Sending resource from " + senderName + " to " + receiverName); } }
Step 3: Define the
security aspect like below.
SecurityAspect.aj
public aspect SecurityAspect{ private AuthorizationUtil authorizationUtil = new AuthorizationUtil(); pointcut secureAceess() : call(* ResourceUtil.sendResource(..)); before() : secureAceess(){ System.out.println("Checking the authorizations of sender and receiver"); String senderName = (String)thisJoinPoint.getArgs()[0]; String receiverName = (String)thisJoinPoint.getArgs()[1]; authorizationUtil.amIAuthorizedToSend(senderName); authorizationUtil.amIAuthorizedToReceive(receiverName); } }
Step 4: Define
Test class like below.
Test.java
public class Test{ public static void main(String args[]){ ResourceUtil resourceUtil = new ResourceUtil(); resourceUtil.sendResource("S01", "R01"); } }
Compile the java class
using below command
ajc -source 5 SecurityAspect.aj *.java
Run the java classes
using below command
java -classpath . Test
C:\Users\krishna\Documents\Study\aspectj\examples>ajc
-source 5 SecurityAspect.aj *.java
C:\Users\krishna\Documents\Study\aspectj\examples>java
-classpath . Test
Checking the authorizations of sender and receiver
S01 is authorized to send
R01 is authorized to receive
Sending resource from S01 to R01
Explanation
How to declare
aspect?
It is just like class in java. Aspect is defined using
the keyword ‘aspect’. You can define an aspect in either .aj file (or) in .java
file.
What is pointcut?
By using pointcuts, we can specify the points that we
want to add extra checks like authorization.
java.lang.NoClassDefFoundError:
org/aspectj/lang/NoAspectBoundException
While running the aspectj applications, I got the error ‘java.lang.NoClassDefFoundError:
org/aspectj/lang/NoAspectBoundException’.
I resolved the above error by placing ‘aspectjrt.jar’ in the
classpath.
I placed the jar file in ‘<JAVA_HOME>\jre\lib\ext’.
classpath error: unable to
find org.aspectj.lang.JoinPoint
When I am trying to run an aspect application, I an
ending up with the error ‘classpath error: unable to find
org.aspectj.lang.JoinPoint’.
I get rid of the error by adding ‘aspectjrt.jar’ file to
my project classpath.
You may like
No comments:
Post a Comment