In this post I would like to describe the simpliest use of AspectJ in a maven project. Sources of sample project are available here: sample AspectJ maven project download.
When you are facing the problem of code repetition (logging method calls, user authentication, etc.) it might be worth considering using aspect oriented programming.
Here I present really simple maven project which may be helpful to start programming with aspectJ.
Let's have a look at this simple example:
public class AreasReformingVisitor implements AreasVisitor {
@Override
public void visit(Poland poland) {
poland.makeEveryoneRich();
}
@Override
public void visit(Krakow krakow) {
krakow.buildTheUnderground();
}
@Override
public void visit(Warsaw warsaw) {
warsaw.createNationalStadium();
}
}
Here we have AreasReformingVisitor which makes fundamental reforms to various areas. Let's imagine the government not only wants to reform the country, but also archive all the changes to have good start in next year's elections ;)
Let's add some propaganda abilieties to the class:
public class AreasReformingVisitor implements AreasVisitor {
private String stateChangeArchive = "";
//visit methods like above
public void archiveAreaStateChange(Area area) {
stateChangeArchive += "State just before visit (" + new Date() + "): "
+ area.getAreaState() + "\n";
}
public String getStateChangeArchive() {
return stateChangeArchive;
}
}
Ok. So the easiest way to make use of archiveAreaStateChange method could be:
@Override
public void visit(Poland poland) {
archiveAreaStateChange(poland);
poland.makeEveryoneRich();
}
@Override
public void visit(Krakow krakow) {
archiveAreaStateChange(krakow);
krakow.buildTheUnderground();
}
@Override
public void visit(Warsaw warsaw) {
archiveAreaStateChange(warsaw);
warsaw.createNationalStadium();
}
We simply add archiving method invocation in front of each main body of visit methods. It may seem easy and simple solution, but wait a moment. What if there were more visit methods or more archiving features we would like to add? Way to much copy-paste technique and problems with future refactoring!
Let's use AspectJ to "inject" archiving code just before each visit method execution.
import pl.mefju.aspectJDemo.visitor.AreasReformingVisitor;
import pl.mefju.aspectJDemo.areas.Area;
public aspect VisitedPlaceStateArchivingAspect {
pointcut visitExecution(AreasReformingVisitor areasReformingVisitor, Area area) :
execution(* *.visit(..)) && this(areasReformingVisitor) && args(area);
before(AreasReformingVisitor areasReformingVisitor, Area area) :
visitExecution(areasReformingVisitor, area) {
areasReformingVisitor.archiveAreaStateChange(area);
}
}
AspectJ maven dependency:
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.6.7</version>
</dependency>
AspectJ maven plugin configuration to enable weaving:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.3</version>
<executions>
<execution>
<configuration>
<complianceLevel>1.6</complianceLevel>
<aspectDirectory>src/main/aspectj</aspectDirectory>
</configuration>
<goals>
<goal>compile</goal>
<!-- use this goal to weave all your main classes -->
<goal>test-compile</goal>
<!-- use this goal to weave all your test classes -->
</goals>
</execution>
</executions>
</plugin>