JBoss.org Community Documentation
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.
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.