13b-AspectWerkz_v36

Download Report

Transcript 13b-AspectWerkz_v36

AspectWerkz
Plain Java AOP
Presented by: Gal Ostfeld
January, 2005
Technion, Israel
Trivia
• Founded Q4 / 2002
• Founders:
– Jonas Boner, senior software
engineer at BEA
– Alexandre Vasseur, software
engineer at BEA
• Open source, by “codehaus” project
• Sponsored by BEA
Presale…
• AspectWerkz is a simple, high-performant, dynamic,
lightweight and powerful AOP for Java
• AspectWerkz offers both power and simplicity and
will help you to easily integrate AOP in both new
and existing projects
• AspectWerkz is a Java only solution that integrates
smoothly into current development processes,
IDEs, tools etc. without extending Java language
• AspectWerkz has been designed to have an
extensible AOP aspect container where any kind of
aspects can coexist, such as: AspectJ, AOP
Alliance, Spring etc.
Diving in – “Hello World!”
package testAOP;
public class HelloWorld {
public static void main(String args[]) {
HelloWorld world = new HelloWorld();
System.out.println(world.greet());
}
public String greet() {
return "Hello World!";
}
}
Now we write the aspect code
package testAOP;
import org.codehaus.aspectwerkz.joinpoint.JoinPoint;
public class MyAspect {
public void beforeGreeting(JoinPoint joinPoint) {
System.out.println("before greeting...");
}
public void afterGreeting(JoinPoint joinPoint) {
System.out.println("after greeting...");
} 1. Aspect methods need to take the JoinPoint argument
otherwise the AspectWerkz weaver won't be able to
}
identify the method when the aspect is weaved in
2. JoinPoint contains metadata & RTTI of this join point
3. In AspectWerkz 2.0 StaticJoinPoint can be used when
RTTI access isn’t needed, thus optimizing performance
Aspect class requirements
Any Java class can be an aspect providing…
AspectWerkz
call order
– The class must be public
– The method implementing the advice must be public
– There must be one of these two c’tor-s defined:
• An implicit/explicit default (no-arg) c’tor
• A c’tor taking an AspectContext instance as its only param
(enables to retrieve info about the runtime system, access
deployment time param-s, access meta-data etc.)
If no c’tor is found - an
exception is thrown
Specifying pointcuts and advice
methods
• At this point we have the test application and
the actual aspect code
• We still need to tell AspectWerkz where to
insert the aspect methods (“pointcuts”), and
which aspect method to actually insert
(“advice”)
• Specifying pointcuts and advice can be done
using either of (or a mixture of), the following
methods…
Method #1: XML definition file
Supports late (deployment time) binding
Loose coupling – code reuse
Aspect class name holding advices
<aspectwerkz>
<system id="AspectWerkzExample">The pointcut name is only
<package name="testAOP">
used to bind the advice
<aspect class="MyAspect">
Wildcards
<pointcut name="greetMethod"
expression="execution(* testAOP.HelloWorld.greet(..))"/>
<advice name="beforeGreeting" type="before" bind-to="greetMethod"/>
<advice name="afterGreeting" type="after" bind-to="greetMethod"/>
</aspect>
</package>
</system>
</aspectwerkz>
The name of the method
before/after/aroun
implementing the
d
advice Output:
before greeting...
Hello World!
after greeting...
Method #2: Annotations
Adding metadata to actual aspect class
– self contained & self defined aspect
package testAOP;
import org.codehaus.aspectwerkz.joinpoint.JoinPoint;
public class MyAspectWithAnnotations { Definition is strong
It is refactoring/tool
coupled to this app
/**
friendly
* @Around execution(* testAOP.HelloWorld.greet(..))
*/
In Java 1.3/1.4,
annotations are
public Object yeller(JoinPoint joinPoint) {
defined in JavaDoc
Object greeting = joinPoint.proceed();
style (In Java 1.5,
Java annotations
return "<yell>" + greeting + "</yell>";
are used)
}
Call joinPoint.proceed() to invoke the
}
next advice in the chain (or the target
method if there are no more advices)
which will return the result from the next
advice in the chain (or the target method)
Method #2: Annotations (cont.)
First you need to compile your aspect class files.
Then run a special AspectWerkz tool known as the
AnnotationC compiler (unless you use Java 5’s annotations)
<aspectwerkz>
<system id="AspectWerkzExample">
<aspect class="testAOP.MyAspectWithAnnotations"/>
</system>
</aspectwerkz>
Output:
<yell>Hello World!</yell>
You still have to create a tiny XML
'stub' which tells the AspectWerkz
runtime system which Java classes it
should load and treat as aspects
Combining XML and annotations can still make
the code reusable – though less tool friendly
Weaving in and running aspects
• There are two kinds of ways to actually weave the
code together:
– Online weaving
Performs weaving as classes are loaded into the JVM
1. Performing the weaving is done by using the
AspectWerkz tool to run java with the relevant
classes, pointing it to the definition XML file/stub
2. Doesn't modify any of the application classes
3. Hot deployment and undeployment of aspects
– Offline weaving
Done before the code is actually run
1. Amends your actual application classes definition
2. Running the aspect is just a matter of invoking the
main class
3. Statically compiled code can be highly tuned
In both cases you need AspectWerkz jar-s on your classpath
and you need to provide an XML definition file/stub
Weaving schemes
AspectWerkz offers three weaving schemes:
1. Post compilation of the application:
offline weaving at application build time
2. Class load time weaving: online weaving
at application deployment time
3. Runtime weaving: online weaving in a
running application
Online weaving – how is it done?
• Java 5 - The AspectWerkz weaver is embedded as
a Java standardized preMain agent in the JVM and
thus activated transparently before any call to the
main method
• HotSwap (Java 1.4) - A 1st tiny JVM launches your
target application in a 2nd JVM. The 1st JVM hooks
AspectWerkz in the 2nd before the main class +
dependencies gets loaded
• Bootclasspath (Java 1.3) - Putting an enhanced
class loader in the JVM bootclasspath
• BEA JRockit - The AspectWerkz weaver is
embedded as a ClassPreProcessor (native
mechanism) component in the JRockit JVM
Hot deployment
DeploymentHandle deploy
(
Class aspect,
String xmlDef,
DeploymentScope scope,
ClassLoader deployLoader
)
DeploymentHandles can be used for
undeployment - they
allow you to
undeploy the aspect
you deployed and
be sure that it will be
undeployed exactly
the way it was
deployed
This is useful only for aspects that have XML definitions
- they can have annotations as well, if so then the XML
definition will override the annotation definition
Hot undeployment
• void undeploy(Class aspect)
• void undeploy(Class aspect, ClassLoader
loader)
• void undeploy(DeploymentHandle
deploymentHandle)
All join points that were affected by a deployment
event will be reverted to the state they were in
before the deployment occurred. This means that
we need to keep track of order and dependencies
DeploymentHandle is used to revert to the state before
that deployment event defined by the handle occurred
Deployment scope
• It’s a special kind of pointcut which will prepare
the application and advise the points that we’re
interested in doing hot deployment on later
<deployment-scope name="toString" expression="execution(String *.toString())"/>
• We can then retrieve a handle to this
deployment scope and be sure that our aspect
will be deployed at valid points in our code that
suit us
DeploymentScope scope =
SystemDefinition.getDefinitionFor(loader, systemId)
.getDeploymentScope("toString");
Pointcut language
(some more presale)
AspectWerkz supports a finegrained pattern language for
picking out pointcuts
Pointcut language - wildcards
You can utilize three types of wildcards when
Constructing your patterns:
• “*” - Is used as a regular wildcard. Matches for
example only one package level or one method
parameter
• “..” - Two uses:
1. To match any sequence of characters that
start and end with a "." (so it can be used to
pick out all types in any sub-package)
2. In method selectors, to match as many
parameters as possible
• “+” - Is used to pick out all subtypes of a type
(including the type itself)
Pointcut language –
pointcut composition
To compose pointcut expressions you
can use the following logical operators:
• ! - logical not
• || or OR - logical or
• && or AND - logical and
• () - for grouping
Pointcut language – class selection
!private com.*.Stam*
public static com.pack.Stam
private com.package.Stam2
com.company.sub.Stam3
Pointcut language – method
selection
int method(*,java.lang.*,Number+)
int method(int i, String s, Long l)
int method(int i1, int i2, Long l)
int method(int i, Long l)
Java.lang.* me*o*(int,..)
StringBuffer method(int i)
String meo(int i, String s , Object o)
int method(int i, double d).
Pointcut language – field selection
java.lang.* *_*
StringBuffer m_
int s_inputString
String _
Pointcut language – pointcut types
•
•
•
•
•
•
•
•
•
•
•
•
execution() – method or c’tor execution
call() – method or c’tor call
set() - field modification
get() – field access
handler() – (before) catch clause
within() - picks out a type set
withincode() - picks out a method or c’tor set
hasmethod() - picks out a class that has a method or
c’tor matching a given pattern
hasfield() - picks out a class that has a field matching
a given pattern
args() - filter method or c'tor param-s and field types
and retrieving and keeping references to them.
this()/target() - narrow a pointcut expression based on
caller/callee types or gain access to them in the advice
cflow() - defining a control flow
Pointcut references –
code reuse
• Pointcuts defined in one aspect can be
referred in another aspect definition.
• This can be very useful when building up
pointcut libraries that need to be used
throughout a project or multiple projects.
Passing parameters to aspects
• There’s an option of passing parameters to aspects
• This can be very convenient in order to reuse the same
aspect but with a different configuration
• To pass a parameter to the aspect add a param tag to
the aspect definition:
<aspect ... >
<param name="timeout" value="10"/>
</aspect>
• To get the parameter (from within an aspect) use the
AspectContext.getParameter(String paramName)
method to retrieve the parameter value (as a String)
• To set a new (or override) a parameter (from within an
aspect) use the AspectContext.setParameter(String
paramName, String paramValue) method
Deployment models
AspectWerkz supports four different
deployment models, which define the scope
of the Aspect:
1. perJVM - one instance per JVM
2. perClass - one instance per class
3. perInstance - one instance per instance
4. perThread – one instance per thread
Extensible aspect container
architecture - background
• In recent years the Java AOP landscape has
become filled with a whole bunch of frameworks,
each one with its own way of defining and
instantiating its aspects and with its own weaver,
runtime environment and tools
• This isn’t making it easier for new users of AOP
and doesn’t speed up its adoption
• Most existing frameworks have a lot in common
Extensible aspect container
architecture - outcome
• The above situation encouraged AspectWerkz
designers to design an open architecture that
allows you to plug in extensions that can handle
the framework specific details, while the common
things are shared
• AspectWerkz architecture holds a weaver and a
container that can weave, deploy and run any
aspect no matter how it is implemented and
defined
• Thus there’s a basis for standardization on tools
(development and runtime manageability)
Extensible aspect container
architecture - example
time
Let’s illustrate what happens when a method has been
advised by a “before” advice on “execution” (callee) side:
unadvised application
Extensible aspect container
architecture – conclusions
• The diagram will be the same no matter how the
advice has been implemented
• There are parts (like "how to get the advised
member arguments?" ) that are independent of
the implementation details of the aspect and thus
can be solved in the same way no matter what
framework we would use (→part of the aspect
container)
• Other parts (like "how to get an aspect instance?“)
that are framework specific (→part of the
extension implementation)
Extensible aspect container
architecture - illustration
Aspects
belonging to
different aspect
models
Each extension is seen
as an aspect model and
is implemented by
implementing the
AspectModel interface
AspectWerkz 2.0 modules
Aspects from
different aspect
models can coexist
in one single
runtime
environment
AspectWerkz custom extensions
If you want to plug in your own AOP framework into the AspectWerkz
Extensible Container then:
1. Implement the AspectModel interface
public interface AspectModel {
String getAspectModelType();
boolean requiresReflectiveInfo();
AroundClosureClassInfo getAroundClosureClassInfo();
void defineAspect(..);
void createMandatoryMethods(..);
void createInvocationOfAroundClosureSuperClass(..);
void createAspectReferenceField(..);
void createAspectInstantiation(..);
void createAroundAdviceArgumentHandling(..);
void createBeforeAdviceArgumentHandling(..);
void createAfterAdviceArgumentHandling(..);
}
2. Register your extension and the container will manage the
weaving, deployment, life-cycle management etc.
AspectWerkz
the next generation
AspectWerkz intends to have one single aspect
container and internal representation but make
the weaver pluggable, so that different strategies
of doing the actual weaving could be plugged in
Benchmark
• All advices did the same amount of work
• The numbers in the table show how many nanosec-s
per iteration, where an iteration is the invocation of the
advice and the advised method
• “after” advices produced identical
results as “before” advices
• The best performance (of advised
invocation) per advice type is colored green
Benchmark results analysis
• The Spring extension was as expected much
faster than the Spring system since it
enjoyed the optimization benefits of static
compilation
• AspectJ, AspectJ extension and
AspectWerkz were pretty similar in the
“before” (and “after”) advices
• The “around” advices’ landslide of AspectJ
over AspectJ extension and AspectWerkz is
explained by the AspectJ compiler inlining
the advice body in the target class
News flash:
Last minute update…
In the last few days the AspectWerkz site
has released the following statement:
“The AspectJ and AspectWerkz projects
have agreed to work together as one team
to produce a single aspect-oriented
programming platform building on their
complementary strengths and expertise…”
News flash:
Last minute update…(cont)
“The combined strengths of the two teams
will enable us to deliver a more
comprehensive technology suite more
quickly than either team could alone. The
backing of two major vendors (IBM and BEA)
and a large open source community will
accelerate the adoption of AOP in the
enterprise…”
News flash:
Last minute update…(cont)
“This will begin with an extension to the
AspectJ language to support an
annotation-based style of development,
and with tighter integration of load-time
weaving for AspectJ in the J2EE
environment…
AspectJ 5 will also have extended
deployment options for load-time weaving,
supporting aop.xml deployment files in the
style of AspectWerkz.”
Summary
• Powerful, expressive and simple AOP
framework
• JLS compatible (does not extend Java)
• Definition syntax in XML or annotations (or
JavaDoc style annotations)
• Build time/Load time/Run time weaving
• Hot Deployment and Undeployment
• High performance
• Tailored for dynamic and static AOP in real
world applications
• Infrastructure extendable to be compatible
with other AOP frameworks