Cours IUT - CSID 2012 - Arnaud Nauwynck .fr

What is AOP (Java) ? … Google It. ○ Not to confound with french. “Appélation d'Origine Protégée”, or .... “interface IFoo { void foo(); }” + “class...implements IFoo”.
1MB taille 0 téléchargements 292 vues
Cours IUT - CSID 2012 An Introduction to AOP: Aspect Oriented Programming

[email protected] This document: http://arnaud.nauwynck.free.fr/CoursIUT/CoursIUT-IntroAOP.pdf

Outline ●

What is AOP ? Samples usages



Java.lang.Proxy, InvocationHandler



AspectJ



Bytecode Generator/Loader/Weaver



Java VM Agent

What is AOP (Java) ? … Google It



Not to confound with french “Appélation d'Origine Protégée”, or “Amplificateur Opérationnel”, ...

Wikipedia

AOP Keywords ●

AOP = Aspect Oriented Programming



To be compared with OO : Object Oriented





Separation of Cross-Cutting Concerns, Orthogonal Aspects in code Other Keywords: Meta-Programming, Programming Paradigm, Technical vs Functional Code, Annotation Based Programming

Cross-Cutting Concerns ? ●

Logging



Auditing



Security Check



Monitoring : Performance Time, Call Counters



Transaction Management (ACID)



...

Sample Aspect: Logging ●

Log : before / before+after / before+after+exceptions?

Sample Aspect: Logging “Around” with try-catch

Around Aspect: Try-catch => log

Functional Code

Sample Before Aspect for Security

Sample Aspect For Performance Time Monitoring

A Very Important “Aspect” : Transactional ●

ACID Principles: All or Nothing …

Combining 4 Simple Orthogonal Aspects...

4 x 1 Simple Aspects + N x functional Codes = ?? ●





Code is linear but no more simple / readable Copy & Paste the wrapper aspects everywhere in your code ?? not maintainable... => NEED a change of Programming Paradigm

AOP Goal = Split Concerns ●

Use 1 File/Method/Other-Langage per Aspect … (*.java Proxy, *.aj, *.xml, annotation...) = “Advice”, Proxy InvocationHandler



Use detection pattern to apply to N x code (*.java Proxy, *.aj, *.xml, annotation...) = “Joint Point”, “PointCut”, Proxy



Result Code = Combining Advice + User-Code

Solution : AOP … Spring +AspectJ

Sample Solution Code : Spring + AspectJ *.aj or @Aspect externallydefined

@Annotation based

Spring Xml Configuration

Sample Externally Defined AOP with AspectJ 1.6 (@Aspect)

Code + Pointcut/Advice => Weaved Code Compiler or Runtime Inputs

User Code1

User Code2

User Code...

Proxy Wrapper Weaved Code2

Proxy Wrapper Weaved Code2

Logging Aspect Security Aspect

Result

Intermediates ...

Transact Aspect Monitoring Aspect

Proxy Wrapper Weaved Code1

PointCut Detection Pattern ●

Define Where / Where-NOT to apply Advice User Code1 @Log, @Mon

User Code2 @Secure,@XA

User Code... @Log @XA, @Mon

Logging Aspect Security Aspect NO match Transact Aspect match Monitoring Aspect

Use Proxy and/or Weaver Compile/Runtime/Agent

Proxy Wrapper Weaved Code1

Proxy Wrapper Code2

Weaved Code 3

Weaving/Wrapping Strategies ●

LOT Of Possibilities !!!



User define *.java: new Proxy(..)



*.xml => new Proxy() in Injection context (Spring)



*.java => *.java



*.java => *.class (byte-code generator)



*.class => *.class (byte-code weaver)



*.class => ClassLoader byte[] dynamic weaver



byte[] => JVM agent byte[]

(javac compiler agent)

dynamic weaver

Simplest Approach : User Code on Objects... Not on Methods ●



“Static Method” can not be overloaded (cf Groovy) Use Object-Oriented pointer + override instead of static methods instead of

“public static void foo() {...}”

prefer: “interface IFoo { void foo(); }” + “class...implements IFoo” ●

With Typed-safe interfaces => Design Pattern names: Proxy, Adapter, Delegate, Bridge, Command, ...

Sample User Proxy / Delegate

Using java.lang.reflect.* Proxy, InvocationHandler ●

Goal: define a “generic” Proxy pattern ●





For any interface … not only for Foo/Bar classes

java.lang.reflect.Proxy for wrapping underlying object class with static methods only, no public constructor! Proxy.newProxyInstance() java.lang.reflect.InvocationHandler for handling calls to proxy methods

Sample java.lang.reflect.Proxy

Proxy

Underlying Inkoke

Debugging Stack Trace with Proxy + Method.Invoke()

● ●

traversing 6-levels at debugging-time … BUT efficient (bytecode is generated + HOTSPOT optimized)

Proxy Class : “$Proxy123..” ??

Analyzing $Proxy123 Class

$Proxy123 Class Pseudo code ●

generated bytecode ~=

transform () => proxy.h.execute(..)

Reflection Duality ... User code => Proxy Proxy => generic InvocationHandler InvocationHandler => reflect Method.invoke() Method.invoke() => user code

Method.invoke() pseudo code ●

Method are instances of java.lang.reflect.Method -> delegating to sun.reflect.MethodAccessor



0-1 singleton MethodAccessor per compile-time method



Pseudo equivalent code:

MethodAccessor Pseudo code GeneratedMethodAccessor123

Method.invoke() Optimizations ●





On first call => use delegate + NativeMethodAccessor ...after few calls => replace delegate with generated bytecode !! class “GeneratedMethodAccessor” … after many calls => bytecode is optimized natively by HOTSPOT !! Method

DelegatingMethodAccessor

MethodAccessor

NativeMethodAccessor

GeneratedMethodAccessor123

MethodAccessor Internals …

Optimized Call Stack Method.invoke() Generated / Native

Usages of java.lang.reflect.Proxy ● ●



Frameworks like Spring use it intensively User Interfaces not known at compilation-time but code is generic !! => at Runtime ● ●



Read Xml file Interpret @Annotation (@Transactional, @PreAuthenticate, ...) wrap Spring beans by Spring Dynamic Proxies

AspectJ ●

AspectJ : (eclipse.org) Open-Source project ●

A Runtime jar



A Compile-time weaver



Maven / Eclipse / … plugins

AspectJ-Maven-Plugin

AspectJ Sample in Spring-Roo ITD : Inter-Type-Definition

Class name to inject (compile-time) field / methods

Last But Not Least JVM Agent … ●

Startup & Triggers can be defined at JVM layer!



Keywords : ●

JVM Agent

-javaagent:myag.jar or -Xrunagent:myag.jar ● ● ● ● ●

Instrumentation ClassFileTransformer Classloading Bytecode Weaver JavaAssist / BCEL Monitoring Agent

Sample Example: onClassLoader.load => add ( => parse bytecode + inject bytecodes + write bytecode replacement )

premain(Instrumentation) … ClassFileTransformer

Bytecode => JavaAssist/BCEL =>

Conclusion Java AOP is Beautiful !! Questions ? [email protected] This document: http://arnaud.nauwynck.free.fr/CoursIUT/CoursIUT-IntroAOP.pdf