[jboss-cvs] JBossAS SVN: r78543 - in projects/aop/trunk/aop/docs/reference/reference/en: modules and 1 other directory.
jboss-cvs-commits at lists.jboss.org
jboss-cvs-commits at lists.jboss.org
Mon Sep 15 10:18:40 EDT 2008
Author: kabir.khan at jboss.com
Date: 2008-09-15 10:18:40 -0400 (Mon, 15 Sep 2008)
New Revision: 78543
Added:
projects/aop/trunk/aop/docs/reference/reference/en/modules/modes.xml
Modified:
projects/aop/trunk/aop/docs/reference/reference/en/master.xml
projects/aop/trunk/aop/docs/reference/reference/en/modules/dynamic.xml
Log:
[JBAOP-383] Document instrumentation modes
Modified: projects/aop/trunk/aop/docs/reference/reference/en/master.xml
===================================================================
--- projects/aop/trunk/aop/docs/reference/reference/en/master.xml 2008-09-15 14:14:37 UTC (rev 78542)
+++ projects/aop/trunk/aop/docs/reference/reference/en/master.xml 2008-09-15 14:18:40 UTC (rev 78543)
@@ -13,6 +13,7 @@
<!ENTITY compiling SYSTEM "modules/compiling.xml">
<!ENTITY running SYSTEM "modules/running.xml">
<!ENTITY reflection SYSTEM "modules/reflection.xml">
+<!ENTITY modes SYSTEM "modules/modes.xml">
<!ENTITY maven SYSTEM "modules/maven.xml">
]>
@@ -106,6 +107,8 @@
&running;
&reflection;
+
+ &modes;
</book>
Modified: projects/aop/trunk/aop/docs/reference/reference/en/modules/dynamic.xml
===================================================================
--- projects/aop/trunk/aop/docs/reference/reference/en/modules/dynamic.xml 2008-09-15 14:14:37 UTC (rev 78542)
+++ projects/aop/trunk/aop/docs/reference/reference/en/modules/dynamic.xml 2008-09-15 14:18:40 UTC (rev 78543)
@@ -2,8 +2,8 @@
<title>Dynamic AOP</title>
- <sect1 id="dyn-2" revision="1">
- <title>Hot Deploment</title>
+ <sect1 id="dyn-1" revision="1">
+ <title>Hot Deployment</title>
<para>
With JBoss AOP you can change advice and interceptor bindings at runtime. You can unregister
existing bindings, and hot deploy new bindings if the given joinpoints have been instrumented.
@@ -16,7 +16,8 @@
There is also a runtime API for adding advice bindings at runtime. Getting an instance of
<literal>org.jboss.aop.AspectManager.instance()</literal>, you can add your binding.
</para>
- <programlisting> org.jboss.aop.advice.AdviceBinding binding = new AdviceBinding("execution(POJO->new(..))", null);
+ <programlisting> org.jboss.aop.advice.AdviceBinding binding =
+ new AdviceBinding("execution(POJO->new(..))", null);
binding.addInterceptor(SimpleInterceptor.class);
AspectManager.instance().addBinding(binding);</programlisting>
<para>
@@ -28,7 +29,7 @@
</para>
</sect1>
- <sect1 id="dyn-3" revision="1">
+ <sect1 id="dyn-2" revision="1">
<title>Per Instance AOP</title>
<para>
Any class that is instrumented by JBoss AOP, is forced to implement the
@@ -66,8 +67,7 @@
interceptors that are added with the
<literal>insertInterceptor()</literal> method for the given object
instance are executed first. Next, those advices/interceptors that were bound using regular
- <literal>bind</literal>s
- . Finally, those interceptors added with the
+ <literal>bind</literal>s. Finally, those interceptors added with the
<literal>appendInterceptor()</literal> method to the object
instance are executed. You can also reference
<literal>stack</literal>s and insert/append full stacks
@@ -79,7 +79,7 @@
</para>
</sect1>
- <sect1 id="dyn-1" revision="1">
+ <sect1 id="dyn-3" revision="1">
<title>Preparation</title>
<para>
Dynamic AOP cannot be used unless the particular joinpoint has been instrumented. You can force intrumentation
@@ -87,7 +87,108 @@
<literal>prepare</literal> functionality
</para>
</sect1>
+
<sect1 id="dyn-4" revision="1">
+ <title>Improved Instance API</title>
+ <para>
+ As mentioned, you can add more aspects to a woven class using the
+ <literal>org.jboss.aop.InstanceAdvisor</literal>. This API is limited to adding
+ interceptors to the existing intereptor chains, so it is a bit limited.
+ </para>
+ <para>
+ The new default weaving mode introduced in JBoss AOP 2.0.0 still allows you access to the
+ <literal>InstanceAdvisor</literal> interface, but also offers a fuller instance API, which allows you to add bindings,
+ annotation overrides etc. via the normal dynamic AOP API. This is underdocumented,
+ but for a full overview of the capabilites take a look at how
+ <literal>org.jboss.aop.AspectXmlLoader</literal> interacts with
+ <literal>org.jboss.aop.AspectManager</literal>. We are working on a new tidier API for
+ the next version of JBoss AOP. Normally, for dynamic AOP you add
+ things to the top level <literal>AspectManager</literal>, which means that all instances
+ of all woven classes can be affected.
+ </para>
+ <para>
+ In JBoss AOP 2.0.0, each aspectized class has its own Domain. A domain is a sub-AspectManager.
+ What is deployed in the main AspectManager is visible to the class's domain, but not vice versa.
+ Furthermore each advised instance has its own Domain again which is a child of the class's domain.
+ The Domain class is a sub-class of the AspectManager, meaning you can add ANYTHING supported by
+ JBoss AOP to it, you are not limited to just interceptors. In the following example we prepare
+ all joinpoints of the POJO class and declare an aspect called <literal>MyAspect</literal>
+ </para>
+ <programlisting><![CDATA[
+ <!-- Weave in the hooks into our POJO class and add the interceptors -->
+ <aop>
+ <aspect class="MyAspect"/>
+ <prepare expr="all(POJO)"/>
+ </aop>
+ ]]>
+ </programlisting>
+ <programlisting><![CDATA[
+ POJO pojo1 = new POJO();
+ POJO pojo2 = new POJO();
+ ]]>
+ </programlisting>
+ <programlisting><![CDATA[
+ pojo1.someMethod();
+ ]]>
+ </programlisting>
+ <para>
+ At this stage, our <literal>POJO</literal> has the hooks woven in for AOP, but now bindings are deployed, so our call
+ to <literal>POJO.someMethod()</literal> is not intercepted. Next let us add a binding to <literal>POJO</literal>'s class domain.
+ </para>
+ <programlisting><![CDATA[
+ //All woven classes implement the Advised interface
+ Advised classAdvisor = ((Advised)pojo1);
+ //Get the domain used by all instances of POJO
+ AspectManager pojoDomain = classAdvisor._getAdvisor().getManager();
+ //Add a binding with an aspect for that class this is similar to
+ AdviceBinding binding1 = new AdviceBinding("execution(* POJO->someMethod*(..))", null);
+ AspectDefinition myAspect = AspectManager.instance().getAspectDefinition("MyAspect");
+ binding1.addInterceptorFactory(new AdviceFactory(myAspect, "intercept"));
+
+ //Add the binding to POJO's domain
+ pojoDomain.addBinding(binding1);
+
+ pojo1.someMethod();
+ pojo2.someMethod();
+ ]]>
+ </programlisting>
+ <para>
+ Now we have added a binding to <literal>POJO</literal>'s class Domain. Both calls to
+ <literal>someMethod()</literal> get intercepted by MyAspect
+ </para>
+ <programlisting><![CDATA[
+ //Create an annotation introduction
+ AnnotationIntroduction intro = AnnotationIntroduction.createMethodAnnotationIntroduction(
+ "* POJO->someMethod()",
+ "@MyAnnotation",
+ true);
+
+ //Create another binding
+ AdviceBinding binding2 = new AdviceBinding("execution(* POJO->@MyAnnotation)", null);
+ binding2.addInterceptor(MyInterceptor.class);
+
+ //All woven instances have an instance advisor
+ InstanceAdvisor instanceAdvisor1 = ((Advised)pojo1)._getInstanceAdvisor();
+
+ //The instance advisor has its own domain
+ Domain pojo1Domain = instanceAdvisor1.getDomain();
+
+ //Add the annotation override and binding to the domain
+ pojo1Domain.addAnnotationOverride(intro);
+ pojo1Domain.addBinding(binding2);
+
+ pojo1.someMethod();
+ pojo2.someMethod();
+ ]]>
+ </programlisting>
+ <para>
+ We have added an annotation override and a new binding matching on that annotaton to <literal>pojo1</literal>'s domain, so
+ when calling <literal>pojo1.someMethod()</literal> this gets intercecpted by <literal>MyAspect</literal>
+ AND <literal>MyInterceptor</literal>. <literal>pojo2.someMethod()</literal> still gets intercepted by MyAspect only.
+ </para>
+ </sect1>
+
+ <sect1 id="dyn-5" revision="1">
<title>DynamicAOP with HotSwap</title>
<para>
When running JBoss AOP with HotSwap, the dynamic AOP operations may result in the weaving of
Added: projects/aop/trunk/aop/docs/reference/reference/en/modules/modes.xml
===================================================================
--- projects/aop/trunk/aop/docs/reference/reference/en/modules/modes.xml (rev 0)
+++ projects/aop/trunk/aop/docs/reference/reference/en/modules/modes.xml 2008-09-15 14:18:40 UTC (rev 78543)
@@ -0,0 +1,220 @@
+<chapter id="insrumentation-modes">
+
+ <title>Instrumentation Modes</title>
+
+ <!-- *********************************** Intro ******************************** -->
+
+ <para>
+ Since it's inception JBoss AOP has introduced different modes of weaving. While
+ the base functionality is the same, the weaving mode introduced in JBoss AOP 2.0.0 allows
+ for more functionality. This chapter will explain a bit about the pros and cons of
+ the different weaving modes, and what functionalities are offered.
+ </para>
+ <!-- *********************************** Aspect ******************************** -->
+
+ <sect1 id="instrumention-modes-classic" revision="1">
+ <title>Classic Weaving</title>
+ <para>
+ This original weaving mode offers the full basic functionality, and comes in two
+ flavours: 'non-optimized' and 'optimized'.
+ </para>
+ <sect2 id="instrumentation-modes-classic-not-optimized" revision="1">
+ <title>Non-optimized</title>
+ <para>
+ This is the original weaving mode. It generates a minimum amount of woven code, only
+ modyfying the target joinpoints. However, the the invocation classes end up calling
+ the target joinpoint using reflection. Hence it will have minimum overhead at weaving
+ time, but incur the extra cost of calling via reflection at runtime.
+ </para>
+ <para>
+ To use not-optimized classic weaving at compile-time, you need to specify the following
+ parameters to the <literal>aopc</literal> ant task.
+ </para>
+ <itemizedlist>
+ <listitem><literal>optimized</literal> - false</listitem>
+ <listitem><literal>jboss.aop.instrumentor</literal> - org.jboss.aop.instrument.ClassicInstrumentor</listitem>
+ </itemizedlist>
+ <para>
+ An example is shown in the following build.xml snippet. Only the relevant parts are shown.
+ </para>
+ <programlisting><![CDATA[
+ <aopc optimized="false" compilerclasspathref="...">
+ <sysproperty key="jboss.aop.instrumentor" \
+ value="org.jboss.aop.instrument.ClassicInstrumentor"/>
+ ...
+ </aopc>
+ ]]>
+ </programlisting>
+ <para>
+ To turn this weaving mode on when using load-time weaving, you need to specify the same flags
+ as system properties when running your woven application. Here is an example:
+ </para>
+ <programlisting>
+ java -Djboss.aop.optimized=false \
+ -Djboss.aop.instrumentor=org.jboss.aop.instrument.ClassicInstrumentor \
+ [other aop and classpath settings] MyClass
+ </programlisting>
+ </sect2>
+ <sect2 id="instrumentation-modes-classic-optimized" revision="1">
+ <title>Optimized</title>
+ <para>
+ This is a development of the original weaving mode. Like the non-optimized flavour, it
+ modifies the target joinpoints, but in addition it generates an invocation class per woven
+ joinpoint, which calls the target joinpoint normally, avoiding the cost of calling via
+ reflection.
+ </para>
+ <para>
+ To use optimized classic weaving at compile-time, you need to specify the following
+ parameters to the <literal>aopc</literal> ant task.
+ </para>
+ <itemizedlist>
+ <listitem><literal>optimized</literal> - true</listitem>
+ <listitem><literal>jboss.aop.instrumentor</literal> - org.jboss.aop.instrument.ClassicInstrumentor</listitem>
+ </itemizedlist>
+ <para>
+ An example is shown in the following build.xml snippet. Only the relevant parts are shown.
+ </para>
+ <programlisting><![CDATA[
+ <aopc optimized="true" compilerclasspathref="...">
+ <sysproperty key="jboss.aop.instrumentor" \
+ value="org.jboss.aop.instrument.ClassicInstrumentor"/>
+ ...
+ </aopc>
+ ]]>
+ </programlisting>
+ <para>
+ To turn this weaving mode on when using load-time weaving, you need to specify the same flags
+ as system properties when running your woven application. Here is an example:
+ </para>
+ <programlisting>
+ java -Djboss.aop.optimized=true \
+ -Djboss.aop.instrumentor=org.jboss.aop.instrument.ClassicInstrumentor \
+ [other aop and classpath settings] MyClass
+ </programlisting>
+ </sect2>
+ </sect1>
+ <sect1 id="instrumention-modes-generated-advisor" revision="1">
+ <title>Generated Advisor Weaving</title>
+ <para>
+ This is the weaving mode that is used by default in JBoss AOP 2.0.x. In addition to generating
+ the invocation classes, it also generates the 'advisors'. These contain the internal
+ book-keeping code that keeps track of the advice chains for the varoius woven joinpoints).
+ At runtime, this means that there is less overhead of looking things up. This mode also allows
+ for some new features in JBoss AOP 2.0.x.
+ </para>
+ <para>
+ This weaving mode is used by default, so you don't have to specify any extra parameters. This may
+ change in future, so for completeness the parameter you would to pass in to the <literal>aopc</literal>
+ ant task is.
+ </para>
+ <itemizedlist>
+ <listitem><literal>jboss.aop.instrumentor</literal> - org.jboss.aop.instrument.GeneratedAdvisorInstrumentor</listitem>
+ </itemizedlist>
+ <para>
+ An example is shown in the following build.xml snippet. Only the relevant parts are shown.
+ </para>
+ <programlisting><![CDATA[
+ <aopc optimized="true" compilerclasspathref="...">
+ <sysproperty key="jboss.aop.instrumentor" \
+ value="org.jboss.aop.instrument.GeneratedAdvisorInstrumentor"/>
+ ...
+ </aopc>
+ ]]>
+ </programlisting>
+ <para>
+ Similarly, for load-time weaving, the default is to use this weaving mode. If you were to need
+ to turn it one you would pass in the <literal>GeneratedAdvisorInstrumentor</literal> when
+ starting the JVM:
+ </para>
+ <programlisting>
+ java -Djboss.aop.instrumentor=org.jboss.aop.instrument.GeneratedAdvisorInstrumentor \
+ [other aop and classpath settings] MyClass
+ </programlisting>
+ <para>
+ Now we will look at some of the features that are available using this weaving mode.
+ </para>
+ <sect2 id="instrumention-modes-generated-advisor-batf" revision="1">
+ <title>Lightweight Aspects</title>
+ <para>
+ The use of the before, after, after-throwing and finally advices as mentioned in the
+ <link linkend="adv-batf">Advices</link> chapter is only supported in this weaving mode.
+ </para>
+ </sect2>
+ <sect2 id="instrumention-modes-generated-advisor-instance-api" revision="1">
+ <title>Improved Instance API</title>
+ <para>
+ The <link linkend="dyn-4">Improved Instance API</link> is only available in this weaving mode.
+ </para>
+ </sect2>
+ <sect2 id="instrumention-modes-generated-advisor-chain-overriding" revision="1">
+ <title>Chain Overriding of Inherited Methods</title>
+ <para>
+ This will be explained with an example. Consider the following case:
+ </para>
+ <programlisting><![CDATA[
+ public class Base{
+ void test(){}
+ }
+
+ public class Child{
+ }
+
+ public class ChildTest{
+ void test(){}
+ }
+ ]]>
+ </programlisting>
+ <programlisting><![CDATA[
+ <aop>
+ <prepare expr="execution(* POJO->test())"/>
+ <bind pointcut="execution(* Base->test())">
+ <interceptor class="BaseInterceptor"/>
+ </bind>
+ <bind pointcut="execution(* Child*->test())">
+ <interceptor class="ChildInterceptor"/>
+ </bind>
+ </aop>
+ ]]>
+ </programlisting>
+ <programlisting><![CDATA[
+
+Base base = new Base(); //1
+Child child = new Child(); //2
+ChildTest childTest = new ChildTest(); //3
+
+base.test(); //4
+child.test(); //5
+childTest.test(); //6
+]]>
+ </programlisting>
+ <para>
+ With the "old" weaving we needed an exact match on methods for advices to get bound, meaning that:
+ <itemizedlist>
+ <listitem>Call 4 would get intercepted by BaseInterceptor</listitem>
+ <listitem>Call 5 would get intercepted by BaseInterceptor</listitem>
+ <listitem>Call 6 would get intercepted by ChildInterceptor</listitem>
+ </itemizedlist>
+ The discrepancy is between calls 5 and 6, we get different behaviour depending on if we have overridden
+ the method or are just inheriting it, which in turn means we have to have some in-depth knowledge about
+ our hierarchy of classes and who overrides/inherits what in order to have predictable interception.
+ </para>
+ <para>
+ The new weaving model matches differently, and treats inherited methods the same as overridden methods, so:
+ <itemizedlist>
+ <listitem>Call 4 would get intercepted by BaseInterceptor</listitem>
+ <listitem>Call 5 would get intercepted by ChildInterceptor</listitem>
+ <listitem>Call 6 would get intercepted by ChildInterceptor</listitem>
+ </itemizedlist>
+ </para>
+ <para>
+ Note that for this to work, the parent method <emphasis>MUST</emphasis> be woven. In the previous example
+ <literal>Base.test()</literal> has been prepared.
+ </para>
+ </sect2>
+ </sect1>
+
+</chapter>
+
+
+
+
More information about the jboss-cvs-commits
mailing list