Rod Bodkin — Using the Spring Framework for Aspect-Oriented Programming.
Page 2. This Talk Is About... ▫ Spring Overview. ▫ Aspect-Oriented Development.
Colorado Software Summit: October 22 – 27, 2006
© Copyright 2006, New Aspects of Software, Inc.
Using the Spring Framework for Aspect-Oriented Programming Ron Bodkin New Aspects of Software rbodkin@newaspects .com
Rod Bodkin — Using the Spring Framework for Aspect-Oriented Programming
Page 1
Colorado Software Summit: October 22 – 27, 2006
© Copyright 2006, New Aspects of Software, Inc.
This Talk Is About... Spring Overview Aspect-Oriented Development ¾ Concepts ¾ Tools and integration
Applications of AOP ¾ Exploration & enforcement ¾ Infrastructure ¾ Domain-Specific
Conclusion ¾ Adoption ¾ Lifecycle Use Rod Bodkin — Using the Spring Framework for Aspect-Oriented Programming
Page 2
Colorado Software Summit: October 22 – 27, 2006
© Copyright 2006, New Aspects of Software, Inc.
The Crosscutting Problem Auxiliary concerns are scattered and tangled ¾ data security ¾ performance monitoring ¾ business rules ¾ error handling
80% of problems come from this 20% of code ¾ inflexibility ¾ redundancy ¾ incomprehensibility
Rod Bodkin — Using the Spring Framework for Aspect-Oriented Programming
Page 3
Colorado Software Summit: October 22 – 27, 2006
© Copyright 2006, New Aspects of Software, Inc.
The AOP Solution Crosscutting is natural ¾can’t decompose requirements in one-dimension
The problem is a lack of support Aspects provide modular support for crosscutting Evolutionary step for software development: ¾structured Æ objects Æ aspects
Rod Bodkin — Using the Spring Framework for Aspect-Oriented Programming
Page 4
Colorado Software Summit: October 22 – 27, 2006
© Copyright 2006, New Aspects of Software, Inc.
Benefits Greater product flexibility Reduced development costs Enforcement of policy… Reliable implementation of policy Fewer intractable bugs
Rod Bodkin — Using the Spring Framework for Aspect-Oriented Programming
Page 5
Colorado Software Summit: October 22 – 27, 2006
© Copyright 2006, New Aspects of Software, Inc.
Spring Refresher http://www.springframework.org Open Source (Apache License) Inversion of Control Container ¾ Injects dependencies into POJOs ¾ Separates environment from core logic ¾ Supports testing
Bean definitions ¾ Usually XML beans file
Additional services and wrapping layers ¾ Servlet MVC, JDBC, EJB, ... Rod Bodkin — Using the Spring Framework for Aspect-Oriented Programming
Page 6
Colorado Software Summit: October 22 – 27, 2006
© Copyright 2006, New Aspects of Software, Inc.
Spring Bean Class: A POJO public class EmailValidator { private ValidationService remoteService; private List validDomains; public ValidationService getValidationService() { return remoteService; } public void setValidationService(ValidationService sv) { remoteService = sv; } … }
Rod Bodkin — Using the Spring Framework for Aspect-Oriented Programming
Page 7
Colorado Software Summit: October 22 – 27, 2006
© Copyright 2006, New Aspects of Software, Inc.
Spring Bean Definition XML .com.net
Bean properties can be strings, numbers, collections, or references to other beans
Rod Bodkin — Using the Spring Framework for Aspect-Oriented Programming
Page 8
Colorado Software Summit: October 22 – 27, 2006
© Copyright 2006, New Aspects of Software, Inc.
Spring Client Coding …
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml"); EmailValidator test = (EmailValidator) factory.getBean("emailValidator"); List domains = test.getDomains(); …
ApplicationContexts look up Beans by name ¾ Is normally used in a Session or Domain Factory
Typical implementations read Spring XML configuration file for Bean Definitions Rod Bodkin — Using the Spring Framework for Aspect-Oriented Programming
Page 9
Colorado Software Summit: October 22 – 27, 2006
© Copyright 2006, New Aspects of Software, Inc.
Spring AOP Live
DEMO
Rod Bodkin — Using the Spring Framework for Aspect-Oriented Programming
Page 10
Colorado Software Summit: October 22 – 27, 2006
© Copyright 2006, New Aspects of Software, Inc.
Example: Online Music Service Online music streaming Playlists have Songs Both Songs and Playlists can be played by a User
MeteringService Playable + play()
Playlist + play()
*
*
Song + play() + showLyrics()
Inspired by the "Implementing Observer in .NET" example at MSDN and Figures from the original AspectJ tutorial
Rod Bodkin — Using the Spring Framework for Aspect-Oriented Programming
Page 11
Colorado Software Summit: October 22 – 27, 2006
New Requirement: Metering User Activity
© Copyright 2006, New Aspects of Software, Inc.
When using titles ¾Individual songs… including lyrics ¾Playing play lists
Should track usage to allow charging user account Billing may vary on a number of factors ¾Monthly subscription ¾Daily pass ¾Per title ¾Promotions… Rod Bodkin — Using the Spring Framework for Aspect-Oriented Programming
Page 12
Colorado Software Summit: October 22 – 27, 2006
© Copyright 2006, New Aspects of Software, Inc.
Join Points : Client
: Playlist
key points in dynamic call graph
: Song
: Song
play()
Playlist.play()
play()
execution return play() Song.play() return
execution
return
Rod Bodkin — Using the Spring Framework for Aspect-Oriented Programming
Page 13
Pointcuts: Queries over Join Points
Colorado Software Summit: October 22 – 27, 2006
© Copyright 2006, New Aspects of Software, Inc.
Execution of Song.play() method
or
@Pointcut("execution(void model.Song.play()) || execution(void model.Song.showLyrics())") void useTitle() {}
Name and Parameters
Execution of Song.showLyrics() method
This pointcut captures the method execution join points of play() and showLyrics() Rod Bodkin — Using the Spring Framework for Aspect-Oriented Programming
Page 14
Colorado Software Summit: October 22 – 27, 2006
© Copyright 2006, New Aspects of Software, Inc.
Advice : Playlist
Playlist.play() execution
play()
Code that runs before, after, or instead of a join point @Pointcut(" execution(void m.Song.play()) || execution(void m.Song.showLyrics())") void useTitle() {}
Song.play() call
@AfterReturning("useTitle()") public void trackTitleUse() { //code to run after using a title }
Rod Bodkin — Using the Spring Framework for Aspect-Oriented Programming
Page 15
Colorado Software Summit: October 22 – 27, 2006
© Copyright 2006, New Aspects of Software, Inc.
An Aspect for Metering @Aspect public class MeteringPolicy { @Pointcut("execution(void model.Song.play()) || execution(void model.Song.showLyrics())") void useTitle() {} @AfterReturning("useTitle()") public void trackTitleUse() { MeteringService.trackUse(); } }
An aspect is a special type ¾Like a class that crosscuts other types ¾Can contain constructs like pointcuts and advice Rod Bodkin — Using the Spring Framework for Aspect-Oriented Programming
Page 16
Colorado Software Summit: October 22 – 27, 2006
© Copyright 2006, New Aspects of Software, Inc.
Metering 2
Metering Playables @Aspect public class MeteringPolicy { @Pointcut("execution(void model.Playable.play()) || execution(void model.Song.showLyrics())") void useTitle() {} @AfterReturning("useTitle()") public void trackTitleUse() { MeteringService.trackUse(); } }
Aspect now applies to Playlist and any other Playables (including Song) Rod Bodkin — Using the Spring Framework for Aspect-Oriented Programming
Page 17
Colorado Software Summit: October 22 – 27, 2006
© Copyright 2006, New Aspects of Software, Inc.
Metering 3
Exposing Context @Aspect public class MeteringPolicy { @Pointcut("(execution(void model.Playable.play()) || execution(void model.Song.showLyrics())) && this(playable)") void useTitle(Playable playable) {} @AfterReturning("useTitle(playable)") public void afterUseTitle(Playable playable) { MeteringService.trackUse(playable); } }
This version exposes the currently executing object at each join point (i.e. the Playlist or Song) using this() Rod Bodkin — Using the Spring Framework for Aspect-Oriented Programming
Page 18
Colorado Software Summit: October 22 – 27, 2006
© Copyright 2006, New Aspects of Software, Inc.
What Is Spring 2.0 AOP? Proxy-based AOP support for Java ¾ Integrated with Spring Bean Container ¾ Proxies generated at runtime ¾ Avoids time and complexity of weaving many classes ¾ Provides instance-based configuration
Two styles for defining Aspects: ¾@AspectJ style with Java 5 Annotations ¾XML Schema-based in Spring config file Supported Pointcuts ¾ execution, within, this, target, args, @within, @target, @args, @annotation Rod Bodkin — Using the Spring Framework for Aspect-Oriented Programming
Page 19
Colorado Software Summit: October 22 – 27, 2006
© Copyright 2006, New Aspects of Software, Inc.
Spring AOP Mechanisms javac
Song (.java source)
Song Bean Song (bytecode) Song Proxy
javac
MeteringPolicy (.java-source)
Spring Container
Metering Policy (bytecode)
Dynamic proxy creation per instance of advised beans Rod Bodkin — Using the Spring Framework for Aspect-Oriented Programming
Page 20
Colorado Software Summit: October 22 – 27, 2006
© Copyright 2006, New Aspects of Software, Inc.
Spring AOP Configuration
An empty Spring Beans config file with AOP support. Rod Bodkin — Using the Spring Framework for Aspect-Oriented Programming
Page 21
Colorado Software Summit: October 22 – 27, 2006
© Copyright 2006, New Aspects of Software, Inc.
Configuration 2
Spring AOP Configuration
Referencing an @AspectJ annotated class ¾Spring will automatically proxy advised Beans
Rod Bodkin — Using the Spring Framework for Aspect-Oriented Programming
Page 22
Colorado Software Summit: October 22 – 27, 2006
© Copyright 2006, New Aspects of Software, Inc.
Configuration 2
Spring AOP Configuration …
Song and PlayList beans will be autoproxied by the MeteringPolicy Aspect: database later
Rod Bodkin — Using the Spring Framework for Aspect-Oriented Programming
Page 23
Colorado Software Summit: October 22 – 27, 2006
© Copyright 2006, New Aspects of Software, Inc.
Java Implementation class PlayList{ private String name; private List entries = new ArrayList(); public void play() { for (Playable entry : entries) { entry.play(); } } }
class Song{ private String name; public void play() { // play song } public void showLyrics(){ // show lyrics } }
Rod Bodkin — Using the Spring Framework for Aspect-Oriented Programming
Page 24
Colorado Software Summit: October 22 – 27, 2006
© Copyright 2006, New Aspects of Software, Inc.
Metering 1
Java Implementation class PlayList{ private String name; private List entries = new ArrayList(); public void play() { for (Playable entry : entries) { entry.play(); } } }
class Song{ private String name; public void play() { // play song MeteringService.trackUse(); } public void showLyrics(){ // show lyrics MeteringService.trackUse(); } }
Rod Bodkin — Using the Spring Framework for Aspect-Oriented Programming
Page 25
Colorado Software Summit: October 22 – 27, 2006
© Copyright 2006, New Aspects of Software, Inc.
Metering 2
Java Implementation class PlayList{ private String name; private List entries = new ArrayList(); public void play() { for (Playable entry : entries) { entry.play(); } MeteringService.trackUse(); } }
class Song{ private String name; public void play() { // play song MeteringService.trackUse(); } public void showLyrics(){ // show lyrics MeteringService.trackUse(); } }
Rod Bodkin — Using the Spring Framework for Aspect-Oriented Programming
Page 26
Colorado Software Summit: October 22 – 27, 2006
© Copyright 2006, New Aspects of Software, Inc.
Metering 3
Java Implementation class PlayList{ private String name; private List entries = new ArrayList(); public void play() { for (Playable entry : entries) { entry.play(); } MeteringService.trackUse(this); } }
class Song{ private String name; public void play() { // play song MeteringService.trackUse(this); } public void showLyrics(){ // show lyrics MeteringService.trackUse(this); } }
Rod Bodkin — Using the Spring Framework for Aspect-Oriented Programming
• Metering code scattered through domain objects • No module captures intent and implementation of metering policy • Evolution of metering behavior cumbersome – Each caller must be changed – Easy to introduce bugs Page 27
Colorado Software Summit: October 22 – 27, 2006
© Copyright 2006, New Aspects of Software, Inc.
Spring AOP Implementation class PlayList{ private String name; private List entries = new ArrayList(); public void play() { for (Playable entry : entries) { entry.play(); } } }
class Song{ private String name; public void play() { // play song } public void showLyrics(){ // show lyrics } }
Rod Bodkin — Using the Spring Framework for Aspect-Oriented Programming
Page 28
Colorado Software Summit: October 22 – 27, 2006
© Copyright 2006, New Aspects of Software, Inc.
Metering 1
Spring AOP Implementation class PlayList{ private String name; private List entries = new ArrayList();
@Aspect class MeteringPolicy { @Pointcut("execution(void Song.showLyrics()) || execution(void Song.play())") void useTitle() {}
public void play() { for (Playable entry : entries) { entry.play(); } } }
@AfterReturning("useTitle()") public void trackTitleUse() { MeteringService.trackUse(); }
}
class Song{ private String name; public void play() { // play song } public void showLyrics(){ // show lyrics } }
Rod Bodkin — Using the Spring Framework for Aspect-Oriented Programming
Page 29
Colorado Software Summit: October 22 – 27, 2006
© Copyright 2006, New Aspects of Software, Inc.
Metering 2
Spring AOP Implementation class PlayList{ private String name; private List entries = new ArrayList();
@Aspect class MeteringPolicy { @Pointcut("execution(void Song.showLyrics()) || execution(void Playable.play())") void useTitle() {}
public void play() { for (Playable entry : entries) { entry.play(); } } }
@AfterReturning("useTitle()") public void trackTitleUse() { MeteringService.trackUse(); }
}
class Song{ private String name; public void play() { // play song } public void showLyrics(){ // show lyrics } }
Rod Bodkin — Using the Spring Framework for Aspect-Oriented Programming
Page 30
Colorado Software Summit: October 22 – 27, 2006
© Copyright 2006, New Aspects of Software, Inc.
Metering 3
Spring AOP Implementation class PlayList{ private String name; private List entries = new ArrayList();
@Aspect class MeteringPolicy { @Pointcut(“(execution(void Song.showLyrics()) || execution(void Playable.play()))") && this(playable)") void useTitle(Playable playable) {}
public void play() { for (Playable entry : entries) { entry.play(); }
@AfterReturning("useTitle(playable)") public void trackTitleUse(Playable playable) { MeteringService.trackUse(playable); }
} }
class Song{ private String name; public void play() { // play song } public void showLyrics(){ // show lyrics
}
Metering code centralized in MeteringPolicy • Intent of metering behavior is clear • Changes to policy only affect aspect • Modular evolution
} }
Rod Bodkin — Using the Spring Framework for Aspect-Oriented Programming
Page 31
Colorado Software Summit: October 22 – 27, 2006
© Copyright 2006, New Aspects of Software, Inc.
Double Billing Don’t want to meter twice for songs played within the context of playing a Playlist A ThreadLocal can be used to only meter top-level advice Can also accomplish using AspectJ control flow pointcuts (AspectJ is discussed later) ¾cflow() and cflowbelow()
Rod Bodkin — Using the Spring Framework for Aspect-Oriented Programming
Page 32
Colorado Software Summit: October 22 – 27, 2006
© Copyright 2006, New Aspects of Software, Inc.
Avoiding Double Billing ThreadLocal callDepth=...; @Around("useTitle(playable)") Public void aroundUseTitle(ProceedingJoinPoint jp, Playable playable) { try { callDepth.set(callDepth.get()+1); //increment counter jp.proceed(); //continue joinpoint if (callDepth.get()==1) //if first call MeteringService.trackUse(playable); } finally { callDepth.set(callDepth.get()-1); //decrement counter } }
Rod Bodkin — Using the Spring Framework for Aspect-Oriented Programming
Page 33
Colorado Software Summit: October 22 – 27, 2006
© Copyright 2006, New Aspects of Software, Inc.
Configuring Spring Aspects Aspects can reference externally defined services @Aspect public class MeteringPolicy { private AccountManager accountManager; private MeteringService meteringService; public void setAccountManager(AccountManager actManager) { this.accountManager = actManager; } public void setMeteringService(MeteringService mtrSvc) { this.meteringService = mtrSvc; } ... } Rod Bodkin — Using the Spring Framework for Aspect-Oriented Programming
Page 34
Colorado Software Summit: October 22 – 27, 2006
© Copyright 2006, New Aspects of Software, Inc.
Configuring Spring Aspects @AspectJ Aspects can be directly configured in Spring standard declarations
The MeteringPolicy Bean is declared with a standard declaration. An is defined referring to the MeteringPolicy Bean
Rod Bodkin — Using the Spring Framework for Aspect-Oriented Programming
Page 38
Colorado Software Summit: October 22 – 27, 2006
© Copyright 2006, New Aspects of Software, Inc.
Schema Style 3
Spring Configuration