[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