Using the Spring Framework for Aspect-Oriented Programming

5 downloads 861 Views 657KB Size Report
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