Skip to main content

Clean code with aspects

In my previous post I've described the alphabet conversion, and I've mentioned that we used AspectJ to resolve that task, but i did not mention how AspectJ works and what are aspects generaly. So in the next few lines i will explain:

  • what is Aspect Oriented Programming and why we need it
  • what is AspectJ
  • using AspectJ with Spring (configuring AspectJ and spring to work together)
  • and i will explain aspects on the example from previous post.

What Is Aspect Oriented Programing and why we need it

During software development we can use different programming paradigms such as OOP (object oriented programing) or POP(procedural oriented programing).
Today most of us use Object Oriented Programming methodologies for resolving real life problems, during software development process.
But during our work, we are constantly meeting with some code which crossing through our code base and breaking its modularity and making it dirty.
This part of code usually don’t have business values, but we need them to resolve our problems.
For example we can take a look on database transactions.
Transactions are very important for our software, because they take care about data consistency. The code which start and handle transaction are very important for our application but it is used for technical stuff (starting, committing and rolling back transactions). This things make it difficult to understand what is real meaning of code (to see real business value of code).
Of course i will not make any example of how to handle transactions using aspects because there is a lot of frameworks which will take care about transactions instead of us. I’ve just mentioned transactions because you probably know how to insert data into database using a plain JDBC API.
So to make our code cleaner we will use a design patterns, which is a good approach for the problem solving. But also sometimes a usage of design patterns will not lead us to easy solution, and most of us will resort to the easier solution what will produced “dirty” code.
In this situation we should give a chance to Aspect Oriented approach for the problem solving. When we think about AOP we should not think about something totally new for us, we should think about AOP as a complements of OOP. AOP is there to make easier code modularisation, make code cleaner, and provide us with easier and faster understand what some part of application should do.
AOP introduce a few new concepts which will allow us easier code modulation. If we want to efficiently use Aspects we need to know its basics principe and terminology.
When we start with using AOP we will meet a new termines:

  • Crosscutting concerns, it is code which should be moved in separate module (i.e. code for handling transactions).
  • Aspect, it is a module which contains concerns.
  • Pointcut, we can look at it as pointer which will instruct when corresponding code should be run 
  • Advice, it contains a code which should be run when some join point is reached.
  • Inner-type declaration, allow modification of class structure.
  • Aspect-weaving, is mechanism which coordinate the integration with the rest of the system.
I will show at the end what are they and how to use them within an example.

What is AspectJ

AspectJ is an extension of Java programing language which allow usage of AOP concepts within Java programing language.
When you use AspectJ you do not need to make any changes in your existing code.
AspectJ extend java with a new construct called aspect, and after AspectJ 5 you can use annotation based development style.

AspectJ and Spring

Spring framework already provide its own implementation of AOP. Spring AOP is simpler solution than AspectJ but it is not so robust as AspectJ. So if you want to use aspects in your spring application you should be familiar with possibilities of Spring AOP before choosing AspectJ to do work.
Before we see the example of using aspect i will show you how to integrate AspectJ with Spring and how to configure Tomcat to be able to run AspectJ application with Spring. In this example I’ve used LTW (load time weaving) of aspects.
So I will start explaining first how to do it from Spring. It is easy, just add next line in your application configuration file:

That is all what is needed to be done with in spring configuration.

The next step is configuration of Tomcat. We need to define new class loader for application. This class loader need to be able to do load time weaving so we use:


The loader need to be in Tomcat classpath before you can use it.
Of course, in order to make this work, we need to create aop.xml file. This file contains instruction which will be used by class loader during class transformation process.
Here is example of aop.xml file which I’ve used for alphabet convertion.


This last xml file is most interesting for all of you which are willing to try AspectJ. It instruct AspectJ weaving process.
The weaver section contains information about what should be weaved. So this file will include all Classes inside:

  • ba.codecentric.medica.model.*
  • ba.codecentric.medica..*.service.*
  • ba.codecentric.medica.controller..*
  • ba.codecentric.medica.utils.ModelMapper
  • ba.codecentric.medica.utils.RedirectHelper
  • ba.codecentric.medica.aop.aspect.CharacterConvertionAspect
  • ba.codecentric.medica.security.UserAuthenticationProvider
  • ba.codecentric.medica.wraper.MedicaRequestWrapper

So the first line including all classes inside of model package. The second one include all Classes which are part of services sub packages inside of ba.codecentric.medica package (i.e. ba.codecentric.medica.hospitalisation.service). The third one include everything belowe controller package. And rest of the lines include specified classes.
Options attribute define addition option which should be used during weaving process. So in this example -Xset:weaveJavaxPackages=true instruct AspectJ also to weave java packages.
Aspects section contain list of aspects which will be used during weaving process.
For more information about configuration with xml you can see AspectJ documentation.

Example of usage AspectJ



I prefer usage of Annotation so the next example will show you how to use AspectJ with annotation. Annotation driven programming with AspectJ is possible from version AspectJ 5. Here is some code of a complete aspect which contains concerns used for alphabet conversion.


First of all we can see that class is annotated with @Aspect annotation. This indicate that this class is actually an aspect. Aspect is a construction which contains similar cross-cutting concerns. So we can look at it as a module which contains cross cutting code and define when which code will be used and how.

This is a method which is annotated with @Around annotation. The around annotation is used to represent around advice. I have already mentioned that, advice is the place which contains a cross-cutting code. In this example I’ve only used “around” advice, but except that there is also before,after,after returning and after throwing advice. All advice except around should not have a return value.
The content inside of around annotation define when code from advice will be weaved. This also can be done when we define pointcuts. In this example I did't use pointcuts for defining join points because it’s simple aspect. With pointcut annotations you can define real robust join points. In this case advice will be executed during setting values of entity beans which have only one parameter of type String.
ProcidingJoinPoint pjp, in the example above, present the join point, so for this example it is setter method of entity bean. Value of object send to the entity setter method will be first converted and then the setter method will be called with a converted value.
If I didn’t use aspects, my code could look like:


I've already said that for this example I use LTW. So in the next few lines I will try to explain weaving process briefly. Weaving is process in which the class is transformed with defined aspect. In the next picture you can see illustration of weaving process.


For better understanding of weaving, you can consider it as code injection around the calling method, in this case.


Conclusion 


So in this example I’ve just covered some basic principles of aspect programming with AspectJ.
This aspect helped me to keep the code clean. The result of using aspect is clean separation of crossing-cut code and the code of real business value. The controllers, services and entity beans stayed clean and technical code is extracted in separate module which allow you to easier understand and maintain your code more easily. 
For more details information about defining pointcuts and general about AspectJ project you can see on the project page.

Comments

Popular posts from this blog

Checking file's "magic numbers"

Few days ago I had very interesting task. Our customer required that we perform checking of so called file's "magic numbers" to determinate does uploaded file correspond to it's extension.  We are already allowed only to upload files with some predefined extensions (PDF, DOC ...). But this can not prevent some evil user to update an exe file after renaming it to PDF or DOC. So first of all I will explain what are "magic numbers", and then I will show how we handle them.

Simple Workflow Engine With Spring

Few months ago, during working on one of the company project, we had need to developed  REST services which is used for sending an email depending on data sent by client application. During developing this service we decide to create simple workflow engine which will be charged for sending an email, but also this engine can be used for any kind of simple flows. In this article i will explain step by step how you can implement your simple workflow engine which can handle sequence flow.

Running Spring Boot Web App on the Random Port from Port Range

By default the spring boot web application is listening on the port 8080 for the incoming connection. This behavior can be changed by providing server.port property value during starting of the application or as part of the application.properties or through the code by implementing EmbeddedServletContainerCustomizer. But it would be even better if we could specified a range of the ports which can be used for the starting the application. It would be great if I could specify a property like server.portRange=8100..8200 to define a list of the port on which I want to start my service. In this blog post I will describe how this can be done.