Aspect-Oriented Programming (AOP) with Spring.Net
Listing 11: Pointcut Configuration Example: Security Check Before Advice
<!-- Pointcut Example: Security Check w/ Before Advice --> <object id="securityCheckBeforeAdvice" type="Spring.Aop.Support.RegularExpressionMethodPointcutAdvisor"> <!-- Only run for methods starting with "save" --> <property name=" value="save" /> <property name="advice" ref="securityCheckBeforeAdviceTarget" /> </object> <object id="securityCheckBeforeAdviceTarget" type="SpringAOPExample.Aspects.SecurityCheckBeforeAdvice" /> <!-- Example Service Proxy w/ Advice Applied --> <object id="exampleService" type="Spring.Aop.Framework.ProxyFactoryObject"> <property name="target" ref="exampleServiceTarget" /> <property name="interceptorNames"> <list> <value>performanceLoggingAroundAdvice</value> </list> </property> </object> <object id="exampleServiceTarget" type="SpringAOPExample.Service.Impl.ExampleServiceImpl"> <!-- Note: This is just a standard service object. Inject dependencies as needed (ie. DAOs, Other Services). --> </object>
Here, you use the Spring.Aop.Support.RegularExpressionMethodPointcutAdvisor class to specify some criteria for running the advice. You define a method pattern to match via the "pattern" property. For this example, the advice will be applied only when the method name begins with "save". So in effect, the security check advice will execute only when the user runs a method like saveObject() where you want security applied and not for other methods like getObject() where everyone has access and you don't need security.
Stacking Advice
For the last topic, let me talk about stacking advice. So far, you have only been applying one piece of advice at a time, but there are many cases where you will want to run several pieces of advice on the same methods. Well, in Spring.Net this is not a problem. Just add all the pieces of advice you want to run to the "interceptorNames" list in the configuration.
Listing 12: Advice Stacking Example
<!-- Example Service Proxy w/ Advice Applied --> <object id="exampleService" type="Spring.Aop.Framework.ProxyFactoryObject"> <property name="target" ref="exampleServiceTarget" /> <property name="interceptorNames"> <list> <value>methodLoggingBeforeAdvice</value> <value>methodLoggingAfterAdvice</value> <value>performanceLoggingAroundAdvice</value> <value>errorHandlingThrowsAdvice</value> <value>securityCheckBeforeAdvice</value> </list> </property> </object> <object id="exampleServiceTarget" type="SpringAOPExample.Service.Impl.ExampleServiceImpl"> <!-- Note: This is just a standard service object. Inject dependencies as needed (ie. DAOs, Other Services). --> </object>
Now, all of the advice will run when you call the various example service functions. Here is a quick test run of everything you have covered in this article; the resulting output is shown in Figure 1.
Listing 13: Example Test Code
// Get Spring.Net context using (IApplicationContext ctx = ContextRegistry.GetContext()) { // Get the example service ExampleService exampleService = (ExampleService)ctx.GetObject("exampleService"); // Run some operations to see the aspects in action Console.WriteLine("Example: Get Object"); exampleService.getObject(25); Console.WriteLine("\nExample: Save Object"); exampleService.saveObject("testSaveObject"); Console.WriteLine("\nExample: Run Operation"); exampleService.runOperation("testRunObject"); Console.WriteLine("\nExample: Run Operation With Error"); exampleService.runOperationWithError("testRunErrorObject"); }
Page 5 of 6
This article was originally published on January 8, 2009