JBoss.org Community Documentation

5.1. Creating an aspect

The examples/User_Guide/gettingStarted/auditAspect directory contains all the files you need to create the aspect.

auditAspect/pom.xml
           /src/main/java/org/jboss/example/aspect/AuditAspect.java

As you can see from the source code below all we need is a simple POJO.


public class AuditAspect {

    private String logDir;
    private BufferedWriter out;

    public AuditAspect() {
        logDir = System.getProperty("user.dir") + "/log";

        File directory = new File(logDir);
        if (!directory.exists()) {
            directory.mkdir();
        }
    }

    public Object audit(ConstructorInvocation inv) throws Throwable {
        SimpleDateFormat formatter = new SimpleDateFormat("ddMMyyyy-kkmmss");
        Calendar now = Calendar.getInstance();
        String filename = "auditLog-" + formatter.format(now.getTime());

        File auditLog = new File(logDir + "/" + filename);
        auditLog.createNewFile();
        out = new BufferedWriter(new FileWriter(auditLog));
        return inv.invokeNext();
    }

    public Object audit(MethodInvocation inv) throws Throwable {
        String name = inv.getMethod().getName();
        Object[] args = inv.getArguments();
        Object retVal = inv.invokeNext();

        StringBuffer buffer = new StringBuffer();
        for (int i=0; i < args.length; i++) {
            if (> 0) {
                buffer.append(", ");
            }
            buffer.append(args[i].toString());
        }

        if (out != null) {
            out.write("Method: " + name);
            if (buffer.length() > 0) {
                out.write(" Args: " + buffer.toString());
            }
            if (retVal != null) {
                 out.write(" Return: " + retVal.toString());
            }
            out.write("\n");
            out.flush();
        }
        return retVal;
    }
}

The constructor checks for the presence of a log directory in the current working directory and creates one if not found. After this we define an advice that will be called whenever the constructor of our target class is called. The purpose of this is to create a new log file within the log directory so that we can record method calls made on different instances of our target class in separate files. Finally we define an advice that will apply to each method call made on the target class. Here we store the method name and arguments together with the return value so that we can construct an audit record and write it to the current log file. Notice how each advice calls inv.invokeNext(). This is required in order to call the next advice, if more than one cross-cutting concern has been applied, or to call the target constructor/method.

Note

Each advice is implemented using a method that takes an invocation object as a parameter, throws Throwable and returns Object. This is necessary as we do not know at design time which constructors or methods our advices will be applied to so the types must be as generic as possible. For more information on creating aspects and advices together with additional examples of how to apply them to various classes please consult the JBoss AOP project documentation.

To compile the class and create an auditAspect.jar file that can be used by other examples simply type mvn install from the auditAspect directory.