JBoss.org Community Documentation

5.3. Applying an aspect

Now that we have a valid distribution containing everything we need we can configure our jboss-beans.xml file to apply the audit aspect. This can be found in the examples/User_Guide/gettingStarted/commandLineClient/target/client-aop.dir directory:


<?xml version="1.0" encoding="UTF-8"?>

<deployment xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation="urn:jboss:bean-deployer:2.0 bean-deployer_2_0.xsd"
            xmlns="urn:jboss:bean-deployer:2.0">

    <bean name="AspectManager" class="org.jboss.aop.AspectManager">
        <constructor factoryClass="org.jboss.aop.AspectManager"
                             factoryMethod="instance"/>
    </bean>

    <aop:aspect xmlns:aop="urn:jboss:aop-beans:1.0"
                       name="AuditAspect" class="org.jboss.example.aspect.AuditAspect"
                       method="audit" pointcut="execution(public org.jboss.example.service.HRManager->new(..)) OR                                        execution(public * org.jboss.example.service.HRManager->*(..))">
    </aop:aspect>

    ...

</deployment>

Before we can apply our aspect to any classes we need to create an instance of org.jboss.aop.AspectManager using a <bean> element. We use a factory method instead of calling a conventional constructor as we only want one instance of the AspectManager in the JVM at runtime i.e. it is a singleton.

Next we create an instance of our aspect called AuditAspect using the <aop:aspect> element. This looks much like the <bean> element as it has name and class attributes that you can use in the same way. However it also has method and pointcut attributes that you can use to apply or 'bind' an advice within the aspect to constructors and methods within other classes. We use these attributes to bind the audit advice to all public constructors and methods within the HRManager class. We only need to specify one method called audit as we have overloaded this method within our AuditAspect class with different parameters. JBoss AOP knows at runtime which one to select based on whether a constructor or method invocation is being made.

This additional configuration is all we need to apply the audit aspect at runtime and add auditing behaviour to the Human Resources service. You can test this out for yourself by running the client using the run.sh script. A log directory will be created on startup alongside the lib directory as the AuditAspect bean is created by the microcontainer. Each deployment of the Human Resources service will then cause a new log file to appear within the log directory containing a record of any calls made from the client to the service:

log/auditLog-28112007-163902
   /auditLog-28112007-164055
   /auditLog-28112007-164108

The audit records inside the log files will look something like this:

Method: getEmployees Return: []
Method: addEmployee Args: (Santa Claus, 1 Reindeer Avenue, Lapland City - 25/12/1860) Return: true
Method: getSalary Args: (Santa Claus, null - Birth date unknown) Return: 10000
Method: getEmployees Return: [(Santa Claus, 1 Reindeer Avenue, Lapland City - 25/12/1860)]
Method: isHiringFreeze Return: false
Method: getEmployees Return: [(Santa Claus, 1 Reindeer Avenue, Lapland City - 25/12/1860)]
Method: getSalaryStrategy

If you wish to remove the auditing behaviour then you can simply comment out the relevant fragments of XML in the deployment descriptor and restart the application.

Warning

The order of deployment for aspects declared in this way relative to normal beans matters in the deployment descriptor. Specifically each aspect must be declared before the beans that it applies to so that the microcontainer deploys them in that order. This is because the microcontainer may need to alter the bytecode of the normal bean class in order to add the cross-cutting logic before it creates an instance and stores a reference to it in the controller. If a normal bean instance has already been created then this is not possible.