The Guice dependency injection library from Google comes with a whole host of added goodies including Method interception. I have been somewhat obsessed with code quality of late and wanted to use method interception to this end. This article talks about using method interceptors to inspect the parameters for a method and implement boiler plate checks such as null parameters without code repetition. As a simple example I will be implementing a check for null arguments.
As a starting point of this implementation I will be using the sample code from an earlier article Setting up a webservice using Guice & Sitebricks</strong> which can be downloaded from Github. The completed project code can also be downloaded from Github here.The source code for this project is released under the BSD License.
Defining the annotation
In order to mark the methods for which we wish to ensure non-null parameters we will define a custom Annotation “NotNull”. The code for defining an annotation is shown below. We are defining that this is a Runtime annotation using the @Retention meta annotation. Similarly we use the @Target meta annotation to define that this annotation can only be applied to methods.
Defining the method interceptor
In order to create our method interceptor we create a class to implement the org.aopalliance.intercept.MethodInterceptor interface and override the invoke method. We get an instance of the org.aopalliance.intercept.MethodInvocation class passed into the invoke method as a parameter. we can then query the getArguments method of the MethodInvocation class to retrieve all of the arguments. As shown in the code below we then traverse the list of arguments and check if they are null. We could implement any number of validation checks on the arguments at this point. If any of the validations fail we would throw an exception with details of the failure.
In order for the interceptor to be invoked we must configure guice to link the annotation to the interceptor. We do this in the GuiceCreater class as part of the bind function of the sitebricks module. We use the bindInterceptor call to link all elements (Matchers) annotated with our NotNull annotation to our interceptor class NotNullInterceptor.
Testing the code
Now all that is left is to take our interceptor for a spin. Create a doSomething(String something) method in the HelloWorld sitebrick (HelloWorld.java). and annotate the method with the NotNull. Also call the method with a null parameter. See code below.
Now compile the code using mvn clean install and run it using mvn jetty:run (See Setting up a webservice using Guice & Sitebricks” for details). To run the code browse to http://localhost:8080/helloworld.
Method interceptors can be useful for a variety of things and a lot of boiler plate code can be written once and hidden away within interceptors. There are other solutions available for the null argument check we can implement a whole host of project specific or domain specific annotations and validation checks.