aop.xml 180.8 KB
Newer Older
1
<?xml version="1.0" encoding="UTF-8"?>
2 3 4 5
<chapter xmlns="http://docbook.org/ns/docbook" version="5.0"
    xmlns:xlink="http://www.w3.org/1999/xlink"
    xmlns:xi="http://www.w3.org/2001/XInclude"
    xml:id="aop">
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
  <title>Aspect Oriented Programming with Spring</title>

  <section id="aop-introduction">
    <title>Introduction</title>

    <para><emphasis>Aspect-Oriented Programming</emphasis> (AOP) complements
    Object-Oriented Programming (OOP) by providing another way of thinking
    about program structure. The key unit of modularity in OOP is the class,
    whereas in AOP the unit of modularity is the <emphasis>aspect</emphasis>.
    Aspects enable the modularization of concerns such as transaction
    management that cut across multiple types and objects. (Such concerns are
    often termed <emphasis>crosscutting</emphasis> concerns in AOP
    literature.)</para>

    <para>One of the key components of Spring is the <emphasis>AOP
    framework</emphasis>. While the Spring IoC container does not depend on
    AOP, meaning you do not need to use AOP if you don't want to, AOP
    complements Spring IoC to provide a very capable middleware
    solution.</para>

    <sidebar>
      <title>Spring 2.0 AOP</title>

      <para>Spring 2.0 introduces a simpler and more powerful way of writing
      custom aspects using either a <link linkend="aop-schema">schema-based
      approach</link> or the <link linkend="aop-ataspectj">@AspectJ annotation
      style</link>. Both of these styles offer fully typed advice and use of
      the AspectJ pointcut language, while still using Spring AOP for
      weaving.</para>

      <para>The Spring 2.0 schema- and @AspectJ-based AOP support is discussed
      in this chapter. Spring 2.0 AOP remains fully backwards compatible with
      Spring 1.2 AOP, and the lower-level AOP support offered by the Spring
      1.2 APIs is discussed in <link linkend="aop-api">the following
      chapter</link>.</para>
    </sidebar>

    <para>AOP is used in the Spring Framework to...</para>

    <itemizedlist>
      <listitem>
        <para>... provide declarative enterprise services, especially as a
        replacement for EJB declarative services. The most important such
        service is <link
        linkend="transaction-declarative"><emphasis>declarative transaction
        management</emphasis></link>.</para>
      </listitem>

      <listitem>
        <para>... allow users to implement custom aspects, complementing their
        use of OOP with AOP.</para>
      </listitem>
    </itemizedlist>

    <remark><para>If you are interested only in generic declarative services
    or other pre-packaged declarative middleware services such as pooling, you
    do not need to work directly with Spring AOP, and can skip most of this
    chapter. </para></remark>

    <section id="aop-introduction-defn">
      <title>AOP concepts</title>

      <para>Let us begin by defining some central AOP concepts and
      terminology. These terms are not Spring-specific... unfortunately, AOP
      terminology is not particularly intuitive; however, it would be even
      more confusing if Spring used its own terminology.</para>

      <itemizedlist>
        <listitem>
          <para><emphasis>Aspect</emphasis>: a modularization of a concern
          that cuts across multiple classes. Transaction management is a good
77 78 79
          example of a crosscutting concern in enterprise Java applications.
          In Spring AOP, aspects are implemented using regular classes (the
          <link linkend="aop-schema">schema-based approach</link>) or regular
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213
          classes annotated with the <interfacename>@Aspect</interfacename>
          annotation (the <link
          linkend="aop-ataspectj"><interfacename>@AspectJ</interfacename>
          style</link>).</para>
        </listitem>

        <listitem>
          <para><emphasis>Join point</emphasis>: a point during the execution
          of a program, such as the execution of a method or the handling of
          an exception. In Spring AOP, a join point
          <emphasis>always</emphasis> represents a method execution.</para>
        </listitem>

        <listitem>
          <para><emphasis>Advice</emphasis>: action taken by an aspect at a
          particular join point. Different types of advice include "around,"
          "before" and "after" advice. (Advice types are discussed below.)
          Many AOP frameworks, including Spring, model an advice as an
          <emphasis>interceptor</emphasis>, maintaining a chain of
          interceptors <emphasis>around</emphasis> the join point.</para>
        </listitem>

        <listitem>
          <para><emphasis>Pointcut</emphasis>: a predicate that matches join
          points. Advice is associated with a pointcut expression and runs at
          any join point matched by the pointcut (for example, the execution
          of a method with a certain name). The concept of join points as
          matched by pointcut expressions is central to AOP, and Spring uses
          the AspectJ pointcut expression language by default.</para>
        </listitem>

        <listitem>
          <para><emphasis>Introduction</emphasis>: declaring additional
          methods or fields on behalf of a type. Spring AOP allows you to
          introduce new interfaces (and a corresponding implementation) to any
          advised object. For example, you could use an introduction to make a
          bean implement an <interfacename>IsModified</interfacename>
          interface, to simplify caching. (An introduction is known as an
          inter-type declaration in the AspectJ community.)</para>
        </listitem>

        <listitem>
          <para><emphasis>Target object</emphasis>: object being advised by
          one or more aspects. Also referred to as the
          <emphasis>advised</emphasis> object. Since Spring AOP is implemented
          using runtime proxies, this object will always be a
          <emphasis>proxied</emphasis> object.</para>
        </listitem>

        <listitem>
          <para><emphasis>AOP proxy</emphasis>: an object created by the AOP
          framework in order to implement the aspect contracts (advise method
          executions and so on). In the Spring Framework, an AOP proxy will be
          a JDK dynamic proxy or a CGLIB proxy.</para>
        </listitem>

        <listitem>
          <para><emphasis>Weaving</emphasis>: linking aspects with other
          application types or objects to create an advised object. This can
          be done at compile time (using the AspectJ compiler, for example),
          load time, or at runtime. Spring AOP, like other pure Java AOP
          frameworks, performs weaving at runtime.</para>
        </listitem>
      </itemizedlist>

      <para>Types of advice:</para>

      <itemizedlist>
        <listitem>
          <para><emphasis>Before advice</emphasis>: Advice that executes
          before a join point, but which does not have the ability to prevent
          execution flow proceeding to the join point (unless it throws an
          exception).</para>
        </listitem>

        <listitem>
          <para><emphasis>After returning advice</emphasis>: Advice to be
          executed after a join point completes normally: for example, if a
          method returns without throwing an exception.</para>
        </listitem>

        <listitem>
          <para><emphasis>After throwing advice</emphasis>: Advice to be
          executed if a method exits by throwing an exception.</para>
        </listitem>

        <listitem>
          <para><emphasis>After (finally) advice</emphasis>: Advice to be
          executed regardless of the means by which a join point exits (normal
          or exceptional return).</para>
        </listitem>

        <listitem>
          <para><emphasis>Around advice</emphasis>: Advice that surrounds a
          join point such as a method invocation. This is the most powerful
          kind of advice. Around advice can perform custom behavior before and
          after the method invocation. It is also responsible for choosing
          whether to proceed to the join point or to shortcut the advised
          method execution by returning its own return value or throwing an
          exception.</para>
        </listitem>
      </itemizedlist>

      <para>Around advice is the most general kind of advice. Since Spring
      AOP, like AspectJ, provides a full range of advice types, we recommend
      that you use the least powerful advice type that can implement the
      required behavior. For example, if you need only to update a cache with
      the return value of a method, you are better off implementing an after
      returning advice than an around advice, although an around advice can
      accomplish the same thing. Using the most specific advice type provides
      a simpler programming model with less potential for errors. For example,
      you do not need to invoke the <methodname>proceed()</methodname> method
      on the <interfacename>JoinPoint</interfacename> used for around advice,
      and hence cannot fail to invoke it.</para>

      <para>In Spring 2.0, all advice parameters are statically typed, so that
      you work with advice parameters of the appropriate type (the type of the
      return value from a method execution for example) rather than
      <classname>Object</classname> arrays.</para>

      <para>The concept of join points, matched by pointcuts, is the key to
      AOP which distinguishes it from older technologies offering only
      interception. Pointcuts enable advice to be targeted independently of
      the Object-Oriented hierarchy. For example, an around advice providing
      declarative transaction management can be applied to a set of methods
      spanning multiple objects (such as all business operations in the
      service layer).</para>
    </section>

    <section id="aop-introduction-spring-defn">
      <title>Spring AOP capabilities and goals</title>

      <para>Spring AOP is implemented in pure Java. There is no need for a
      special compilation process. Spring AOP does not need to control the
214
      class loader hierarchy, and is thus suitable for use in a Servlet
215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237
      container or application server.</para>

      <para>Spring AOP currently supports only method execution join points
      (advising the execution of methods on Spring beans). Field interception
      is not implemented, although support for field interception could be
      added without breaking the core Spring AOP APIs. If you need to advise
      field access and update join points, consider a language such as
      AspectJ.</para>

      <para>Spring AOP's approach to AOP differs from that of most other AOP
      frameworks. The aim is not to provide the most complete AOP
      implementation (although Spring AOP is quite capable); it is rather to
      provide a close integration between AOP implementation and Spring IoC to
      help solve common problems in enterprise applications.</para>

      <para>Thus, for example, the Spring Framework's AOP functionality is
      normally used in conjunction with the Spring IoC container. Aspects are
      configured using normal bean definition syntax (although this allows
      powerful "autoproxying" capabilities): this is a crucial difference from
      other AOP implementations. There are some things you cannot do easily or
      efficiently with Spring AOP, such as advise very fine-grained objects
      (such as domain objects typically): AspectJ is the best choice in such
      cases. However, our experience is that Spring AOP provides an excellent
238 239
      solution to most problems in enterprise Java applications that are
      amenable to AOP.</para>
240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273

      <para>Spring AOP will never strive to compete with AspectJ to provide a
      comprehensive AOP solution. We believe that both proxy-based frameworks
      like Spring AOP and full-blown frameworks such as AspectJ are valuable,
      and that they are complementary, rather than in competition. Spring 2.0
      seamlessly integrates Spring AOP and IoC with AspectJ, to enable all
      uses of AOP to be catered for within a consistent Spring-based
      application architecture. This integration does not affect the Spring
      AOP API or the AOP Alliance API: Spring AOP remains backward-compatible.
      See <link linkend="aop-api">the following chapter</link> for a
      discussion of the Spring AOP APIs.</para>

      <note>
        <para>One of the central tenets of the Spring Framework is that of
        <emphasis>non-invasiveness</emphasis>; this is the idea that you
        should not be forced to introduce framework-specific classes and
        interfaces into your business/domain model. However, in some places
        the Spring Framework does give you the option to introduce Spring
        Framework-specific dependencies into your codebase: the rationale in
        giving you such options is because in certain scenarios it might be
        just plain easier to read or code some specific piece of functionality
        in such a way. The Spring Framework (almost) always offers you the
        choice though: you have the freedom to make an informed decision as to
        which option best suits your particular use case or scenario.</para>

        <para>One such choice that is relevant to this chapter is that of
        which AOP framework (and which AOP style) to choose. You have the
        choice of AspectJ and/or Spring AOP, and you also have the choice of
        either the @AspectJ annotation-style approach or the Spring XML
        configuration-style approach. The fact that this chapter chooses to
        introduce the @AspectJ-style approach first should not be taken as an
        indication that the Spring team favors the @AspectJ annotation-style
        approach over the Spring XML configuration-style.</para>

274 275
        <para>See <xref linkend="aop-choosing" /> for a
        more complete discussion of the whys and wherefores of each style.</para>
276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296
      </note>
    </section>

    <section id="aop-introduction-proxies">
      <title>AOP Proxies</title>

      <para>Spring AOP defaults to using standard J2SE <emphasis>dynamic
      proxies</emphasis> for AOP proxies. This enables any interface (or set
      of interfaces) to be proxied.</para>

      <para>Spring AOP can also use CGLIB proxies. This is necessary to proxy
      classes, rather than interfaces. CGLIB is used by default if a business
      object does not implement an interface. As it is good practice to
      program to interfaces rather than classes, business classes normally
      will implement one or more business interfaces. It is possible to <link
      linkend="aop-autoproxy-force-CGLIB">force the use of CGLIB</link>, in
      those (hopefully rare) cases where you need to advise a method that is
      not declared on an interface, or where you need to pass a proxied object
      to a method as a concrete type.</para>

      <para>It is important to grasp the fact that Spring AOP is
297
      <emphasis>proxy-based</emphasis>. See <xref
298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332
      linkend="aop-understanding-aop-proxies" /> for a thorough examination of
      exactly what this implementation detail actually means.</para>
    </section>
  </section>

  <section id="aop-ataspectj">
    <title>@AspectJ support</title>

    <para>@AspectJ refers to a style of declaring aspects as regular Java
    classes annotated with Java 5 annotations. The @AspectJ style was
    introduced by the <ulink url="http://www.eclipse.org/aspectj">AspectJ
    project</ulink> as part of the AspectJ 5 release. Spring 2.0 interprets
    the same annotations as AspectJ 5, using a library supplied by AspectJ for
    pointcut parsing and matching. The AOP runtime is still pure Spring AOP
    though, and there is no dependency on the AspectJ compiler or
    weaver.</para>

    <remark><para>Using the AspectJ compiler and weaver enables use of the
    full AspectJ language, and is discussed in <xref
    linkend="aop-using-aspectj" />.</para></remark>

    <section id="aop-aspectj-support">
      <title>Enabling @AspectJ Support</title>

      <para>To use @AspectJ aspects in a Spring configuration you need to
      enable Spring support for configuring Spring AOP based on @AspectJ
      aspects, and <emphasis>autoproxying</emphasis> beans based on whether or
      not they are advised by those aspects. By autoproxying we mean that if
      Spring determines that a bean is advised by one or more aspects, it will
      automatically generate a proxy for that bean to intercept method
      invocations and ensure that advice is executed as needed.</para>

      <para>The @AspectJ support is enabled by including the following element
      inside your spring configuration:</para>

333
      <programlisting language="xml">&lt;aop:aspectj-autoproxy/&gt;</programlisting>
334 335 336 337 338 339 340 341 342 343

      <para>This assumes that you are using schema support as described in
      <xref linkend="xsd-config" />. See <xref
      linkend="xsd-config-body-schemas-aop" /> for how to import the tags in
      the aop namespace.</para>

      <para>If you are using the DTD, it is still possible to enable @AspectJ
      support by adding the following definition to your application
      context:</para>

344
      <programlisting language="xml">&lt;bean class="org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator" /&gt;</programlisting>
345

346 347 348 349 350
      <para>You will also need AspectJ's
      <filename class="libraryfile">aspectjrt.jar</filename> library on the
      classpath of your application, version 1.6.8 or later. This library is
      available in the <filename class="directory">'lib'</filename> directory
      of an AspectJ distribution or via the Maven Central repository.</para>
351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366
    </section>

    <section id="aop-at-aspectj">
      <title>Declaring an aspect</title>

      <para>With the @AspectJ support enabled, any bean defined in your
      application context with a class that is an @AspectJ aspect (has the
      <interfacename>@Aspect</interfacename> annotation) will be automatically
      detected by Spring and used to configure Spring AOP. The following
      example shows the minimal definition required for a not-very-useful
      aspect:</para>

      <para>A regular bean definition in the application context, pointing to
      a bean class that has the <interfacename>@Aspect</interfacename>
      annotation:</para>

367
      <programlisting language="xml">&lt;bean id="myAspect" class="org.xyz.NotVeryUsefulAspect"&gt;
368 369 370 371 372 373 374 375 376
   <lineannotation>&lt;!-- configure properties of aspect here as normal --&gt;</lineannotation>
&lt;/bean&gt;
</programlisting>

      <para>And the <classname>NotVeryUsefulAspect</classname> class
      definition, annotated with
      <interfacename>org.aspectj.lang.annotation.Aspect</interfacename>
      annotation;</para>

377
      <programlisting language="java">package org.xyz;
378 379 380 381 382 383 384 385 386 387 388 389 390
import org.aspectj.lang.annotation.Aspect;

@Aspect
public class NotVeryUsefulAspect {

}</programlisting>

      <para>Aspects (classes annotated with
      <interfacename>@Aspect</interfacename>) may have methods and fields just
      like any other class. They may also contain pointcut, advice, and
      introduction (inter-type) declarations.</para>

      <note>
391 392 393
        <title>Autodetecting aspects through component scanning</title>

        <para>You may register aspect classes as regular beans in your Spring
394
        XML configuration, or autodetect them through classpath scanning -
395 396 397 398 399 400 401 402 403 404
        just like any other Spring-managed bean. However, note that the
        <emphasis>@Aspect</emphasis> annotation is <emphasis>not</emphasis>
        sufficient for autodetection in the classpath: For that purpose,
        you need to add a separate <emphasis>@Component</emphasis> annotation
        (or alternatively a custom stereotype annotation that qualifies,
        as per the rules of Spring's component scanner).</para>
      </note>

      <note>
        <title>Advising aspects with other aspects?</title>
405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434

        <para>In Spring AOP, it is <emphasis>not</emphasis> possible to have
        aspects themselves be the target of advice from other aspects. The
        <emphasis>@Aspect</emphasis> annotation on a class marks it as an
        aspect, and hence excludes it from auto-proxying.</para>
      </note>
    </section>

    <section id="aop-pointcuts">
      <title>Declaring a pointcut</title>

      <para>Recall that pointcuts determine join points of interest, and thus
      enable us to control when advice executes. <emphasis>Spring AOP only
      supports method execution join points for Spring beans</emphasis>, so
      you can think of a pointcut as matching the execution of methods on
      Spring beans. A pointcut declaration has two parts: a signature
      comprising a name and any parameters, and a pointcut expression that
      determines <emphasis>exactly</emphasis> which method executions we are
      interested in. In the @AspectJ annotation-style of AOP, a pointcut
      signature is provided by a regular method definition, and the pointcut
      expression is indicated using the
      <interfacename>@Pointcut</interfacename> annotation (the method serving
      as the pointcut signature <emphasis>must</emphasis> have a
      <literal>void</literal> return type).</para>

      <para>An example will help make this distinction between a pointcut
      signature and a pointcut expression clear. The following example defines
      a pointcut named <literal>'anyOldTransfer'</literal> that will match the
      execution of any method named <literal>'transfer'</literal>:</para>

435
      <programlisting language="java">@Pointcut("execution(* transfer(..))")<lineannotation>// the pointcut expression</lineannotation>
436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467
private void anyOldTransfer() {}<lineannotation>// the pointcut signature</lineannotation></programlisting>

      <para>The pointcut expression that forms the value of the
      <interfacename>@Pointcut</interfacename> annotation is a regular AspectJ
      5 pointcut expression. For a full discussion of AspectJ's pointcut
      language, see the <ulink
      url="http://www.eclipse.org/aspectj/doc/released/progguide/index.html">AspectJ
      Programming Guide</ulink> (and for Java 5 based extensions, the <ulink
      url="http://www.eclipse.org/aspectj/doc/released/adk15notebook/index.html">AspectJ
      5 Developers Notebook</ulink>) or one of the books on AspectJ such as
      <quote>Eclipse AspectJ</quote> by Colyer et. al. or <quote>AspectJ in
      Action</quote> by Ramnivas Laddad.</para>

      <section id="aop-pointcuts-designators">
        <title>Supported Pointcut Designators</title>

        <para>Spring AOP supports the following AspectJ pointcut designators
        (PCD) for use in pointcut expressions:</para>

        <sidebar>
          <title>Other pointcut types</title>

          <para>The full AspectJ pointcut language supports additional
          pointcut designators that are not supported in Spring. These are:
          <literal>call, get, set, preinitialization, staticinitialization,
          initialization, handler, adviceexecution, withincode, cflow,
          cflowbelow, if, @this</literal>, and <literal>@withincode</literal>.
          Use of these pointcut designators in pointcut expressions
          interpreted by Spring AOP will result in an
          <classname>IllegalArgumentException</classname> being thrown.</para>

          <para>The set of pointcut designators supported by Spring AOP may be
C
Chris Beams 已提交
468 469
          extended in future releases to support more of the AspectJ pointcut
          designators.</para>
470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565
        </sidebar>

        <itemizedlist>
          <listitem>
            <para><emphasis>execution</emphasis> - for matching method
            execution join points, this is the primary pointcut designator you
            will use when working with Spring AOP</para>
          </listitem>

          <listitem>
            <para><emphasis>within</emphasis> - limits matching to join points
            within certain types (simply the execution of a method declared
            within a matching type when using Spring AOP)</para>
          </listitem>

          <listitem>
            <para><emphasis>this</emphasis> - limits matching to join points
            (the execution of methods when using Spring AOP) where the bean
            reference (Spring AOP proxy) is an instance of the given
            type</para>
          </listitem>

          <listitem>
            <para><emphasis>target</emphasis> - limits matching to join points
            (the execution of methods when using Spring AOP) where the target
            object (application object being proxied) is an instance of the
            given type</para>
          </listitem>

          <listitem>
            <para><emphasis>args</emphasis> - limits matching to join points
            (the execution of methods when using Spring AOP) where the
            arguments are instances of the given types</para>
          </listitem>

          <listitem>
            <para><emphasis><interfacename>@target</interfacename></emphasis>
            - limits matching to join points (the execution of methods when
            using Spring AOP) where the class of the executing object has an
            annotation of the given type</para>
          </listitem>

          <listitem>
            <para><emphasis><interfacename>@args</interfacename></emphasis> -
            limits matching to join points (the execution of methods when
            using Spring AOP) where the runtime type of the actual arguments
            passed have annotations of the given type(s)</para>
          </listitem>

          <listitem>
            <para><emphasis><interfacename>@within</interfacename></emphasis>
            - limits matching to join points within types that have the given
            annotation (the execution of methods declared in types with the
            given annotation when using Spring AOP)</para>
          </listitem>

          <listitem>
            <para><emphasis>@annotation</emphasis> - limits matching to join
            points where the subject of the join point (method being executed
            in Spring AOP) has the given annotation</para>
          </listitem>
        </itemizedlist>

        <para>Because Spring AOP limits matching to only method execution
        join points, the discussion of the pointcut designators above gives a
        narrower definition than you will find in the AspectJ programming
        guide. In addition, AspectJ itself has type-based semantics and at an
        execution join point both '<literal>this</literal>' and
        '<literal>target</literal>' refer to the same object - the object
        executing the method. Spring AOP is a proxy-based system and
        differentiates between the proxy object itself (bound to
        '<literal>this</literal>') and the target object behind the proxy
        (bound to '<literal>target</literal>').</para>

        <note>
          <para>Due to the proxy-based nature of Spring's AOP framework,
          protected methods are by definition <emphasis>not</emphasis>
          intercepted, neither for JDK proxies (where this isn't applicable)
          nor for CGLIB proxies (where this is technically possible but not
          recommendable for AOP purposes). As a consequence, any given pointcut
          will be matched against <emphasis>public methods only</emphasis>!</para>

          <para>If your interception needs include protected/private methods
          or even constructors, consider the use of Spring-driven
          <link linkend="aop-aj-ltw">native AspectJ weaving</link> instead
          of Spring's proxy-based AOP framework. This constitutes a different
          mode of AOP usage with different characteristics, so be sure to make
          yourself familiar with weaving first before making a decision.</para>
        </note>

        <para>Spring AOP also supports an additional PCD named
        '<literal>bean</literal>'. This PCD allows you to limit the matching
        of join points to a particular named Spring bean, or to a set of named
        Spring beans (when using wildcards). The '<literal>bean</literal>' PCD
        has the following form:</para>

566
        <programlisting language="java">bean(idOrNameOfBean)</programlisting>
567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607

        <para>The '<literal>idOrNameOfBean</literal>' token can be the name of
        any Spring bean: limited wildcard support using the
        '<literal>*</literal>' character is provided, so if you establish
        some naming conventions for your Spring beans you can quite easily
        write a '<literal>bean</literal>' PCD expression to pick them out. As
        is the case with other pointcut designators, the
        '<literal>bean</literal>' PCD can be &amp;&amp;'ed, ||'ed, and !
        (negated) too.</para>

        <note>
          <para>Please note that the '<literal>bean</literal>' PCD is
          <emphasis>only</emphasis> supported in Spring AOP - and
          <emphasis>not</emphasis> in native AspectJ weaving. It is a
          Spring-specific extension to the standard PCDs that AspectJ
          defines.</para>

          <para>The '<literal>bean</literal>' PCD operates at the
          <emphasis>instance</emphasis> level (building on the Spring
          bean name concept) rather than at the type level only
          (which is what weaving-based AOP is limited to).
          Instance-based pointcut designators are a special capability
          of Spring's proxy-based AOP framework and its close integration
          with the Spring bean factory, where it is natural and
          straightforward to identify specific beans by name.</para>
        </note>
      </section>

      <section id="aop-pointcuts-combining">
        <title>Combining pointcut expressions</title>

        <para>Pointcut expressions can be combined using '&amp;&amp;', '||'
        and '!'. It is also possible to refer to pointcut expressions by name.
        The following example shows three pointcut expressions:
        <literal>anyPublicOperation</literal> (which matches if a method
        execution join point represents the execution of any public method);
        <literal>inTrading</literal> (which matches if a method execution is
        in the trading module), and <literal>tradingOperation</literal> (which
        matches if a method execution represents any public method in the
        trading module).</para>

608
        <programlisting language="java">    @Pointcut("execution(public * *(..))")
609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633
    private void anyPublicOperation() {}
    
    @Pointcut("within(com.xyz.someapp.trading..*)")
    private void inTrading() {}
    
    @Pointcut("anyPublicOperation() &amp;&amp; inTrading()")
    private void tradingOperation() {}</programlisting>

        <para>It is a best practice to build more complex pointcut expressions
        out of smaller named components as shown above. When referring to
        pointcuts by name, normal Java visibility rules apply (you can see
        private pointcuts in the same type, protected pointcuts in the
        hierarchy, public pointcuts anywhere and so on). Visibility does not
        affect pointcut <emphasis>matching</emphasis>.</para>
      </section>

      <section id="aop-common-pointcuts">
        <title>Sharing common pointcut definitions</title>

        <para>When working with enterprise applications, you often want to
        refer to modules of the application and particular sets of operations
        from within several aspects. We recommend defining a
        "SystemArchitecture" aspect that captures common pointcut expressions
        for this purpose. A typical such aspect would look as follows:</para>

634
        <programlisting language="java">package com.xyz.someapp;
635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;

@Aspect
public class SystemArchitecture {

  <lineannotation>/**
   * A join point is in the web layer if the method is defined
   * in a type in the com.xyz.someapp.web package or any sub-package
   * under that.
   */</lineannotation>
  @Pointcut("within(com.xyz.someapp.web..*)")
  public void inWebLayer() {}

  <lineannotation>/**
   * A join point is in the service layer if the method is defined
   * in a type in the <literal>com.xyz.someapp.service</literal> package or any sub-package
   * under that.
   */</lineannotation>
  @Pointcut("within(com.xyz.someapp.service..*)")
  public void inServiceLayer() {}

  <lineannotation>/**
   * A join point is in the data access layer if the method is defined
   * in a type in the <literal>com.xyz.someapp.dao</literal> package or any sub-package
   * under that.
   */</lineannotation>
  @Pointcut("within(com.xyz.someapp.dao..*)")
  public void inDataAccessLayer() {}

  <lineannotation>/**
   * A business service is the execution of any method defined on a service
   * interface. This definition assumes that interfaces are placed in the
   * "service" package, and that implementation types are in sub-packages.
   * 
   * If you group service interfaces by functional area (for example, 
   * in packages <literal>com.xyz.someapp.abc.service</literal> and <literal>com.xyz.def.service</literal>) then
   * the pointcut expression "<literal>execution(* com.xyz.someapp..service.*.*(..))</literal>"
   * could be used instead.
   *
   * Alternatively, you can write the expression using the '<literal>bean</literal>'
   * PCD, like so "<literal>bean(*Service)</literal>". (This assumes that you have
   * named your Spring service beans in a consistent fashion.)
   */</lineannotation>
  @Pointcut("execution(* com.xyz.someapp.service.*.*(..))")
  public void businessService() {}
  
  <lineannotation>/**
   * A data access operation is the execution of any method defined on a 
   * dao interface. This definition assumes that interfaces are placed in the
   * "<literal>dao</literal>" package, and that implementation types are in sub-packages.
   */</lineannotation>
  @Pointcut("execution(* com.xyz.someapp.dao.*.*(..))")
  public void dataAccessOperation() {}

}</programlisting>

        <para>The pointcuts defined in such an aspect can be referred to
        anywhere that you need a pointcut expression. For example, to make the
        service layer transactional, you could write:</para>

697
        <programlisting language="xml">&lt;aop:config&gt;
698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721
  &lt;aop:advisor 
      pointcut="com.xyz.someapp.SystemArchitecture.businessService()"
      advice-ref="tx-advice"/&gt;
&lt;/aop:config&gt;

&lt;tx:advice id="tx-advice"&gt;
  &lt;tx:attributes&gt;
    &lt;tx:method name="*" propagation="REQUIRED"/&gt;
  &lt;/tx:attributes&gt;
&lt;/tx:advice&gt;</programlisting>

        <para>The <literal>&lt;aop:config&gt;</literal> and
        <literal>&lt;aop:advisor&gt;</literal> elements are discussed in <xref
        linkend="aop-schema" />. The transaction elements are discussed in
        <xref linkend="transaction" />.</para>
      </section>

      <section id="aop-pointcuts-examples">
        <title>Examples</title>

        <para>Spring AOP users are likely to use the
        <literal>execution</literal> pointcut designator the most often. The
        format of an execution expression is:</para>

722
        <programlisting language="java">execution(modifiers-pattern? ret-type-pattern declaring-type-pattern? name-pattern(param-pattern)
723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751
          throws-pattern?)</programlisting>

        <para>All parts except the returning type pattern (ret-type-pattern in
        the snippet above), name pattern, and parameters pattern are optional.
        The returning type pattern determines what the return type of the
        method must be in order for a join point to be matched. Most
        frequently you will use <literal>*</literal> as the returning type
        pattern, which matches any return type. A fully-qualified type name
        will match only when the method returns the given type. The name
        pattern matches the method name. You can use the <literal>*</literal>
        wildcard as all or part of a name pattern. The parameters pattern is
        slightly more complex: <literal>()</literal> matches a method that
        takes no parameters, whereas <literal>(..)</literal> matches any
        number of parameters (zero or more). The pattern
        <literal>(*)</literal> matches a method taking one parameter of any
        type, <literal>(*,String)</literal> matches a method taking two
        parameters, the first can be of any type, the second must be a String.
        Consult the <ulink
        url="http://www.eclipse.org/aspectj/doc/released/progguide/semantics-pointcuts.html">
        Language Semantics</ulink> section of the AspectJ Programming Guide
        for more information.</para>

        <para>Some examples of common pointcut expressions are given
        below.</para>

        <itemizedlist>
          <listitem>
            <para>the execution of any public method:</para>

752
            <programlisting language="java">execution(public * *(..))</programlisting>
753 754 755 756 757 758
          </listitem>

          <listitem>
            <para>the execution of any method with a name beginning with
            "set":</para>

759
            <programlisting language="java">execution(* set*(..))</programlisting>
760 761 762 763 764 765
          </listitem>

          <listitem>
            <para>the execution of any method defined by the
            <interfacename>AccountService</interfacename> interface:</para>

766
            <programlisting language="java">execution(* com.xyz.service.AccountService.*(..))</programlisting>
767 768 769 770 771 772
          </listitem>

          <listitem>
            <para>the execution of any method defined in the service
            package:</para>

773
            <programlisting language="java">execution(* com.xyz.service.*.*(..))</programlisting>
774 775 776 777 778 779
          </listitem>

          <listitem>
            <para>the execution of any method defined in the service package
            or a sub-package:</para>

780
            <programlisting language="java">execution(* com.xyz.service..*.*(..))</programlisting>
781 782 783 784 785 786
          </listitem>

          <listitem>
            <para>any join point (method execution only in Spring AOP) within
            the service package:</para>

787
            <programlisting language="java">within(com.xyz.service.*)</programlisting>
788 789 790 791 792 793
          </listitem>

          <listitem>
            <para>any join point (method execution only in Spring AOP) within
            the service package or a sub-package:</para>

794
            <programlisting language="java">within(com.xyz.service..*)</programlisting>
795 796 797 798 799 800 801
          </listitem>

          <listitem>
            <para>any join point (method execution only in Spring AOP) where
            the proxy implements the
            <interfacename>AccountService</interfacename> interface:</para>

802
            <programlisting language="java">this(com.xyz.service.AccountService)</programlisting>
803 804 805 806 807 808 809 810 811 812 813

            <remark><para>'this' is more commonly used in a binding form :-
            see the following section on advice for how to make the proxy
            object available in the advice body.</para></remark>
          </listitem>

          <listitem>
            <para>any join point (method execution only in Spring AOP) where
            the target object implements the
            <interfacename>AccountService</interfacename> interface:</para>

814
            <programlisting language="java">target(com.xyz.service.AccountService)</programlisting>
815 816 817 818 819 820 821 822 823 824 825

            <remark><para>'target' is more commonly used in a binding form :-
            see the following section on advice for how to make the target
            object available in the advice body.</para></remark>
          </listitem>

          <listitem>
            <para>any join point (method execution only in Spring AOP) which
            takes a single parameter, and where the argument passed at runtime
            is <interfacename>Serializable</interfacename>:</para>

826
            <programlisting language="java">args(java.io.Serializable)</programlisting>
827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844

            <remark>'args' is more commonly used in a binding form :- see the
            following section on advice for how to make the method arguments
            available in the advice body.</remark>

            <para>Note that the pointcut given in this example is different to
            <literal>execution(* *(java.io.Serializable))</literal>: the args
            version matches if the argument passed at runtime is Serializable,
            the execution version matches if the method signature declares a
            single parameter of type
            <interfacename>Serializable</interfacename>.</para>
          </listitem>

          <listitem>
            <para>any join point (method execution only in Spring AOP) where
            the target object has an
            <interfacename>@Transactional</interfacename> annotation:</para>

845
            <programlisting language="java">@target(org.springframework.transaction.annotation.Transactional)</programlisting>
846 847 848 849 850 851 852 853 854 855 856

            <remark><para>'@target' can also be used in a binding form :- see
            the following section on advice for how to make the annotation
            object available in the advice body.</para></remark>
          </listitem>

          <listitem>
            <para>any join point (method execution only in Spring AOP) where
            the declared type of the target object has an
            <interfacename>@Transactional</interfacename> annotation:</para>

857
            <programlisting language="java">@within(org.springframework.transaction.annotation.Transactional)</programlisting>
858 859 860 861 862 863 864 865 866 867 868

            <remark><para>'@within' can also be used in a binding form :- see
            the following section on advice for how to make the annotation
            object available in the advice body.</para></remark>
          </listitem>

          <listitem>
            <para>any join point (method execution only in Spring AOP) where
            the executing method has an
            <interfacename>@Transactional</interfacename> annotation:</para>

869
            <programlisting language="java">@annotation(org.springframework.transaction.annotation.Transactional)</programlisting>
870 871 872 873 874 875 876 877 878 879 880 881

            <remark><para>'@annotation' can also be used in a binding form :-
            see the following section on advice for how to make the annotation
            object available in the advice body.</para></remark>
          </listitem>

          <listitem>
            <para>any join point (method execution only in Spring AOP) which
            takes a single parameter, and where the runtime type of the
            argument passed has the <interfacename>@Classified</interfacename>
            annotation:</para>

882
            <programlisting language="java">@args(com.xyz.security.Classified)</programlisting>
883 884 885 886 887 888 889 890 891 892

            <remark><para>'@args' can also be used in a binding form :- see
            the following section on advice for how to make the annotation
            object(s) available in the advice body.</para></remark>
          </listitem>

          <listitem>
            <para>any join point (method execution only in Spring AOP) on a
            Spring bean named '<literal>tradeService</literal>':</para>

893
            <programlisting language="java">bean(tradeService)</programlisting>
894 895 896 897 898 899 900
          </listitem>

          <listitem>
            <para>any join point (method execution only in Spring AOP) on
            Spring beans having names that match the wildcard expression
            '<literal>*Service</literal>':</para>

901
            <programlisting language="java">bean(*Service)</programlisting>
902 903 904
          </listitem>
        </itemizedlist>
      </section>
905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933
      <section id="writing-good-pointcuts">
        <title>Writing good pointcuts</title>

        <para>During compilation, AspectJ processes pointcuts in order to try and optimize matching performance. Examining code 
        and determining if each join point matches (statically or dynamically) a given pointcut is a costly process. (A dynamic 
        match means the match cannot be fully determined from static analysis and a test will be placed in the code to 
        determine if there is an actual match when the code is running). On first encountering a pointcut declaration, 
        AspectJ will rewrite it into an optimal form for the matching process. What does this mean? Basically pointcuts 
        are rewritten in DNF (Disjunctive Normal Form) and the components of the pointcut are sorted such that those 
        components that are cheaper to evaluate are checked first. This means you do not have to worry about understanding 
        the performance of various pointcut designators and may supply them in any order in a pointcut declaration.</para>
        
        <para>However, AspectJ can only work with what it is told, and for optimal performance of matching you should 
        think about what they are trying to achieve and narrow the search space for matches as much as possible in the 
        definition. The existing designators naturally fall into one of three groups: kinded, scoping and context:</para>
        <itemizedlist>
	        <listitem><para>Kinded designators are those which select a particular kind of join point. For example: execution, get, set, call, handler</para></listitem>
    	    <listitem><para>Scoping designators are those which select a group of join points of interest (of probably many kinds). For example: within, withincode</para></listitem>
        	<listitem><para>Contextual designators are those that match (and optionally bind) based on context. For example: this, target, @annotation</para></listitem>
        </itemizedlist>
        
        <para>A well written pointcut should try and include at least the first two types (kinded and scoping), whilst 
        the contextual designators may be included if wishing to match based on join point context, or bind that context 
        for use in the advice. Supplying either just a kinded designator or just a contextual designator will work but 
        could affect weaving performance (time and memory used) due to all the extra processing and analysis. Scoping 
        designators are very fast to match and their usage means AspectJ can very quickly dismiss groups of 
        join points that should not be further processed - that is why a good pointcut should always include 
        one if possible.</para> 
      </section>
934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949
    </section>

    <section id="aop-advice">
      <title>Declaring advice</title>

      <para>Advice is associated with a pointcut expression, and runs before,
      after, or around method executions matched by the pointcut. The pointcut
      expression may be either a simple reference to a named pointcut, or a
      pointcut expression declared in place.</para>

      <section id="aop-advice-before">
        <title>Before advice</title>

        <para>Before advice is declared in an aspect using the
        <interfacename>@Before</interfacename> annotation:</para>

950
        <programlisting language="java">import org.aspectj.lang.annotation.Aspect;
951 952 953 954 955 956 957 958 959 960 961 962 963 964 965
import org.aspectj.lang.annotation.Before;

@Aspect
public class BeforeExample {

  @Before("com.xyz.myapp.SystemArchitecture.dataAccessOperation()")
  public void doAccessCheck() {
    <lineannotation>// ...</lineannotation>
  }

}</programlisting>

        <para>If using an in-place pointcut expression we could rewrite the
        above example as:</para>

966
        <programlisting language="java">import org.aspectj.lang.annotation.Aspect;
967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986
import org.aspectj.lang.annotation.Before;

@Aspect
public class BeforeExample {

  @Before("execution(* com.xyz.myapp.dao.*.*(..))")
  public void doAccessCheck() {
    <lineannotation>// ...</lineannotation>
  }

}</programlisting>
      </section>

      <section id="aop-advice-after-returning">
        <title>After returning advice</title>

        <para>After returning advice runs when a matched method execution
        returns normally. It is declared using the
        <interfacename>@AfterReturning</interfacename> annotation:</para>

987
        <programlisting language="java">import org.aspectj.lang.annotation.Aspect;
988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009
import org.aspectj.lang.annotation.AfterReturning;

@Aspect
public class AfterReturningExample {

  @AfterReturning("com.xyz.myapp.SystemArchitecture.dataAccessOperation()")
  public void doAccessCheck() {
    <lineannotation>// ...</lineannotation>
  }

}</programlisting>

        <remark>Note: it is of course possible to have multiple advice
        declarations, and other members as well, all inside the same aspect.
        We're just showing a single advice declaration in these examples to
        focus on the issue under discussion at the time.</remark>

        <para>Sometimes you need access in the advice body to the actual value
        that was returned. You can use the form of
        <interfacename>@AfterReturning</interfacename> that binds the return
        value for this:</para>

1010
        <programlisting language="java">import org.aspectj.lang.annotation.Aspect;
1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045
import org.aspectj.lang.annotation.AfterReturning;

@Aspect
public class AfterReturningExample {

  @AfterReturning(
    pointcut="com.xyz.myapp.SystemArchitecture.dataAccessOperation()",
    returning="retVal")
  public void doAccessCheck(Object retVal) {
    <lineannotation>// ...</lineannotation>
  }
  
}</programlisting>

        <para>The name used in the <literal>returning</literal> attribute must
        correspond to the name of a parameter in the advice method. When a
        method execution returns, the return value will be passed to the
        advice method as the corresponding argument value. A
        <literal>returning</literal> clause also restricts matching to only
        those method executions that return a value of the specified type
        (<classname>Object</classname> in this case, which will match any
        return value).</para>

        <para>Please note that it is <emphasis>not</emphasis> possible to
        return a totally different reference when using after-returning
        advice.</para>
      </section>

      <section id="aop-advice-after-throwing">
        <title>After throwing advice</title>

        <para>After throwing advice runs when a matched method execution exits
        by throwing an exception. It is declared using the
        <interfacename>@AfterThrowing</interfacename> annotation:</para>

1046
        <programlisting language="java">import org.aspectj.lang.annotation.Aspect;
1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066
import org.aspectj.lang.annotation.AfterThrowing;

@Aspect
public class AfterThrowingExample {

  @AfterThrowing("com.xyz.myapp.SystemArchitecture.dataAccessOperation()")
  public void doRecoveryActions() {
    <lineannotation>// ...</lineannotation>
  }

}</programlisting>

        <para>Often you want the advice to run only when exceptions of a given
        type are thrown, and you also often need access to the thrown
        exception in the advice body. Use the <literal>throwing</literal>
        attribute to both restrict matching (if desired, use
        <interfacename>Throwable</interfacename> as the exception type
        otherwise) and bind the thrown exception to an advice
        parameter.</para>

1067
        <programlisting language="java">import org.aspectj.lang.annotation.Aspect;
1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099
import org.aspectj.lang.annotation.AfterThrowing;

@Aspect
public class AfterThrowingExample {

  @AfterThrowing(
    pointcut="com.xyz.myapp.SystemArchitecture.dataAccessOperation()",
    throwing="ex")
  public void doRecoveryActions(DataAccessException ex) {
    <lineannotation>// ...</lineannotation>
  }

}</programlisting>

        <para>The name used in the <literal>throwing</literal> attribute must
        correspond to the name of a parameter in the advice method. When a
        method execution exits by throwing an exception, the exception will be
        passed to the advice method as the corresponding argument value. A
        <literal>throwing</literal> clause also restricts matching to only
        those method executions that throw an exception of the specified type
        (<classname>DataAccessException</classname> in this case).</para>
      </section>

      <section id="aop-advice-after-finally">
        <title>After (finally) advice</title>

        <para>After (finally) advice runs however a matched method execution
        exits. It is declared using the <interfacename>@After</interfacename>
        annotation. After advice must be prepared to handle both normal and
        exception return conditions. It is typically used for releasing
        resources, etc.</para>

1100
        <programlisting language="java">import org.aspectj.lang.annotation.Aspect;
1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155
import org.aspectj.lang.annotation.After;

@Aspect
public class AfterFinallyExample {

  @After("com.xyz.myapp.SystemArchitecture.dataAccessOperation()")
  public void doReleaseLock() {
    <lineannotation>// ...</lineannotation>
  }

}</programlisting>
      </section>

      <section id="aop-ataspectj-around-advice">
        <title>Around advice</title>

        <para>The final kind of advice is around advice. Around advice runs
        "around" a matched method execution. It has the opportunity to do work
        both before and after the method executes, and to determine when, how,
        and even if, the method actually gets to execute at all. Around advice
        is often used if you need to share state before and after a method
        execution in a thread-safe manner (starting and stopping a timer for
        example). Always use the least powerful form of advice that meets your
        requirements (i.e. don't use around advice if simple before advice
        would do).</para>

        <para>Around advice is declared using the
        <interfacename>@Around</interfacename> annotation. The first parameter
        of the advice method must be of type
        <interfacename>ProceedingJoinPoint</interfacename>. Within the body of
        the advice, calling <literal>proceed()</literal> on the
        <interfacename>ProceedingJoinPoint</interfacename> causes the
        underlying method to execute. The <literal>proceed</literal> method
        may also be called passing in an <classname>Object[]</classname> - the
        values in the array will be used as the arguments to the method
        execution when it proceeds.</para>

        <remark>The behavior of proceed when called with an
        <classname>Object[]</classname> is a little different than the
        behavior of proceed for around advice compiled by the AspectJ
        compiler. For around advice written using the traditional AspectJ
        language, the number of arguments passed to proceed must match the
        number of arguments passed to the around advice (not the number of
        arguments taken by the underlying join point), and the value passed to
        proceed in a given argument position supplants the original value at
        the join point for the entity the value was bound to (Don't worry if
        this doesn't make sense right now!). The approach taken by Spring is
        simpler and a better match to its proxy-based, execution only
        semantics. You only need to be aware of this difference if you are
        compiling @AspectJ aspects written for Spring and using proceed with
        arguments with the AspectJ compiler and weaver. There is a way to
        write such aspects that is 100% compatible across both Spring AOP and
        AspectJ, and this is discussed in the following section on advice
        parameters.</remark>

1156
        <programlisting language="java">import org.aspectj.lang.annotation.Aspect;
1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.ProceedingJoinPoint;

@Aspect
public class AroundExample {

  @Around("com.xyz.myapp.SystemArchitecture.businessService()")
  public Object doBasicProfiling(ProceedingJoinPoint pjp) throws Throwable {
    // start stopwatch
    Object retVal = pjp.proceed();
    // stop stopwatch
    return retVal;
  }

}</programlisting>

        <para>The value returned by the around advice will be the return value
        seen by the caller of the method. A simple caching aspect for example
        could return a value from a cache if it has one, and invoke proceed()
        if it does not. Note that proceed may be invoked once, many times, or
        not at all within the body of the around advice, all of these are
        quite legal.</para>
      </section>

      <section id="aop-ataspectj-advice-params">
        <title>Advice parameters</title>

        <para>Spring 2.0 offers fully typed advice - meaning that you declare
        the parameters you need in the advice signature (as we saw for the
        returning and throwing examples above) rather than work with
        <classname>Object[]</classname> arrays all the time. We'll see how to
        make argument and other contextual values available to the advice body
        in a moment. First let's take a look at how to write generic advice
        that can find out about the method the advice is currently
        advising.</para>

        <section id="aop-ataspectj-advice-params-the-joinpoint">
          <title>Access to the current
          <interfacename>JoinPoint</interfacename></title>

          <para>Any advice method may declare as its first parameter, a
          parameter of type
          <interfacename>org.aspectj.lang.JoinPoint</interfacename> (please
          note that around advice is <emphasis>required</emphasis> to declare
          a first parameter of type
          <interfacename>ProceedingJoinPoint</interfacename>, which is a
          subclass of <interfacename>JoinPoint</interfacename>. The
          <interfacename>JoinPoint</interfacename> interface provides a number
          of useful methods such as <literal>getArgs()</literal> (returns the
          method arguments), <methodname>getThis()</methodname> (returns the
          proxy object), <methodname>getTarget()</methodname> (returns the
          target object), <methodname>getSignature()</methodname> (returns a
          description of the method that is being advised) and
          <methodname>toString()</methodname> (prints a useful description of
          the method being advised). Please do consult the Javadocs for full
          details.</para>
        </section>

        <section id="aop-ataspectj-advice-params-passing">
          <title>Passing parameters to advice</title>

          <para>We've already seen how to bind the returned value or exception
          value (using after returning and after throwing advice). To make
          argument values available to the advice body, you can use the
          binding form of <literal>args</literal>. If a parameter name is used
          in place of a type name in an args expression, then the value of the
          corresponding argument will be passed as the parameter value when
          the advice is invoked. An example should make this clearer. Suppose
          you want to advise the execution of dao operations that take an
          Account object as the first parameter, and you need access to the
          account in the advice body. You could write the following:</para>

1229
          <programlisting language="java">@Before("com.xyz.myapp.SystemArchitecture.dataAccessOperation() &amp;&amp;" + 
1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247
        "args(account,..)")
public void validateAccount(Account account) {
  <lineannotation>// ...</lineannotation>
}</programlisting>

          <para>The <literal>args(account,..)</literal> part of the pointcut
          expression serves two purposes: firstly, it restricts matching to
          only those method executions where the method takes at least one
          parameter, and the argument passed to that parameter is an instance
          of <classname>Account</classname>; secondly, it makes the actual
          <classname>Account</classname> object available to the advice via
          the <literal>account</literal> parameter.</para>

          <para>Another way of writing this is to declare a pointcut that
          "provides" the <classname>Account</classname> object value when it
          matches a join point, and then just refer to the named pointcut from
          the advice. This would look as follows:</para>

1248
          <programlisting language="java">@Pointcut("com.xyz.myapp.SystemArchitecture.dataAccessOperation() &amp;&amp;" + 
1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270
          "args(account,..)")
private void accountDataAccessOperation(Account account) {}

@Before("accountDataAccessOperation(account)")
public void validateAccount(Account account) {
  <lineannotation>// ...</lineannotation>
}</programlisting>

          <para>The interested reader is once more referred to the AspectJ
          programming guide for more details.</para>

          <para>The proxy object (<literal>this</literal>), target object
          (<literal>target</literal>), and annotations (<literal>@within,
          @target, @annotation, @args</literal>) can all be bound in a similar
          fashion. The following example shows how you could match the
          execution of methods annotated with an
          <interfacename>@Auditable</interfacename> annotation, and extract
          the audit code.</para>

          <para>First the definition of the
          <interfacename>@Auditable</interfacename> annotation:</para>

1271
          <programlisting language="java">@Retention(RetentionPolicy.RUNTIME)
1272 1273 1274 1275 1276 1277 1278 1279
@Target(ElementType.METHOD)
public @interface Auditable {
	AuditCode value();
}</programlisting>

          <para>And then the advice that matches the execution of
          <interfacename>@Auditable</interfacename> methods:</para>

1280
          <programlisting language="java">@Before("com.xyz.lib.Pointcuts.anyPublicMethod() &amp;&amp; " + 
1281 1282 1283 1284 1285 1286 1287
        "@annotation(auditable)")
public void audit(Auditable auditable) {
  AuditCode code = auditable.value();
  <lineannotation>// ...</lineannotation>
}</programlisting>
        </section>

1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325
        <section id="aop-ataspectj-advice-params-generics">
          <title>Advice parameters and generics</title>

          <para>Spring AOP can handle generics used in class declarations and
          method parameters. Suppose you have a generic type like this:</para>

          <programlisting language="java">public interface Sample&lt;T&gt; {
  void sampleGenericMethod(T param);
  void sampleGenericCollectionMethod(Collection&gt;T&gt; param);
}</programlisting>

          <para>You can restrict interception of method types to certain
          parameter types by simply typing the advice parameter to the
          parameter type you want to intercept the method for:</para>

          <programlisting language="java">@Before("execution(* ..Sample+.sampleGenericMethod(*)) &amp;&amp; args(param)")
public void beforeSampleMethod(MyType param) {
  // Advice implementation
}</programlisting>

          <para>That this works is pretty obvious as we already discussed
          above. However, it's worth pointing out that this won't work for
          generic collections. So you cannot define a pointcut like
          this:</para>

          <programlisting language="java">@Before("execution(* ..Sample+.sampleGenericCollectionMethod(*)) &amp;&amp; args(param)")
public void beforeSampleMethod(Collection&lt;MyType&gt; param) {
  // Advice implementation
}</programlisting>

          <para>To make this work we would have to inspect every element of
          the collection, which is not reasonable as we also cannot decide how
          to treat <literal>null</literal> values in general. To achieve
          something similar to this you have to type the parameter to
          <interfacename>Collection&lt;?&gt;</interfacename> and manually
          check the type of the elements.</para>
        </section>

1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345
        <section id="aop-ataspectj-advice-params-names">
          <title>Determining argument names</title>

          <para>The parameter binding in advice invocations relies on matching
          names used in pointcut expressions to declared parameter names in
          (advice and pointcut) method signatures. Parameter names are
          <emphasis>not</emphasis> available through Java reflection, so
          Spring AOP uses the following strategies to determine parameter
          names:</para>

          <orderedlist>
            <listitem>
              <para>If the parameter names have been specified by the user
              explicitly, then the specified parameter names are used: both
              the advice and the pointcut annotations have an optional
              "argNames" attribute which can be used to specify the argument
              names of the annotated method - these argument names
              <emphasis>are</emphasis> available at runtime. For
              example:</para>

1346
              <programlisting language="java">@Before(
1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362
   value="com.xyz.lib.Pointcuts.anyPublicMethod() &amp;&amp; target(bean) &amp;&amp; @annotation(auditable)",
   argNames="bean,auditable")
public void audit(Object bean, Auditable auditable) {
  AuditCode code = auditable.value();
  <lineannotation>// ... use code and bean</lineannotation>
}</programlisting>

              <para>If the first parameter is of the
              <interfacename>JoinPoint</interfacename>,
              <interfacename>ProceedingJoinPoint</interfacename>, or
              <interfacename>JoinPoint.StaticPart</interfacename> type, you
              may leave out the name of the parameter from the value of the
              "argNames" attribute. For example, if you modify the preceding
              advice to receive the join point object, the "argNames"
              attribute need not include it:</para>

1363
              <programlisting language="java">@Before(
1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379
   value="com.xyz.lib.Pointcuts.anyPublicMethod() &amp;&amp; target(bean) &amp;&amp; @annotation(auditable)",
   argNames="bean,auditable")
public void audit(JoinPoint jp, Object bean, Auditable auditable) {
  AuditCode code = auditable.value();
  <lineannotation>// ... use code, bean, and jp</lineannotation>
}</programlisting>

              <para>The special treatment given to the first parameter of the
              <interfacename>JoinPoint</interfacename>,
              <interfacename>ProceedingJoinPoint</interfacename>, and
              <interfacename>JoinPoint.StaticPart</interfacename> types is
              particularly convenient for advice that do not collect any other
              join point context. In such situations, you may simply omit the
              "argNames" attribute. For example, the following advice need not
              declare the "argNames" attribute:</para>

1380
              <programlisting language="java">@Before(
1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437
   "com.xyz.lib.Pointcuts.anyPublicMethod()")
public void audit(JoinPoint jp) {
  <lineannotation>// ... use jp</lineannotation>
}</programlisting>
            </listitem>

            <listitem>
              <para>Using the <literal>'argNames'</literal> attribute is a
              little clumsy, so if the <literal>'argNames'</literal> attribute
              has not been specified, then Spring AOP will look at the debug
              information for the class and try to determine the parameter
              names from the local variable table. This information will be
              present as long as the classes have been compiled with debug
              information (<literal>'-g:vars'</literal> at a minimum). The
              consequences of compiling with this flag on are: (1) your code
              will be slightly easier to understand (reverse engineer), (2)
              the class file sizes will be very slightly bigger (typically
              inconsequential), (3) the optimization to remove unused local
              variables will not be applied by your compiler. In other words,
              you should encounter no difficulties building with this flag
              on.</para>

              <remark>If an @AspectJ aspect has been compiled by the AspectJ
              compiler (ajc) even without the debug information then there is
              no need to add the <literal>argNames</literal> attribute as the
              compiler will retain the needed information.</remark>
            </listitem>

            <listitem>
              <para>If the code has been compiled without the necessary debug
              information, then Spring AOP will attempt to deduce the pairing
              of binding variables to parameters (for example, if only one
              variable is bound in the pointcut expression, and the advice
              method only takes one parameter, the pairing is obvious!). If
              the binding of variables is ambiguous given the available
              information, then an
              <exceptionname>AmbiguousBindingException</exceptionname> will be
              thrown.</para>
            </listitem>

            <listitem>
              <para>If all of the above strategies fail then an
              <exceptionname>IllegalArgumentException</exceptionname> will be
              thrown.</para>
            </listitem>
          </orderedlist>
        </section>

        <section id="aop-ataspectj-advice-proceeding-with-the-call">
          <title>Proceeding with arguments</title>

          <para>We remarked earlier that we would describe how to write a
          proceed call <emphasis>with arguments</emphasis> that works
          consistently across Spring AOP and AspectJ. The solution is simply
          to ensure that the advice signature binds each of the method
          parameters in order. For example:</para>

1438
          <programlisting language="java">@Around("execution(List&lt;Account&gt; find*(..)) &amp;&amp;" +
1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505
        "com.xyz.myapp.SystemArchitecture.inDataAccessLayer() &amp;&amp; " +
        "args(accountHolderNamePattern)")		
public Object preProcessQueryPattern(ProceedingJoinPoint pjp, String accountHolderNamePattern)
throws Throwable {
  String newPattern = preProcess(accountHolderNamePattern);
  return pjp.proceed(new Object[] {newPattern});
}        
</programlisting>

          <para>In many cases you will be doing this binding anyway (as in the
          example above).</para>
        </section>
      </section>

      <section id="aop-ataspectj-advice-ordering">
        <title>Advice ordering</title>

        <para>What happens when multiple pieces of advice all want to run at
        the same join point? Spring AOP follows the same precedence rules as
        AspectJ to determine the order of advice execution. The highest
        precedence advice runs first "on the way in" (so given two pieces of
        before advice, the one with highest precedence runs first). "On the
        way out" from a join point, the highest precedence advice runs last
        (so given two pieces of after advice, the one with the highest
        precedence will run second).</para>

        <para>When two pieces of advice defined in
        <emphasis>different</emphasis> aspects both need to run at the same
        join point, unless you specify otherwise the order of execution is
        undefined. You can control the order of execution by specifying
        precedence. This is done in the normal Spring way by either
        implementing the
        <interfacename>org.springframework.core.Ordered</interfacename>
        interface in the aspect class or annotating it with the
        <interfacename>Order</interfacename> annotation. Given two aspects,
        the aspect returning the lower value from
        <literal>Ordered.getValue()</literal> (or the annotation value) has
        the higher precedence.</para>

        <para>When two pieces of advice defined in <emphasis>the
        same</emphasis> aspect both need to run at the same join point, the
        ordering is undefined (since there is no way to retrieve the
        declaration order via reflection for javac-compiled classes). Consider
        collapsing such advice methods into one advice method per join point
        in each aspect class, or refactor the pieces of advice into separate
        aspect classes - which can be ordered at the aspect level.</para>
      </section>
    </section>

    <section id="aop-introductions">
      <title>Introductions</title>

      <para>Introductions (known as inter-type declarations in AspectJ) enable
      an aspect to declare that advised objects implement a given interface,
      and to provide an implementation of that interface on behalf of those
      objects.</para>

      <para>An introduction is made using the
      <interfacename>@DeclareParents</interfacename> annotation. This
      annotation is used to declare that matching types have a new parent
      (hence the name). For example, given an interface
      <interfacename>UsageTracked</interfacename>, and an implementation of
      that interface <classname>DefaultUsageTracked</classname>, the following
      aspect declares that all implementors of service interfaces also
      implement the <interfacename>UsageTracked</interfacename> interface. (In
      order to expose statistics via JMX for example.)</para>

1506
      <programlisting language="java">@Aspect
1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529
public class UsageTracking {

  @DeclareParents(value="com.xzy.myapp.service.*+",
                  defaultImpl=DefaultUsageTracked.class)
  public static UsageTracked mixin;
  
  @Before("com.xyz.myapp.SystemArchitecture.businessService() &amp;&amp;" +
          "this(usageTracked)")
  public void recordUsage(UsageTracked usageTracked) {
    usageTracked.incrementUseCount();
  }
  
}</programlisting>

      <para>The interface to be implemented is determined by the type of the
      annotated field. The <literal>value</literal> attribute of the
      <interfacename>@DeclareParents</interfacename> annotation is an AspectJ
      type pattern :- any bean of a matching type will implement the
      UsageTracked interface. Note that in the before advice of the above
      example, service beans can be directly used as implementations of the
      <interfacename>UsageTracked</interfacename> interface. If accessing a
      bean programmatically you would write the following:</para>

1530
      <programlisting language="java">UsageTracked usageTracked = (UsageTracked) context.getBean("myService");</programlisting>
1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551
    </section>

    <section id="aop-instantiation-models">
      <title>Aspect instantiation models</title>

      <remark>(This is an advanced topic, so if you are just starting out with
      AOP you can safely skip it until later.)</remark>

      <para>By default there will be a single instance of each aspect within
      the application context. AspectJ calls this the singleton instantiation
      model. It is possible to define aspects with alternate lifecycles :-
      Spring supports AspectJ's <literal>perthis</literal> and
      <literal>pertarget</literal> instantiation models (<literal>percflow,
      percflowbelow,</literal> and <literal>pertypewithin</literal> are not
      currently supported).</para>

      <para>A "perthis" aspect is declared by specifying a
      <literal>perthis</literal> clause in the
      <interfacename>@Aspect</interfacename> annotation. Let's look at an
      example, and then we'll explain how it works.</para>

1552
      <programlisting language="java">@Aspect("perthis(com.xyz.myapp.SystemArchitecture.businessService())")
1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601
public class MyAspect {

  private int someState;
	
  @Before(com.xyz.myapp.SystemArchitecture.businessService())
  public void recordServiceUsage() {
    <lineannotation>// ...</lineannotation>
  }
  	
}</programlisting>

      <para>The effect of the <literal>'perthis'</literal> clause is that one
      aspect instance will be created for each unique service object executing
      a business service (each unique object bound to 'this' at join points
      matched by the pointcut expression). The aspect instance is created the
      first time that a method is invoked on the service object. The aspect
      goes out of scope when the service object goes out of scope. Before the
      aspect instance is created, none of the advice within it executes. As
      soon as the aspect instance has been created, the advice declared within
      it will execute at matched join points, but only when the service object
      is the one this aspect is associated with. See the AspectJ programming
      guide for more information on per-clauses.</para>

      <para>The <literal>'pertarget'</literal> instantiation model works in
      exactly the same way as perthis, but creates one aspect instance for
      each unique target object at matched join points.</para>
    </section>

    <section id="aop-ataspectj-example">
      <title>Example</title>

      <para>Now that you have seen how all the constituent parts work, let's
      put them together to do something useful!</para>

      <para>The execution of business services can sometimes fail due to
      concurrency issues (for example, deadlock loser). If the operation is
      retried, it is quite likely to succeed next time round. For business
      services where it is appropriate to retry in such conditions (idempotent
      operations that don't need to go back to the user for conflict
      resolution), we'd like to transparently retry the operation to avoid the
      client seeing a
      <classname>PessimisticLockingFailureException</classname>. This is a
      requirement that clearly cuts across multiple services in the service
      layer, and hence is ideal for implementing via an aspect.</para>

      <para>Because we want to retry the operation, we will need to use around
      advice so that we can call proceed multiple times. Here's how the basic
      aspect implementation looks:</para>

1602
      <programlisting language="java">@Aspect
1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655
public class ConcurrentOperationExecutor implements Ordered {
   
   private static final int DEFAULT_MAX_RETRIES = 2;

   private int maxRetries = DEFAULT_MAX_RETRIES;
   private int order = 1;

   public void setMaxRetries(int maxRetries) {
      this.maxRetries = maxRetries;
   }
   
   public int getOrder() {
      return this.order;
   }
   
   public void setOrder(int order) {
      this.order = order;
   }
   
   @Around("com.xyz.myapp.SystemArchitecture.businessService()")
   public Object doConcurrentOperation(ProceedingJoinPoint pjp) throws Throwable { 
      int numAttempts = 0;
      PessimisticLockingFailureException lockFailureException;
      do {
         numAttempts++;
         try { 
            return pjp.proceed();
         }
         catch(PessimisticLockingFailureException ex) {
            lockFailureException = ex;
         }
      }
      while(numAttempts &lt;= this.maxRetries);
      throw lockFailureException;
   }

}</programlisting>

      <para>Note that the aspect implements the
      <interfacename>Ordered</interfacename> interface so we can set the
      precedence of the aspect higher than the transaction advice (we want a
      fresh transaction each time we retry). The <literal>maxRetries</literal>
      and <literal>order</literal> properties will both be configured by
      Spring. The main action happens in the
      <literal>doConcurrentOperation</literal> around advice. Notice that for
      the moment we're applying the retry logic to all
      <literal>businessService()s</literal>. We try to proceed, and if we fail
      with an <classname>PessimisticLockingFailureException</classname> we
      simply try again unless we have exhausted all of our retry
      attempts.</para>

      <para>The corresponding Spring configuration is:</para>

1656
      <programlisting language="xml">&lt;aop:aspectj-autoproxy/&gt;
1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667

&lt;bean id="concurrentOperationExecutor"
  class="com.xyz.myapp.service.impl.ConcurrentOperationExecutor"&gt;
     &lt;property name="maxRetries" value="3"/&gt;
     &lt;property name="order" value="100"/&gt;  
&lt;/bean&gt;</programlisting>

      <para>To refine the aspect so that it only retries idempotent
      operations, we might define an <interfacename>Idempotent</interfacename>
      annotation:</para>

1668
      <programlisting language="java">@Retention(RetentionPolicy.RUNTIME)
1669 1670 1671 1672 1673 1674 1675 1676 1677
public @interface Idempotent {
  <lineannotation>// marker annotation</lineannotation>
}</programlisting>

      <para>and use the annotation to annotate the implementation of service
      operations. The change to the aspect to only retry idempotent operations
      simply involves refining the pointcut expression so that only
      <interfacename>@Idempotent</interfacename> operations match:</para>

1678
      <programlisting language="java">@Around("com.xyz.myapp.SystemArchitecture.businessService() &amp;&amp; " + 
1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735
        "@annotation(com.xyz.myapp.service.Idempotent)")
public Object doConcurrentOperation(ProceedingJoinPoint pjp) throws Throwable { 
  ...	
}</programlisting>
    </section>
  </section>

  <section id="aop-schema">
    <title>Schema-based AOP support</title>

    <para>If you are unable to use Java 5, or simply prefer an XML-based
    format, then Spring 2.0 also offers support for defining aspects using the
    new "aop" namespace tags. The exact same pointcut expressions and advice
    kinds are supported as when using the @AspectJ style, hence in this
    section we will focus on the new <emphasis>syntax</emphasis> and refer the
    reader to the discussion in the previous section (<xref
    linkend="aop-ataspectj" />) for an understanding of writing pointcut
    expressions and the binding of advice parameters.</para>

    <para>To use the aop namespace tags described in this section, you need to
    import the spring-aop schema as described in <xref
    linkend="xsd-config" />. See <xref
    linkend="xsd-config-body-schemas-aop" /> for how to import the tags in the
    aop namespace.</para>

    <para>Within your Spring configurations, all aspect and advisor elements
    must be placed within an <literal>&lt;aop:config&gt;</literal> element
    (you can have more than one <literal>&lt;aop:config&gt;</literal> element
    in an application context configuration). An
    <literal>&lt;aop:config&gt;</literal> element can contain pointcut,
    advisor, and aspect elements (note these must be declared in that
    order).</para>

    <warning>
      <para>The <literal>&lt;aop:config&gt;</literal> style of configuration
      makes heavy use of Spring's <link
      linkend="aop-autoproxy">auto-proxying</link> mechanism. This can cause
      issues (such as advice not being woven) if you are already using
      explicit auto-proxying via the use of
      <classname>BeanNameAutoProxyCreator</classname> or suchlike. The
      recommended usage pattern is to use either just the
      <literal>&lt;aop:config&gt;</literal> style, or just the
      <interfacename>AutoProxyCreator</interfacename> style.</para>
    </warning>

    <section id="aop-schema-declaring-an-aspect">
      <title>Declaring an aspect</title>

      <para>Using the schema support, an aspect is simply a regular Java
      object defined as a bean in your Spring application context. The state
      and behavior is captured in the fields and methods of the object, and
      the pointcut and advice information is captured in the XML.</para>

      <para>An aspect is declared using the &lt;aop:aspect&gt; element, and
      the backing bean is referenced using the <literal>ref</literal>
      attribute:</para>

1736
      <programlisting language="xml">&lt;aop:config&gt;
1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760
  &lt;aop:aspect id="myAspect" ref="aBean"&gt;
    ...
  &lt;/aop:aspect&gt;
&lt;/aop:config&gt;

&lt;bean id="aBean" class="..."&gt;
  ...
&lt;/bean&gt;</programlisting>

      <para>The bean backing the aspect ("<literal>aBean</literal>" in this
      case) can of course be configured and dependency injected just like any
      other Spring bean.</para>
    </section>

    <section id="aop-schema-pointcuts">
      <title>Declaring a pointcut</title>

      <para>A named pointcut can be declared inside an &lt;aop:config&gt;
      element, enabling the pointcut definition to be shared across several
      aspects and advisors.</para>

      <para>A pointcut representing the execution of any business service in
      the service layer could be defined as follows:</para>

1761
      <programlisting language="xml">&lt;aop:config&gt;
1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776

  &lt;aop:pointcut id="businessService" 
        expression="execution(* com.xyz.myapp.service.*.*(..))"/&gt;

&lt;/aop:config&gt;</programlisting>

      <para>Note that the pointcut expression itself is using the same AspectJ
      pointcut expression language as described in <xref
      linkend="aop-ataspectj" />. If you are using the schema based
      declaration style with Java 5, you can refer to named pointcuts defined
      in types (@Aspects) within the pointcut expression, but this feature is
      not available on JDK 1.4 and below (it relies on the Java 5 specific
      AspectJ reflection APIs). On JDK 1.5 therefore, another way of defining
      the above pointcut would be:</para>

1777
      <programlisting language="xml">&lt;aop:config&gt;
1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789

  &lt;aop:pointcut id="businessService" 
        expression="com.xyz.myapp.SystemArchitecture.businessService()"/&gt;

&lt;/aop:config&gt;</programlisting>

      <para>Assuming you have a <literal>SystemArchitecture</literal> aspect
      as described in <xref linkend="aop-common-pointcuts" />.</para>

      <para>Declaring a pointcut inside an aspect is very similar to declaring
      a top-level pointcut:</para>

1790
      <programlisting language="xml">&lt;aop:config&gt;
1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807

  &lt;aop:aspect id="myAspect" ref="aBean"&gt;

    &lt;aop:pointcut id="businessService" 
          expression="execution(* com.xyz.myapp.service.*.*(..))"/&gt;
          
    ...
    
  &lt;/aop:aspect&gt;

&lt;/aop:config&gt;</programlisting>

      <para>Much the same way in an @AspectJ aspect, pointcuts declared using
      the schema based definition style may collect join point context. For
      example, the following pointcut collects the 'this' object as the join
      point context and passes it to advice:</para>

1808
      <programlisting language="xml">&lt;aop:config&gt;
1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823

  &lt;aop:aspect id="myAspect" ref="aBean"&gt;

    &lt;aop:pointcut id="businessService" 
          expression="execution(* com.xyz.myapp.service.*.*(..)) &amp;amp;&amp;amp; this(service)"/&gt;
    &lt;aop:before pointcut-ref="businessService" method="monitor"/&gt;
    ...
    
  &lt;/aop:aspect&gt;

&lt;/aop:config&gt;</programlisting>

      <para>The advice must be declared to receive the collected join point
      context by including parameters of the matching names:</para>

1824
      <programlisting language="java">public void monitor(Object service) {
1825 1826 1827 1828 1829 1830 1831 1832
    ...
}</programlisting>

      <para>When combining pointcut sub-expressions, '&amp;&amp;' is awkward
      within an XML document, and so the keywords 'and', 'or' and 'not' can be
      used in place of '&amp;&amp;', '||' and '!' respectively. For example,
      the previous pointcut may be better written as:</para>

1833
      <programlisting language="xml">&lt;aop:config&gt;
1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866

  &lt;aop:aspect id="myAspect" ref="aBean"&gt;

    &lt;aop:pointcut id="businessService" 
          expression="execution(* com.xyz.myapp.service.*.*(..)) <emphasis
          role="bold">and</emphasis> this(service)"/&gt;
    &lt;aop:before pointcut-ref="businessService" method="monitor"/&gt;
    ...
    
  &lt;/aop:aspect&gt;

&lt;/aop:config&gt;</programlisting>

      <para>Note that pointcuts defined in this way are referred to by their
      XML id and cannot be used as named pointcuts to form composite
      pointcuts. The named pointcut support in the schema based definition
      style is thus more limited than that offered by the @AspectJ
      style.</para>
    </section>

    <section id="aop-schema-advice">
      <title>Declaring advice</title>

      <para>The same five advice kinds are supported as for the @AspectJ
      style, and they have exactly the same semantics.</para>

      <section id="aop-schema-advice-before">
        <title>Before advice</title>

        <para>Before advice runs before a matched method execution. It is
        declared inside an <literal>&lt;aop:aspect&gt;</literal> using the
        &lt;aop:before&gt; element.</para>

1867
        <programlisting language="xml">&lt;aop:aspect id="beforeExample" ref="aBean"&gt;
1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882

    &lt;aop:before 
      pointcut-ref="dataAccessOperation" 
      method="doAccessCheck"/&gt;
          
    ...
    
&lt;/aop:aspect&gt;</programlisting>

        <para>Here <literal>dataAccessOperation</literal> is the id of a
        pointcut defined at the top (<literal>&lt;aop:config&gt;</literal>)
        level. To define the pointcut inline instead, replace the
        <literal>pointcut-ref</literal> attribute with a
        <literal>pointcut</literal> attribute:</para>

1883
        <programlisting language="xml">&lt;aop:aspect id="beforeExample" ref="aBean"&gt;
1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913

    &lt;aop:before 
      pointcut="execution(* com.xyz.myapp.dao.*.*(..))" 
      method="doAccessCheck"/&gt;
          
    ...
    
&lt;/aop:aspect&gt;</programlisting>

        <para>As we noted in the discussion of the @AspectJ style, using named
        pointcuts can significantly improve the readability of your
        code.</para>

        <para>The method attribute identifies a method
        (<literal>doAccessCheck</literal>) that provides the body of the
        advice. This method must be defined for the bean referenced by the
        aspect element containing the advice. Before a data access operation
        is executed (a method execution join point matched by the pointcut
        expression), the "doAccessCheck" method on the aspect bean will be
        invoked.</para>
      </section>

      <section id="aop-schema-advice-after-returning">
        <title>After returning advice</title>

        <para>After returning advice runs when a matched method execution
        completes normally. It is declared inside an
        <literal>&lt;aop:aspect&gt;</literal> in the same way as before
        advice. For example:</para>

1914
        <programlisting language="xml">&lt;aop:aspect id="afterReturningExample" ref="aBean"&gt;
1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928

    &lt;aop:after-returning 
      pointcut-ref="dataAccessOperation" 
      method="doAccessCheck"/&gt;
          
    ...
    
&lt;/aop:aspect&gt;</programlisting>

        <para>Just as in the @AspectJ style, it is possible to get hold of the
        return value within the advice body. Use the returning attribute to
        specify the name of the parameter to which the return value should be
        passed:</para>

1929
        <programlisting language="xml">&lt;aop:aspect id="afterReturningExample" ref="aBean"&gt;
1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944

    &lt;aop:after-returning 
      pointcut-ref="dataAccessOperation"
      returning="retVal" 
      method="doAccessCheck"/&gt;
          
    ...
    
&lt;/aop:aspect&gt;</programlisting>

        <para>The doAccessCheck method must declare a parameter named
        <literal>retVal</literal>. The type of this parameter constrains
        matching in the same way as described for @AfterReturning. For
        example, the method signature may be declared as:</para>

1945
        <programlisting language="java">public void doAccessCheck(Object retVal) {...</programlisting>
1946 1947 1948 1949 1950 1951 1952 1953 1954 1955
      </section>

      <section id="aop-schema-advice-after-throwing">
        <title>After throwing advice</title>

        <para>After throwing advice executes when a matched method execution
        exits by throwing an exception. It is declared inside an
        <literal>&lt;aop:aspect&gt;</literal> using the after-throwing
        element:</para>

1956
        <programlisting language="xml">&lt;aop:aspect id="afterThrowingExample" ref="aBean"&gt;
1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970

    &lt;aop:after-throwing
      pointcut-ref="dataAccessOperation" 
      method="doRecoveryActions"/&gt;
          
    ...
    
&lt;/aop:aspect&gt;</programlisting>

        <para>Just as in the @AspectJ style, it is possible to get hold of the
        thrown exception within the advice body. Use the throwing attribute to
        specify the name of the parameter to which the exception should be
        passed:</para>

1971
        <programlisting language="xml">&lt;aop:aspect id="afterThrowingExample" ref="aBean"&gt;
1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986

    &lt;aop:after-throwing 
      pointcut-ref="dataAccessOperation"
      throwing="dataAccessEx" 
      method="doRecoveryActions"/&gt;
          
    ...
    
&lt;/aop:aspect&gt;</programlisting>

        <para>The doRecoveryActions method must declare a parameter named
        <literal>dataAccessEx</literal>. The type of this parameter constrains
        matching in the same way as described for @AfterThrowing. For example,
        the method signature may be declared as:</para>

1987
        <programlisting language="java">public void doRecoveryActions(DataAccessException dataAccessEx) {...</programlisting>
1988 1989 1990 1991 1992 1993 1994 1995 1996
      </section>

      <section id="aop-schema-advice-after-finally">
        <title>After (finally) advice</title>

        <para>After (finally) advice runs however a matched method execution
        exits. It is declared using the <literal>after</literal>
        element:</para>

1997
        <programlisting language="xml">&lt;aop:aspect id="afterFinallyExample" ref="aBean"&gt;
1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033

    &lt;aop:after
      pointcut-ref="dataAccessOperation" 
      method="doReleaseLock"/&gt;
          
    ...
    
&lt;/aop:aspect&gt;</programlisting>
      </section>

      <section id="aop-schema-advice-around">
        <title>Around advice</title>

        <para>The final kind of advice is around advice. Around advice runs
        "around" a matched method execution. It has the opportunity to do work
        both before and after the method executes, and to determine when, how,
        and even if, the method actually gets to execute at all. Around advice
        is often used if you need to share state before and after a method
        execution in a thread-safe manner (starting and stopping a timer for
        example). Always use the least powerful form of advice that meets your
        requirements; don't use around advice if simple before advice would
        do.</para>

        <para>Around advice is declared using the
        <literal>aop:around</literal> element. The first parameter of the
        advice method must be of type
        <interfacename>ProceedingJoinPoint</interfacename>. Within the body of
        the advice, calling <literal>proceed()</literal> on the
        <interfacename>ProceedingJoinPoint</interfacename> causes the
        underlying method to execute. The <literal>proceed</literal> method
        may also be calling passing in an <classname>Object[]</classname> -
        the values in the array will be used as the arguments to the method
        execution when it proceeds. See <xref
        linkend="aop-ataspectj-around-advice" /> for notes on calling proceed
        with an <classname>Object[]</classname>.</para>

2034
        <programlisting language="xml">&lt;aop:aspect id="aroundExample" ref="aBean"&gt;
2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047

    &lt;aop:around
      pointcut-ref="businessService" 
      method="doBasicProfiling"/&gt;
          
    ...
    
&lt;/aop:aspect&gt;</programlisting>

        <para>The implementation of the <literal>doBasicProfiling</literal>
        advice would be exactly the same as in the @AspectJ example (minus the
        annotation of course):</para>

2048
        <programlisting language="java">public Object doBasicProfiling(ProceedingJoinPoint pjp) throws Throwable {
2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069
    <lineannotation>// start stopwatch</lineannotation>
    Object retVal = pjp.proceed();
    <lineannotation>// stop stopwatch</lineannotation>
    return retVal;
}</programlisting>
      </section>

      <section id="aop-schema-params">
        <title>Advice parameters</title>

        <para>The schema based declaration style supports fully typed advice
        in the same way as described for the @AspectJ support - by matching
        pointcut parameters by name against advice method parameters. See
        <xref linkend="aop-ataspectj-advice-params" /> for details. If you
        wish to explicitly specify argument names for the advice methods (not
        relying on the detection strategies previously described) then this is
        done using the <literal>arg-names</literal> attribute of the advice
        element, which is treated in the same manner to the "argNames"
        attribute in an advice annotation as described in <xref
        linkend="aop-ataspectj-advice-params-names" />. For example:</para>

2070
        <programlisting language="xml">&lt;aop:before
2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081
  pointcut="com.xyz.lib.Pointcuts.anyPublicMethod() and @annotation(auditable)"
  method="audit"
  arg-names="auditable"/&gt;</programlisting>

        <para>The <literal>arg-names</literal> attribute accepts a
        comma-delimited list of parameter names.</para>

        <para>Find below a slightly more involved example of the XSD-based
        approach that illustrates some around advice used in conjunction with
        a number of strongly typed parameters.</para>

2082
        <programlisting language="java">package x.y.service;
2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103

public interface FooService {

   Foo getFoo(String fooName, int age);
}

public class DefaultFooService implements FooService {

   public Foo getFoo(String name, int age) {
      return new Foo(name, age);
   }
}</programlisting>

        <para>Next up is the aspect. Notice the fact that the
        <methodname>profile(..)</methodname> method accepts a number of
        strongly-typed parameters, the first of which happens to be the join
        point used to proceed with the method call: the presence of this
        parameter is an indication that the
        <methodname>profile(..)</methodname> is to be used as
        <literal>around</literal> advice:</para>

2104
        <programlisting language="java">package x.y;
2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127

import org.aspectj.lang.ProceedingJoinPoint;
import org.springframework.util.StopWatch;

public class SimpleProfiler {

   public Object profile(ProceedingJoinPoint call, String name, int age) throws Throwable {
      StopWatch clock = new StopWatch(
            "Profiling for '" + name + "' and '" + age + "'");
      try {
         clock.start(call.toShortString());
         return call.proceed();
      } finally {
         clock.stop();
         System.out.println(clock.prettyPrint());
      }
   }
}</programlisting>

        <para>Finally, here is the XML configuration that is required to
        effect the execution of the above advice for a particular join
        point:</para>

2128
        <programlisting language="xml">&lt;beans xmlns="http://www.springframework.org/schema/beans"
2129 2130 2131
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xmlns:aop="http://www.springframework.org/schema/aop"
      xsi:schemaLocation="
2132 2133
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"&gt;
2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158

   <lineannotation>&lt;!-- this is the object that will be proxied by Spring's AOP infrastructure --&gt;</lineannotation>
   &lt;bean id="fooService" class="x.y.service.DefaultFooService"/&gt;

   <lineannotation>&lt;!-- this is the actual advice itself --&gt;</lineannotation>
   &lt;bean id="profiler" class="x.y.SimpleProfiler"/&gt;

   &lt;aop:config&gt;
      &lt;aop:aspect ref="profiler"&gt;

         &lt;aop:pointcut id="theExecutionOfSomeFooServiceMethod"
                    expression="execution(* x.y.service.FooService.getFoo(String,int))
                    and args(name, age)"/&gt;

         &lt;aop:around pointcut-ref="theExecutionOfSomeFooServiceMethod"
                  method="profile"/&gt;

      &lt;/aop:aspect&gt;
   &lt;/aop:config&gt;

&lt;/beans&gt;</programlisting>

        <para>If we had the following driver script, we would get output
        something like this on standard output:</para>

2159
        <programlisting language="java">import org.springframework.beans.factory.BeanFactory;
2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210
import org.springframework.context.support.ClassPathXmlApplicationContext;
import x.y.service.FooService;

public final class Boot {

   public static void main(final String[] args) throws Exception {
      BeanFactory ctx = new ClassPathXmlApplicationContext("x/y/plain.xml");
      FooService foo = (FooService) ctx.getBean("fooService");
      foo.getFoo("Pengo", 12);
   }
}</programlisting>

        <programlisting>StopWatch 'Profiling for 'Pengo' and '12'': running time (millis) = 0
-----------------------------------------
ms     %     Task name
-----------------------------------------
00000  ?  execution(getFoo)</programlisting>
      </section>

      <section id="aop-ordering">
        <title>Advice ordering</title>

        <para>When multiple advice needs to execute at the same join point
        (executing method) the ordering rules are as described in <xref
        linkend="aop-ataspectj-advice-ordering" />. The precedence between
        aspects is determined by either adding the
        <interfacename>Order</interfacename> annotation to the bean backing
        the aspect or by having the bean implement the
        <interfacename>Ordered</interfacename> interface.</para>
      </section>
    </section>

    <section id="aop-schema-introductions">
      <title>Introductions</title>

      <para>Introductions (known as inter-type declarations in AspectJ) enable
      an aspect to declare that advised objects implement a given interface,
      and to provide an implementation of that interface on behalf of those
      objects.</para>

      <para>An introduction is made using the
      <literal>aop:declare-parents</literal> element inside an
      <literal>aop:aspect</literal> This element is used to declare that
      matching types have a new parent (hence the name). For example, given an
      interface <interfacename>UsageTracked</interfacename>, and an
      implementation of that interface
      <classname>DefaultUsageTracked</classname>, the following aspect
      declares that all implementors of service interfaces also implement the
      <interfacename>UsageTracked</interfacename> interface. (In order to
      expose statistics via JMX for example.)</para>

2211
      <programlisting language="xml">&lt;aop:aspect id="usageTrackerAspect" ref="usageTracking"&gt;
2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227

  &lt;aop:declare-parents
      types-matching="com.xzy.myapp.service.*+"
      implement-interface="com.xyz.myapp.service.tracking.UsageTracked"
      default-impl="com.xyz.myapp.service.tracking.DefaultUsageTracked"/&gt;
  
  &lt;aop:before
    pointcut="com.xyz.myapp.SystemArchitecture.businessService()
              and this(usageTracked)"
    method="recordUsage"/&gt;
  
&lt;/aop:aspect&gt;</programlisting>

      <para>The class backing the <literal>usageTracking</literal> bean would
      contain the method:</para>

2228
      <programlisting language="java">public void recordUsage(UsageTracked usageTracked) {
2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241
    usageTracked.incrementUseCount();
}</programlisting>

      <para>The interface to be implemented is determined by
      <literal>implement-interface</literal> attribute. The value of the
      <literal>types-matching</literal> attribute is an AspectJ type pattern
      :- any bean of a matching type will implement the
      <interfacename>UsageTracked</interfacename> interface. Note that in the
      before advice of the above example, service beans can be directly used
      as implementations of the <interfacename>UsageTracked</interfacename>
      interface. If accessing a bean programmatically you would write the
      following:</para>

2242
      <programlisting language="java">UsageTracked usageTracked = (UsageTracked) context.getBean("myService");</programlisting>
2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268
    </section>

    <section id="aop-schema-instatiation-models">
      <title>Aspect instantiation models</title>

      <para>The only supported instantiation model for schema-defined aspects
      is the singleton model. Other instantiation models may be supported in
      future releases.</para>
    </section>

    <section id="aop-schema-advisors">
      <title>Advisors</title>

      <para>The concept of "advisors" is brought forward from the AOP support
      defined in Spring 1.2 and does not have a direct equivalent in AspectJ.
      An advisor is like a small self-contained aspect that has a single piece
      of advice. The advice itself is represented by a bean, and must
      implement one of the advice interfaces described in <xref
      linkend="aop-api-advice-types" />. Advisors can take advantage of
      AspectJ pointcut expressions though.</para>

      <para>Spring 2.0 supports the advisor concept with the
      <literal>&lt;aop:advisor&gt;</literal> element. You will most commonly
      see it used in conjunction with transactional advice, which also has its
      own namespace support in Spring 2.0. Here's how it looks:</para>

2269
      <programlisting language="xml">&lt;aop:config&gt;
2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317

  &lt;aop:pointcut id="businessService"
        expression="execution(* com.xyz.myapp.service.*.*(..))"/&gt;

  &lt;aop:advisor 
      pointcut-ref="businessService"
      advice-ref="tx-advice"/&gt;
      
&lt;/aop:config&gt;

&lt;tx:advice id="tx-advice"&gt;
  &lt;tx:attributes&gt;
    &lt;tx:method name="*" propagation="REQUIRED"/&gt;
  &lt;/tx:attributes&gt;
&lt;/tx:advice&gt;</programlisting>
    </section>

    <para>As well as the <literal>pointcut-ref</literal> attribute used in the
    above example, you can also use the <literal>pointcut</literal> attribute
    to define a pointcut expression inline.</para>

    <para>To define the precedence of an advisor so that the advice can
    participate in ordering, use the <literal>order</literal> attribute to
    define the <literal>Ordered</literal> value of the advisor.</para>

    <section id="aop-schema-example">
      <title>Example</title>

      <para>Let's see how the concurrent locking failure retry example from
      <xref linkend="aop-ataspectj-example" /> looks when rewritten using the
      schema support.</para>

      <para>The execution of business services can sometimes fail due to
      concurrency issues (for example, deadlock loser). If the operation is
      retried, it is quite likely it will succeed next time round. For
      business services where it is appropriate to retry in such conditions
      (idempotent operations that don't need to go back to the user for
      conflict resolution), we'd like to transparently retry the operation to
      avoid the client seeing a
      <classname>PessimisticLockingFailureException</classname>. This is a
      requirement that clearly cuts across multiple services in the service
      layer, and hence is ideal for implementing via an aspect.</para>

      <para>Because we want to retry the operation, we'll need to use around
      advice so that we can call proceed multiple times. Here's how the basic
      aspect implementation looks (it's just a regular Java class using the
      schema support):</para>

2318
      <programlisting language="java">public class ConcurrentOperationExecutor implements Ordered {
2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370
   
   private static final int DEFAULT_MAX_RETRIES = 2;

   private int maxRetries = DEFAULT_MAX_RETRIES;
   private int order = 1;

   public void setMaxRetries(int maxRetries) {
      this.maxRetries = maxRetries;
   }
   
   public int getOrder() {
      return this.order;
   }
   
   public void setOrder(int order) {
      this.order = order;
   }
   
   public Object doConcurrentOperation(ProceedingJoinPoint pjp) throws Throwable { 
      int numAttempts = 0;
      PessimisticLockingFailureException lockFailureException;
      do {
         numAttempts++;
         try { 
            return pjp.proceed();
         }
         catch(PessimisticLockingFailureException ex) {
            lockFailureException = ex;
         }
      }
      while(numAttempts &lt;= this.maxRetries);
      throw lockFailureException;
   }

}</programlisting>

      <para>Note that the aspect implements the
      <interfacename>Ordered</interfacename> interface so we can set the
      precedence of the aspect higher than the transaction advice (we want a
      fresh transaction each time we retry). The <literal>maxRetries</literal>
      and <literal>order</literal> properties will both be configured by
      Spring. The main action happens in the
      <literal>doConcurrentOperation</literal> around advice method. We try to
      proceed, and if we fail with a
      <classname>PessimisticLockingFailureException</classname> we simply try
      again unless we have exhausted all of our retry attempts.</para>

      <remark>This class is identical to the one used in the @AspectJ example,
      but with the annotations removed.</remark>

      <para>The corresponding Spring configuration is:</para>

2371
      <programlisting language="xml">&lt;aop:config&gt;
2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397

  &lt;aop:aspect id="concurrentOperationRetry" ref="concurrentOperationExecutor"&gt;

    &lt;aop:pointcut id="idempotentOperation"
        expression="execution(* com.xyz.myapp.service.*.*(..))"/&gt;
       
    &lt;aop:around
       pointcut-ref="idempotentOperation"
       method="doConcurrentOperation"/&gt;
  
  &lt;/aop:aspect&gt;

&lt;/aop:config&gt;

&lt;bean id="concurrentOperationExecutor"
  class="com.xyz.myapp.service.impl.ConcurrentOperationExecutor"&gt;
     &lt;property name="maxRetries" value="3"/&gt;
     &lt;property name="order" value="100"/&gt;  
&lt;/bean&gt;</programlisting>

      <para>Notice that for the time being we assume that all business
      services are idempotent. If this is not the case we can refine the
      aspect so that it only retries genuinely idempotent operations, by
      introducing an <interfacename>Idempotent</interfacename>
      annotation:</para>

2398
      <programlisting language="java">@Retention(RetentionPolicy.RUNTIME)
2399 2400 2401 2402 2403 2404 2405 2406 2407
public @interface Idempotent {
  <lineannotation>// marker annotation</lineannotation>
}</programlisting>

      <para>and using the annotation to annotate the implementation of service
      operations. The change to the aspect to retry only idempotent operations
      simply involves refining the pointcut expression so that only
      <interfacename>@Idempotent</interfacename> operations match:</para>

2408
      <programlisting language="xml">  &lt;aop:pointcut id="idempotentOperation"
2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483
        expression="execution(* com.xyz.myapp.service.*.*(..)) and
                    @annotation(com.xyz.myapp.service.Idempotent)"/&gt;</programlisting>
    </section>
  </section>

  <section id="aop-choosing">
    <title>Choosing which AOP declaration style to use</title>

    <para>Once you have decided that an aspect is the best approach for
    implementing a given requirement, how do you decide between using Spring
    AOP or AspectJ, and between the Aspect language (code) style, @AspectJ
    annotation style, or the Spring XML style? These decisions are influenced
    by a number of factors including application requirements, development
    tools, and team familiarity with AOP.</para>

    <section id="aop-spring-or-aspectj">
      <title>Spring AOP or full AspectJ?</title>

      <para>Use the simplest thing that can work. Spring AOP is simpler than
      using full AspectJ as there is no requirement to introduce the AspectJ
      compiler / weaver into your development and build processes. If you only
      need to advise the execution of operations on Spring beans, then Spring
      AOP is the right choice. If you need to advise objects not managed by
      the Spring container (such as domain objects typically), then you will
      need to use AspectJ. You will also need to use AspectJ if you wish to
      advise join points other than simple method executions (for example,
      field get or set join points, and so on).</para>

      <para>When using AspectJ, you have the choice of the AspectJ language
      syntax (also known as the "code style") or the @AspectJ annotation
      style. Clearly, if you are not using Java 5+ then the choice has been
      made for you... use the code style. If aspects play a large role in your
      design, and you are able to use the <ulink
      url="http://www.eclipse.org/ajdt/">AspectJ Development Tools
      (AJDT)</ulink> plugin for Eclipse, then the AspectJ language syntax is
      the preferred option: it is cleaner and simpler because the language was
      purposefully designed for writing aspects. If you are not using Eclipse,
      or have only a few aspects that do not play a major role in your
      application, then you may want to consider using the @AspectJ style and
      sticking with a regular Java compilation in your IDE, and adding an
      aspect weaving phase to your build script.</para>
    </section>

    <section id="aop-ataspectj-or-xml">
      <title>@AspectJ or XML for Spring AOP?</title>

      <para>If you have chosen to use Spring AOP, then you have a choice of
      @AspectJ or XML style. Clearly if you are not running on Java 5+, then
      the XML style is the appropriate choice; for Java 5 projects there are
      various tradeoffs to consider.</para>

      <para>The XML style will be most familiar to existing Spring users. It
      can be used with any JDK level (referring to named pointcuts from within
      pointcut expressions does still require Java 5+ though) and is backed by
      genuine POJOs. When using AOP as a tool to configure enterprise services
      then XML can be a good choice (a good test is whether you consider the
      pointcut expression to be a part of your configuration you might want to
      change independently). With the XML style arguably it is clearer from
      your configuration what aspects are present in the system.</para>

      <para>The XML style has two disadvantages. Firstly it does not fully
      encapsulate the implementation of the requirement it addresses in a
      single place. The DRY principle says that there should be a single,
      unambiguous, authoritative representation of any piece of knowledge
      within a system. When using the XML style, the knowledge of
      <emphasis>how</emphasis> a requirement is implemented is split across
      the declaration of the backing bean class, and the XML in the
      configuration file. When using the @AspectJ style there is a single
      module - the aspect - in which this information is encapsulated.
      Secondly, the XML style is slightly more limited in what it can express
      than the @AspectJ style: only the "singleton" aspect instantiation model
      is supported, and it is not possible to combine named pointcuts declared
      in XML. For example, in the @AspectJ style you can write something
      like:</para>

2484
      <programlisting language="java">  @Pointcut(execution(* get*()))
2485 2486 2487 2488 2489 2490 2491 2492 2493 2494
  public void propertyAccess() {}

  @Pointcut(execution(org.xyz.Account+ *(..))
  public void operationReturningAnAccount() {}

  @Pointcut(propertyAccess() &amp;&amp; operationReturningAnAccount())
  public void accountPropertyAccess() {}</programlisting>

      <para>In the XML style I can declare the first two pointcuts:</para>

2495
      <programlisting language="xml">  &lt;aop:pointcut id="propertyAccess"
2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574
      expression="execution(* get*())"/&gt;

  &lt;aop:pointcut id="operationReturningAnAccount"
      expression="execution(org.xyz.Account+ *(..))"/&gt;</programlisting>

      <para>The downside of the XML approach is that you cannot define the
      '<literal>accountPropertyAccess</literal>' pointcut by combining these
      definitions.</para>

      <para>The @AspectJ style supports additional instantiation models, and
      richer pointcut composition. It has the advantage of keeping the aspect
      as a modular unit. It also has the advantage the @AspectJ aspects can be
      understood (and thus consumed) both by Spring AOP and by AspectJ - so if
      you later decide you need the capabilities of AspectJ to implement
      additional requirements then it is very easy to migrate to an
      AspectJ-based approach. On balance the Spring team prefer the @AspectJ
      style whenever you have aspects that do more than simple "configuration"
      of enterprise services.</para>
    </section>
  </section>

  <section id="aop-mixing-styles">
    <title>Mixing aspect types</title>

    <para>It is perfectly possible to mix @AspectJ style aspects using the
    autoproxying support, schema-defined <literal>&lt;aop:aspect&gt;</literal>
    aspects, <literal>&lt;aop:advisor&gt;</literal> declared advisors and even
    proxies and interceptors defined using the Spring 1.2 style in the same
    configuration. All of these are implemented using the same underlying
    support mechanism and will co-exist without any difficulty.</para>
  </section>

  <section id="aop-proxying">
    <title>Proxying mechanisms</title>

    <para>Spring AOP uses either JDK dynamic proxies or CGLIB to create the
    proxy for a given target object. (JDK dynamic proxies are preferred
    whenever you have a choice).</para>

    <para>If the target object to be proxied implements at least one interface
    then a JDK dynamic proxy will be used. All of the interfaces implemented
    by the target type will be proxied. If the target object does not
    implement any interfaces then a CGLIB proxy will be created.</para>

    <para>If you want to force the use of CGLIB proxying (for example, to
    proxy every method defined for the target object, not just those
    implemented by its interfaces) you can do so. However, there are some
    issues to consider:</para>

    <itemizedlist>
      <listitem>
        <para><literal>final</literal> methods cannot be advised, as they
        cannot be overriden.</para>
      </listitem>

      <listitem>
        <para>You will need the CGLIB 2 binaries on your classpath, whereas
        dynamic proxies are available with the JDK. Spring will automatically
        warn you when it needs CGLIB and the CGLIB library classes are not
        found on the classpath.</para>
      </listitem>

      <listitem>
        <para>The constructor of your proxied object will be called twice.
        This is a natural consequence of the CGLIB proxy model whereby a
        subclass is generated for each proxied object. For each proxied
        instance, two objects are created: the actual proxied object and an
        instance of the subclass that implements the advice. This behavior is
        not exhibited when using JDK proxies. Usually, calling the constructor
        of the proxied type twice, is not an issue, as there are usually only
        assignments taking place and no real logic is implemented in the
        constructor.</para>
      </listitem>
    </itemizedlist>

    <para id="aop-autoproxy-force-CGLIB">To force the use of CGLIB proxies set
    the value of the <literal>proxy-target-class</literal> attribute of the
    <literal>&lt;aop:config&gt;</literal> element to true:</para>

2575
    <programlisting language="xml">&lt;aop:config <emphasis role="bold">proxy-target-class="true"</emphasis>&gt;
2576 2577 2578 2579 2580 2581 2582 2583
    <lineannotation>&lt;!-- other beans defined here... --&gt;</lineannotation>
&lt;/aop:config&gt;</programlisting>

    <para>To force CGLIB proxying when using the @AspectJ autoproxy support,
    set the <literal>'proxy-target-class'</literal> attribute of the
    <literal>&lt;aop:aspectj-autoproxy&gt;</literal> element to
    <literal>true</literal>:</para>

2584
    <programlisting language="xml">&lt;aop:aspectj-autoproxy <emphasis role="bold">proxy-target-class="true"</emphasis>/&gt;</programlisting>
2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613

    <note>
      <para>Multiple <literal>&lt;aop:config/&gt;</literal> sections are
      collapsed into a single unified auto-proxy creator at runtime, which
      applies the <emphasis>strongest</emphasis> proxy settings that any of
      the <literal>&lt;aop:config/&gt;</literal> sections (typically from
      different XML bean definition files) specified. This also applies to the
      <literal>&lt;tx:annotation-driven/&gt;</literal> and
      <literal>&lt;aop:aspectj-autoproxy/&gt;</literal> elements.</para>

      <para>To be clear: using '<literal>proxy-target-class="true"</literal>'
      on <literal>&lt;tx:annotation-driven/&gt;</literal>,
      <literal>&lt;aop:aspectj-autoproxy/&gt;</literal> or
      <literal>&lt;aop:config/&gt;</literal> elements will force the use of
      CGLIB proxies <emphasis>for all three of them</emphasis>.</para>
    </note>

    <section id="aop-understanding-aop-proxies">
      <title>Understanding AOP proxies</title>

      <para>Spring AOP is <emphasis>proxy-based</emphasis>. It is vitally
      important that you grasp the semantics of what that last statement
      actually means before you write your own aspects or use any of the
      Spring AOP-based aspects supplied with the Spring Framework.</para>

      <para>Consider first the scenario where you have a plain-vanilla,
      un-proxied, nothing-special-about-it, straight object reference, as
      illustrated by the following code snippet.</para>

2614
      <programlisting language="java">public class SimplePojo implements Pojo {
2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644

   public void foo() {
      <lineannotation>// this next method invocation is a <emphasis
            role="bold">direct</emphasis> call on the 'this' reference</lineannotation>
      this.bar();
   }
   
   public void bar() {
      <lineannotation>// some logic...</lineannotation>
   }
}</programlisting>

      <para>If you invoke a method on an object reference, the method is
      invoked <emphasis>directly</emphasis> on that object reference, as can
      be seen below.</para>

      <para><mediaobject>
          <imageobject role="fo">
            <imagedata align="center"
                       fileref="images/aop-proxy-plain-pojo-call.png"
                       format="PNG" />
          </imageobject>

          <imageobject role="html">
            <imagedata align="center"
                       fileref="images/aop-proxy-plain-pojo-call.png"
                       format="PNG" />
          </imageobject>
        </mediaobject></para>

2645
      <programlisting language="java">public class Main {
2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670

   public static void main(String[] args) {
   
      Pojo pojo = new SimplePojo();
      
      <lineannotation>// this is a <emphasis role="bold">direct</emphasis> method call on the 'pojo' reference</lineannotation>
      pojo.foo();
   }
}</programlisting>

      <para>Things change slightly when the reference that client code has is
      a proxy. Consider the following diagram and code snippet.</para>

      <para><mediaobject>
          <imageobject role="fo">
            <imagedata align="center" fileref="images/aop-proxy-call.png"
                       format="PNG" />
          </imageobject>

          <imageobject role="html">
            <imagedata align="center" fileref="images/aop-proxy-call.png"
                       format="PNG" />
          </imageobject>
        </mediaobject></para>

2671
      <programlisting language="java">public class Main {
2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710

   public static void main(String[] args) {
   
      ProxyFactory factory = new ProxyFactory(new SimplePojo());
      factory.addInterface(Pojo.class);
      factory.addAdvice(new RetryAdvice());

      Pojo pojo = (Pojo) factory.getProxy();
      
      <lineannotation>// this is a method call <emphasis role="bold">on the proxy!</emphasis></lineannotation>
      pojo.foo();
   }
}</programlisting>

      <para>The key thing to understand here is that the client code inside
      the <methodname>main(..)</methodname> of the <classname>Main</classname>
      class <emphasis>has a reference to the proxy</emphasis>. This means that
      method calls on that object reference will be calls on the proxy, and as
      such the proxy will be able to delegate to all of the interceptors
      (advice) that are relevant to that particular method call. However, once
      the call has finally reached the target object, the
      <classname>SimplePojo</classname> reference in this case, any method
      calls that it may make on itself, such as
      <methodname>this.bar()</methodname> or
      <methodname>this.foo()</methodname>, are going to be invoked against the
      <emphasis><literal>this</literal></emphasis> reference, and
      <emphasis>not</emphasis> the proxy. This has important implications. It
      means that self-invocation is <emphasis>not</emphasis> going to result
      in the advice associated with a method invocation getting a chance to
      execute.</para>

      <para>Okay, so what is to be done about this? The best approach (the
      term best is used loosely here) is to refactor your code such that the
      self-invocation does not happen. For sure, this does entail some work on
      your part, but it is the best, least-invasive approach. The next
      approach is absolutely horrendous, and I am almost reticent to point it
      out precisely because it is so horrendous. You can (choke!) totally tie
      the logic within your class to Spring AOP by doing this:</para>

2711
      <programlisting language="java">public class SimplePojo implements Pojo {
2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728

   public void foo() {
      <lineannotation>// this works, but... gah!</lineannotation>
      ((Pojo) AopContext.currentProxy()).bar();
   }
   
   public void bar() {
      <lineannotation>// some logic...</lineannotation>
   }
}</programlisting>

      <para>This totally couples your code to Spring AOP,
      <emphasis>and</emphasis> it makes the class itself aware of the fact
      that it is being used in an AOP context, which flies in the face of AOP.
      It also requires some additional configuration when the proxy is being
      created:</para>

2729
      <programlisting language="java">public class Main {
2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767

   public static void main(String[] args) {
   
      ProxyFactory factory = new ProxyFactory(new SimplePojo());
      factory.adddInterface(Pojo.class);
      factory.addAdvice(new RetryAdvice());
      <lineannotation><emphasis role="bold">factory.setExposeProxy(true);</emphasis></lineannotation>

      Pojo pojo = (Pojo) factory.getProxy();

      <lineannotation>// this is a method call <emphasis role="bold">on the proxy!</emphasis></lineannotation>
      pojo.foo();
   }
}</programlisting>

      <para>Finally, it must be noted that AspectJ does not have this
      self-invocation issue because it is not a proxy-based AOP
      framework.</para>
    </section>
  </section>

  <section id="aop-aspectj-programmatic">
    <title>Programmatic creation of @AspectJ Proxies</title>

    <para>In addition to declaring aspects in your configuration using either
    <literal>&lt;aop:config&gt;</literal> or
    <literal>&lt;aop:aspectj-autoproxy&gt;</literal>, it is also possible
    programmatically to create proxies that advise target objects. For the
    full details of Spring's AOP API, see the next chapter. Here we want to
    focus on the ability to automatically create proxies using @AspectJ
    aspects.</para>

    <para>The class
    <classname>org.springframework.aop.aspectj.annotation.AspectJProxyFactory</classname>
    can be used to create a proxy for a target object that is advised by one
    or more @AspectJ aspects. Basic usage for this class is very simple, as
    illustrated below. See the Javadocs for full information.</para>

2768
    <programlisting language="java"><lineannotation>// create a factory that can generate a proxy for the given target object</lineannotation>
2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 2821
AspectJProxyFactory factory = new AspectJProxyFactory(targetObject); 

<lineannotation>// add an aspect, the class must be an @AspectJ aspect
// you can call this as many times as you need with different aspects</lineannotation>
factory.addAspect(SecurityManager.class);

<lineannotation>// you can also add existing aspect instances, the type of the object supplied must be an @AspectJ aspect</lineannotation>
factory.addAspect(usageTracker);	

<lineannotation>// now get the proxy object...</lineannotation>
MyInterfaceType proxy = factory.getProxy();</programlisting>
  </section>

  <section id="aop-using-aspectj">
    <title>Using AspectJ with Spring applications</title>

    <para>Everything we've covered so far in this chapter is pure Spring AOP.
    In this section, we're going to look at how you can use the AspectJ
    compiler/weaver instead of, or in addition to, Spring AOP if your needs go
    beyond the facilities offered by Spring AOP alone.</para>

    <para>Spring ships with a small AspectJ aspect library, which is available
    standalone in your distribution as <filename
    class="libraryfile">spring-aspects.jar</filename>; you'll need to add this
    to your classpath in order to use the aspects in it. <xref
    linkend="aop-atconfigurable"/> and <xref linkend="aop-ajlib-other"/>
    discuss the content of this library and how you can use it. <xref
    linkend="aop-aj-configure"/> discusses how to dependency inject AspectJ
    aspects that are woven using the AspectJ compiler. Finally, <xref
    linkend="aop-aj-ltw"/> provides an introduction to load-time weaving for
    Spring applications using AspectJ.</para>

    <section id="aop-atconfigurable">
      <title>Using AspectJ to dependency inject domain objects with
      Spring</title>

      <para>The Spring container instantiates and configures beans defined in
      your application context. It is also possible to ask a bean factory to
      configure a <emphasis>pre-existing</emphasis> object given the name of a
      bean definition containing the configuration to be applied. The
      <filename class="libraryfile">spring-aspects.jar</filename> contains an
      annotation-driven aspect that exploits this capability to allow
      dependency injection of <emphasis>any object</emphasis>. The support is
      intended to be used for objects created <emphasis>outside of the control
      of any container</emphasis>. Domain objects often fall into this
      category because they are often created programmatically using the
      <literal>new</literal> operator, or by an ORM tool as a result of a
      database query.</para>

      <para>The <interfacename>@Configurable</interfacename> annotation marks
      a class as eligible for Spring-driven configuration. In the simplest
      case it can be used just as a marker annotation:</para>

2822
      <programlisting language="java">package com.xyz.myapp.domain;
2823 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833 2834 2835 2836 2837 2838 2839

import org.springframework.beans.factory.annotation.Configurable;

@Configurable
public class Account {
   <lineannotation>// ...</lineannotation>
}</programlisting>

      <para>When used as a marker interface in this way, Spring will configure
      new instances of the annotated type (<classname>Account</classname> in
      this case) using a prototype-scoped bean definition with the same name
      as the fully-qualified type name
      (<classname>com.xyz.myapp.domain.Account</classname>). Since the default
      name for a bean is the fully-qualified name of its type, a convenient
      way to declare the prototype definition is simply to omit the
      <literal>id</literal> attribute:</para>

2840
      <programlisting language="xml">&lt;bean class="com.xyz.myapp.domain.Account" scope="prototype"&gt;
2841 2842 2843 2844 2845 2846
  &lt;property name="fundsTransferService" ref="fundsTransferService"/&gt;
&lt;/bean&gt;</programlisting>

      <para>If you want to explicitly specify the name of the prototype bean
      definition to use, you can do so directly in the annotation:</para>

2847
      <programlisting language="java">package com.xyz.myapp.domain;
2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868

import org.springframework.beans.factory.annotation.Configurable;

@Configurable("account")
public class Account {
   <lineannotation>// ...</lineannotation>
}</programlisting>

      <para>Spring will now look for a bean definition named
      "<literal>account</literal>" and use that as the definition to configure
      new <classname>Account</classname> instances.</para>

      <para>You can also use autowiring to avoid having to specify a
      prototype-scoped bean definition at all. To have Spring apply autowiring
      use the '<literal>autowire</literal>' property of the
      <interfacename>@Configurable</interfacename> annotation: specify either
      <literal>@Configurable(autowire=Autowire.BY_TYPE)</literal> or
      <literal>@Configurable(autowire=Autowire.BY_NAME</literal> for
      autowiring by type or by name respectively. As an alternative, as of
      Spring 2.5 it is preferable to specify explicit, annotation-driven 
      dependency injection for your <interfacename>@Configurable</interfacename> 
M
Michael Isvy 已提交
2869 2870
      beans by using <interfacename>@Autowired</interfacename> or
      <interfacename>@Inject</interfacename> at the field or method level (see 
2871 2872 2873 2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909
      <xref linkend="beans-annotation-config" /> for further details).</para>

      <para>Finally you can enable Spring dependency checking for the object
      references in the newly created and configured object by using the
      <literal>dependencyCheck</literal> attribute (for example:
      <literal>@Configurable(autowire=Autowire.BY_NAME,dependencyCheck=true)</literal>).
      If this attribute is set to true, then Spring will validate after
      configuration that all properties (<emphasis>which are not primitives or
      collections</emphasis>) have been set.</para>

      <para>Using the annotation on its own does nothing of course. It is the
      <classname>AnnotationBeanConfigurerAspect</classname> in <filename
      class="libraryfile">spring-aspects.jar</filename> that acts on the
      presence of the annotation. In essence the aspect says "after returning
      from the initialization of a new object of a type annotated with
      <interfacename>@Configurable</interfacename>, configure the newly
      created object using Spring in accordance with the properties of the
      annotation". In this context, <emphasis>initialization</emphasis> refers
      to newly instantiated objects (e.g., objects instantiated with the
      '<literal>new</literal>' operator) as well as to
      <interfacename>Serializable</interfacename> objects that are undergoing
      deserialization (e.g., via <ulink
      url="http://java.sun.com/j2se/1.5.0/docs/api/java/io/Serializable.html">readResolve()</ulink>).</para>

      <note>
        <para>One of the key phrases in the above paragraph is '<emphasis>in
        essence</emphasis>'. For most cases, the exact semantics of
        '<emphasis>after returning from the initialization of a new
        object</emphasis>' will be fine... in this context, '<emphasis>after
        initialization</emphasis>' means that the dependencies will be
        injected <emphasis>after</emphasis> the object has been constructed -
        this means that the dependencies will not be available for use in the
        constructor bodies of the class. If you want the dependencies to be
        injected <emphasis>before</emphasis> the constructor bodies execute,
        and thus be available for use in the body of the constructors, then
        you need to define this on the
        <interfacename>@Configurable</interfacename> declaration like
        so:</para>

2910
        <programlisting language="java">@Configurable(preConstruction=true)</programlisting>
2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 2932

        <para>You can find out more information about the language semantics
        of the various pointcut types in AspectJ <ulink
        url="http://www.eclipse.org/aspectj/doc/next/progguide/semantics-joinPoints.html">in
        this appendix</ulink> of the <ulink
        url="http://www.eclipse.org/aspectj/doc/next/progguide/index.html">AspectJ
        Programming Guide</ulink>.</para>
      </note>

      <para>For this to work the annotated types must be woven with the
      AspectJ weaver - you can either use a build-time Ant or Maven task to do
      this (see for example the <ulink
      url="http://www.eclipse.org/aspectj/doc/released/devguide/antTasks.html">AspectJ
      Development Environment Guide</ulink>) or load-time weaving (see <xref
      linkend="aop-aj-ltw"/>). The
      <classname>AnnotationBeanConfigurerAspect</classname> itself needs
      configuring by Spring (in order to obtain a reference to the bean
      factory that is to be used to configure new objects). The Spring <link
      linkend="xsd-config-body-schemas-context"><literal>context</literal>
      namespace</link> defines a convenient tag for doing this: just include
      the following in your application context configuration:</para>

2933
      <programlisting language="xml">&lt;context:spring-configured/&gt;</programlisting>
2934 2935 2936 2937

      <para>If you are using the DTD instead of schema, the equivalent
      definition is:</para>

2938
      <programlisting language="xml">&lt;bean 
2939 2940 2941 2942 2943 2944 2945 2946 2947 2948 2949 2950
      class="org.springframework.beans.factory.aspectj.AnnotationBeanConfigurerAspect"
      factory-method="aspectOf"/&gt;</programlisting>

      <para>Instances of <interfacename>@Configurable</interfacename> objects
      created <emphasis>before</emphasis> the aspect has been configured will
      result in a warning being issued to the log and no configuration of the
      object taking place. An example might be a bean in the Spring
      configuration that creates domain objects when it is initialized by
      Spring. In this case you can use the "depends-on" bean attribute to
      manually specify that the bean depends on the configuration
      aspect.</para>

2951
      <programlisting language="xml">&lt;bean id="myService"
2952 2953 2954 2955 2956 2957 2958
  class="com.xzy.myapp.service.MyService"
  depends-on="org.springframework.beans.factory.aspectj.AnnotationBeanConfigurerAspect"&gt;

  <lineannotation>&lt;!-- ... --&gt;</lineannotation>

&lt;/bean&gt;</programlisting>

2959 2960 2961 2962 2963 2964 2965 2966 2967 2968
      <note>
        <para>Do not activate <interfacename>@Configurable</interfacename>
        processing through the bean configurer aspect unless you really
        mean to rely on its semantics at runtime. In particular, make sure
        that you do not use <interfacename>@Configurable</interfacename>
        on bean classes which are registered as regular Spring beans with
        the container: You would get double initialization otherwise, once
        through the container and once through the aspect.</para>
      </note>

2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 3051 3052 3053 3054 3055 3056 3057 3058 3059 3060 3061 3062 3063 3064 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074
      <section id="aop-configurable-testing">
        <title>Unit testing <interfacename>@Configurable</interfacename>
        objects</title>

        <para>One of the goals of the
        <interfacename>@Configurable</interfacename> support is to enable
        independent unit testing of domain objects without the difficulties
        associated with hard-coded lookups. If
        <interfacename>@Configurable</interfacename> types have not been woven
        by AspectJ then the annotation has no affect during unit testing, and
        you can simply set mock or stub property references in the object
        under test and proceed as normal. If
        <interfacename>@Configurable</interfacename> types
        <emphasis>have</emphasis> been woven by AspectJ then you can still
        unit test outside of the container as normal, but you will see a
        warning message each time that you construct an
        <interfacename>@Configurable</interfacename> object indicating that it
        has not been configured by Spring.</para>
      </section>

      <section id="aop-configurable-container">
        <title>Working with multiple application contexts</title>

        <para>The <classname>AnnotationBeanConfigurerAspect</classname> used
        to implement the <interfacename>@Configurable</interfacename> support
        is an AspectJ singleton aspect. The scope of a singleton aspect is the
        same as the scope of <literal>static</literal> members, that is to say
        there is one aspect instance per classloader that defines the type.
        This means that if you define multiple application contexts within the
        same classloader hierarchy you need to consider where to define the
        <literal>&lt;context:spring-configured/&gt;</literal> bean and where to
        place <filename class="libraryfile">spring-aspects.jar</filename> on
        the classpath.</para>

        <para>Consider a typical Spring web-app configuration with a shared
        parent application context defining common business services and
        everything needed to support them, and one child application context
        per servlet containing definitions particular to that servlet. All of
        these contexts will co-exist within the same classloader hierarchy,
        and so the <literal>AnnotationBeanConfigurerAspect</literal> can only
        hold a reference to one of them. In this case we recommend defining
        the <literal>&lt;context:spring-configured/&gt;</literal> bean in the
        shared (parent) application context: this defines the services that
        you are likely to want to inject into domain objects. A consequence is
        that you cannot configure domain objects with references to beans
        defined in the child (servlet-specific) contexts using the
        @Configurable mechanism (probably not something you want to do
        anyway!).</para>

        <para>When deploying multiple web-apps within the same container,
        ensure that each web-application loads the types in <filename
        class="libraryfile">spring-aspects.jar</filename> using its own
        classloader (for example, by placing <filename
        class="libraryfile">spring-aspects.jar</filename> in <filename
        class="directory">'WEB-INF/lib'</filename>). If <filename
        class="libraryfile">spring-aspects.jar</filename> is only added to the
        container wide classpath (and hence loaded by the shared parent
        classloader), all web applications will share the same aspect instance
        which is probably not what you want.</para>
      </section>
    </section>

    <section id="aop-ajlib-other">
      <title>Other Spring aspects for AspectJ</title>

      <para>In addition to the <interfacename>@Configurable</interfacename>
      aspect, <filename class="libraryfile">spring-aspects.jar</filename>
      contains an AspectJ aspect that can be used to drive Spring's
      transaction management for types and methods annotated with the
      <interfacename>@Transactional</interfacename> annotation. This is
      primarily intended for users who want to use the Spring Framework's
      transaction support outside of the Spring container.</para>

      <para>The aspect that interprets
      <interfacename>@Transactional</interfacename> annotations is the
      <classname>AnnotationTransactionAspect</classname>. When using this
      aspect, you must annotate the <emphasis>implementation</emphasis> class
      (and/or methods within that class), <emphasis>not</emphasis> the
      interface (if any) that the class implements. AspectJ follows Java's
      rule that annotations on interfaces are <emphasis>not
      inherited</emphasis>.</para>

      <para>A <interfacename>@Transactional</interfacename> annotation on a
      class specifies the default transaction semantics for the execution of
      any <emphasis>public</emphasis> operation in the class.</para>

      <para>A <interfacename>@Transactional</interfacename> annotation on a
      method within the class overrides the default transaction semantics
      given by the class annotation (if present). Methods with
      <literal>public</literal>, <literal>protected</literal>, and default
      visibility may all be annotated. Annotating <literal>protected</literal>
      and default visibility methods directly is the only way to get
      transaction demarcation for the execution of such methods.</para>

      <para>For AspectJ programmers that want to use the Spring configuration
      and transaction management support but don't want to (or cannot) use
      annotations, <filename class="libraryfile">spring-aspects.jar</filename>
      also contains <literal>abstract</literal> aspects you can extend to
      provide your own pointcut definitions. See the sources for the
      <classname>AbstractBeanConfigurerAspect</classname> and
      <classname>AbstractTransactionAspect</classname> aspects for more
      information. As an example, the following excerpt shows how you could
      write an aspect to configure all instances of objects defined in the
      domain model using prototype bean definitions that match the
      fully-qualified class names:</para>

3075
      <programlisting language="java">public aspect DomainObjectConfiguration extends AbstractBeanConfigurerAspect {
3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 3106

  public DomainObjectConfiguration() {
    setBeanWiringInfoResolver(new ClassNameBeanWiringInfoResolver());
  }

  <lineannotation>// the creation of a new bean (any object in the domain model)</lineannotation>
  protected pointcut beanCreation(Object beanInstance) :
    initialization(new(..)) &amp;&amp;
    SystemArchitecture.inDomainModel() &amp;&amp; 
    this(beanInstance);
		   		   
}</programlisting>
    </section>

    <section id="aop-aj-configure">
      <title>Configuring AspectJ aspects using Spring IoC</title>

      <para>When using AspectJ aspects with Spring applications, it is natural
      to both want and expect to be able to configure such aspects using
      Spring. The AspectJ runtime itself is responsible for aspect creation,
      and the means of configuring the AspectJ created aspects via Spring
      depends on the AspectJ instantiation model (the
      '<literal>per-xxx</literal>' clause) used by the aspect.</para>

      <para>The majority of AspectJ aspects are <emphasis>singleton</emphasis>
      aspects. Configuration of these aspects is very easy: simply create a
      bean definition referencing the aspect type as normal, and include the
      bean attribute <literal>'factory-method="aspectOf"'</literal>. This
      ensures that Spring obtains the aspect instance by asking AspectJ for it
      rather than trying to create an instance itself. For example:</para>

3107
      <programlisting language="xml">&lt;bean id="profiler" class="com.xyz.profiler.Profiler"
3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131
      <emphasis role="bold">factory-method="aspectOf"</emphasis>&gt;
  &lt;property name="profilingStrategy" ref="jamonProfilingStrategy"/&gt;
&lt;/bean&gt;</programlisting>

      <para>Non-singleton aspects are harder to configure: however it is
      possible to do so by creating prototype bean definitions and using the
      <interfacename>@Configurable</interfacename> support from <filename
      class="libraryfile">spring-aspects.jar</filename> to configure the
      aspect instances once they have bean created by the AspectJ
      runtime.</para>

      <para>If you have some @AspectJ aspects that you want to weave with
      AspectJ (for example, using load-time weaving for domain model types)
      and other @AspectJ aspects that you want to use with Spring AOP, and
      these aspects are all configured using Spring, then you will need to
      tell the Spring AOP @AspectJ autoproxying support which exact subset of
      the @AspectJ aspects defined in the configuration should be used for
      autoproxying. You can do this by using one or more
      <literal>&lt;include/&gt;</literal> elements inside the
      <literal>&lt;aop:aspectj-autoproxy/&gt;</literal> declaration. Each
      <literal>&lt;include/&gt;</literal> element specifies a name pattern,
      and only beans with names matched by at least one of the patterns will
      be used for Spring AOP autoproxy configuration:</para>

3132
      <programlisting language="xml">&lt;aop:aspectj-autoproxy&gt;
3133 3134 3135 3136 3137 3138 3139 3140 3141 3142 3143 3144 3145 3146 3147 3148 3149 3150 3151 3152 3153 3154 3155 3156 3157 3158 3159 3160 3161 3162 3163 3164 3165 3166 3167 3168 3169 3170 3171 3172 3173 3174
  &lt;aop:include name="thisBean"/&gt;
  &lt;aop:include name="thatBean"/&gt;
&lt;/aop:aspectj-autoproxy&gt;</programlisting>

      <note>
        <para>Do not be misled by the name of the
        <literal>&lt;aop:aspectj-autoproxy/&gt;</literal> element: using it
        will result in the creation of <emphasis>Spring AOP
        proxies</emphasis>. The @AspectJ style of aspect declaration is just
        being used here, but the AspectJ runtime is <emphasis>not</emphasis>
        involved.</para>
      </note>
    </section>

    <section id="aop-aj-ltw">
      <title>Load-time weaving with AspectJ in the Spring Framework</title>

      <para>Load-time weaving (LTW) refers to the process of weaving AspectJ
      aspects into an application's class files as they are being loaded into
      the Java virtual machine (JVM). The focus of this section is on
      configuring and using LTW in the specific context of the Spring
      Framework: this section is not an introduction to LTW though. For full
      details on the specifics of LTW and configuring LTW with just AspectJ
      (with Spring not being involved at all), see the <ulink
      url="http://www.eclipse.org/aspectj/doc/released/devguide/ltw.html">LTW
      section of the AspectJ Development Environment Guide</ulink>.</para>

      <para>The value-add that the Spring Framework brings to AspectJ LTW is
      in enabling much finer-grained control over the weaving process.
      'Vanilla' AspectJ LTW is effected using a Java (5+) agent, which is
      switched on by specifying a VM argument when starting up a JVM. It is
      thus a JVM-wide setting, which may be fine in some situations, but often
      is a little too coarse. Spring-enabled LTW enables you to switch on LTW
      on a <emphasis>per-<classname>ClassLoader</classname></emphasis> basis,
      which obviously is more fine-grained and which can make more sense in a
      'single-JVM-multiple-application' environment (such as is found in a
      typical application server environment).</para>

      <para>Further, <link linkend="aop-aj-ltw-environments">in certain
      environments</link>, this support enables load-time weaving
      <emphasis>without making any modifications to the application server's
      launch script</emphasis> that will be needed to add
C
Costin Leau 已提交
3175
      <literal>-javaagent:path/to/aspectjweaver.jar</literal> or (as we describe later in this
3176 3177
      section) <literal>-javaagent:path/to/org.springframework.instrument-{version}.jar</literal> 
      (previously named <literal>spring-agent.jar</literal>). Developers simply modify
3178 3179 3180 3181 3182 3183 3184
      one or more files that form the application context to enable load-time
      weaving instead of relying on administrators who typically are in charge
      of the deployment configuration such as the launch script.</para>

      <para>Now that the sales pitch is over, let us first walk through a
      quick example of AspectJ LTW using Spring, followed by detailed
      specifics about elements introduced in the following example. For a
3185
      complete example, please see the Petclinic <link linkend="new-in-3.0-samples">sample</link> application.</para>
3186 3187 3188 3189 3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201

      <section id="aop-aj-ltw-first-example">
        <title>A first example</title>

        <para>Let us assume that you are an application developer who has been
        tasked with diagnosing the cause of some performance problems in a
        system. Rather than break out a profiling tool, what we are going to
        do is switch on a simple profiling aspect that will enable us to very
        quickly get some performance metrics, so that we can then apply a
        finer-grained profiling tool to that specific area immediately
        afterwards.</para>

        <para>Here is the profiling aspect. Nothing too fancy, just a
        quick-and-dirty time-based profiler, using the @AspectJ-style of
        aspect declaration.</para>

3202
        <programlisting language="java">package foo;
3203 3204 3205 3206 3207 3208 3209 3210 3211 3212 3213 3214 3215 3216 3217 3218 3219 3220 3221 3222 3223 3224 3225 3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.util.StopWatch;
import org.springframework.core.annotation.Order;

@Aspect
public class ProfilingAspect {

    @Around("methodsToBeProfiled()")
    public Object profile(ProceedingJoinPoint pjp) throws Throwable {
        StopWatch sw = new StopWatch(getClass().getSimpleName());
        try {
            sw.start(pjp.getSignature().getName());
            return pjp.proceed();
        } finally {
            sw.stop();
            System.out.println(sw.prettyPrint());
        }
    }

    @Pointcut("execution(public * foo..*.*(..))")
    public void methodsToBeProfiled(){}
}
</programlisting>

        <para>We will also need to create an
        '<filename>META-INF/aop.xml</filename>' file, to inform the AspectJ
        weaver that we want to weave our
        <classname>ProfilingAspect</classname> into our classes. This file
        convention, namely the presence of a file (or files) on the Java
        classpath called ' <filename>META-INF/aop.xml</filename>' is standard
        AspectJ.</para>

3239
        <programlisting language="xml">&lt;!DOCTYPE aspectj PUBLIC
3240 3241 3242 3243 3244 3245 3246 3247 3248 3249 3250 3251 3252 3253 3254 3255 3256 3257 3258 3259 3260 3261 3262 3263 3264 3265 3266 3267 3268
        "-//AspectJ//DTD//EN" "http://www.eclipse.org/aspectj/dtd/aspectj.dtd"&gt;
&lt;aspectj&gt;

    &lt;weaver&gt;

        <lineannotation>&lt;!-- only weave classes in our application-specific packages --&gt;</lineannotation>
        &lt;include within="foo.*"/&gt;

    &lt;/weaver&gt;

    &lt;aspects&gt;

        <lineannotation>&lt;!-- weave in just this aspect --&gt;</lineannotation>        
        &lt;aspect name="foo.ProfilingAspect"/&gt;

    &lt;/aspects&gt;

  &lt;/aspectj&gt;</programlisting>

        <para>Now to the Spring-specific portion of the configuration. We need
        to configure a <interfacename>LoadTimeWeaver</interfacename> (all
        explained later, just take it on trust for now). This load-time weaver
        is the essential component responsible for weaving the aspect
        configuration in one or more '<filename>META-INF/aop.xml</filename>'
        files into the classes in your application. The good thing is that it
        does not require a lot of configuration, as can be seen below (there
        are some more options that you can specify, but these are detailed
        later).</para>

3269
        <programlisting language="xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
3270 3271 3272 3273
&lt;beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="
C
Costin Leau 已提交
3274 3275 3276 3277
http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context 
    http://www.springframework.org/schema/context/spring-context-3.0.xsd"&gt;
3278 3279 3280 3281 3282 3283 3284 3285 3286 3287 3288 3289 3290 3291 3292 3293

    <lineannotation>&lt;!-- a service object; we will be profiling its methods --&gt;</lineannotation>
    &lt;bean id="entitlementCalculationService"
          class="foo.StubEntitlementCalculationService"/&gt;

    <lineannotation>&lt;!-- this switches on the load-time weaving --&gt;</lineannotation>
    <emphasis role="bold">&lt;context:load-time-weaver/&gt;</emphasis>

&lt;/beans&gt;</programlisting>

        <para>Now that all the required artifacts are in place - the aspect,
        the '<filename>META-INF/aop.xml</filename>' file, and the Spring
        configuration -, let us create a simple driver class with a
        <methodname>main(..)</methodname> method to demonstrate the LTW in
        action.</para>

3294
        <programlisting language="java">package foo;
3295 3296 3297 3298 3299 3300 3301 3302 3303 3304 3305 3306 3307 3308 3309 3310 3311 3312 3313 3314 3315 3316 3317 3318

import org.springframework.context.support.ClassPathXmlApplicationContext;

public final class Main {

    public static void main(String[] args) {

        ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml", Main.class);

        EntitlementCalculationService entitlementCalculationService
            = (EntitlementCalculationService) ctx.getBean("entitlementCalculationService");

        <lineannotation>// the profiling aspect is 'woven' around this method execution</lineannotation>
        entitlementCalculationService.calculateEntitlement();
    }
}</programlisting>

        <para>There is one last thing to do. The introduction to this section
        did say that one could switch on LTW selectively on a
        per-<classname>ClassLoader</classname> basis with Spring, and this is
        true. However, just for this example, we are going to use a Java agent
        (supplied with Spring) to switch on the LTW. This is the command line
        we will use to run the above <classname>Main</classname> class:</para>

3319
        <programlisting>java -javaagent:C:/projects/foo/lib/global/spring-instrument.jar foo.Main</programlisting>
3320 3321 3322 3323 3324 3325 3326

        <para>The '<literal>-javaagent</literal>' is a Java 5+ flag for
        specifying and enabling <ulink
        url="http://java.sun.com/j2se/1.5.0/docs/api/java/lang/instrument/package-summary.html">agents
        to instrument programs running on the JVM</ulink>. The Spring
        Framework ships with such an agent, the
        <classname>InstrumentationSavingAgent</classname>, which is packaged
3327 3328
        in the <filename class="libraryfile">spring-instrument.jar</filename>
		that
3329 3330 3331 3332 3333 3334 3335 3336 3337 3338 3339 3340 3341 3342 3343 3344 3345 3346 3347 3348 3349 3350 3351 3352
        was supplied as the value of the <literal>-javaagent</literal>
        argument in the above example.</para>

        <para>The output from the execution of the <classname>Main</classname>
        program will look something like that below. (I have introduced a
        <methodname>Thread.sleep(..)</methodname> statement into the
        <methodname>calculateEntitlement()</methodname> implementation so that
        the profiler actually captures something other than 0 milliseconds -
        the <literal>01234</literal> milliseconds is <emphasis>not</emphasis>
        an overhead introduced by the AOP :) )</para>

        <programlisting>Calculating entitlement

StopWatch 'ProfilingAspect': running time (millis) = 1234
------ ----- ----------------------------
ms     %     Task name
------ ----- ----------------------------
01234  100%  calculateEntitlement</programlisting>

        <para>Since this LTW is effected using full-blown AspectJ, we are not
        just limited to advising Spring beans; the following slight variation
        on the <classname>Main</classname> program will yield the same
        result.</para>

3353
        <programlisting language="java">package foo;
3354 3355 3356 3357 3358 3359 3360 3361 3362 3363 3364 3365 3366 3367 3368 3369 3370 3371 3372 3373 3374 3375 3376 3377 3378 3379 3380 3381 3382 3383 3384 3385 3386 3387 3388 3389 3390 3391 3392 3393 3394 3395 3396 3397 3398 3399 3400 3401 3402 3403 3404 3405 3406 3407 3408 3409 3410 3411 3412 3413 3414 3415 3416 3417 3418 3419 3420 3421 3422 3423 3424 3425 3426 3427 3428

import org.springframework.context.support.ClassPathXmlApplicationContext;

public final class Main {

    public static void main(String[] args) {

        new ClassPathXmlApplicationContext("beans.xml", Main.class);

        EntitlementCalculationService entitlementCalculationService =
            new StubEntitlementCalculationService();

        <lineannotation>// the profiling aspect will be 'woven' around this method execution</lineannotation>
        entitlementCalculationService.calculateEntitlement();
    }
}</programlisting>

        <para>Notice how in the above program we are simply bootstrapping the
        Spring container, and then creating a new instance of the
        <classname>StubEntitlementCalculationService</classname> totally
        outside the context of Spring... the profiling advice still gets woven
        in.</para>

        <para>The example admittedly is simplistic... however the basics of
        the LTW support in Spring have all been introduced in the above
        example, and the rest of this section will explain the 'why' behind
        each bit of configuration and usage in detail.</para>

        <note>
          <para>The <classname>ProfilingAspect</classname> used in this
          example may be basic, but it is quite useful. It is a nice example
          of a development-time aspect that developers can use during
          development (of course), and then quite easily exclude from builds
          of the application being deployed into UAT or production.</para>
        </note>
      </section>

      <section id="aop-aj-ltw-the-aspects">
        <title>Aspects</title>

        <para>The aspects that you use in LTW have to be AspectJ aspects. They
        can be written in either the AspectJ language itself or you can write
        your aspects in the @AspectJ-style. The latter option is of course
        only an option if you are using Java 5+, but it does mean that your
        aspects are then both valid AspectJ <emphasis>and</emphasis> Spring
        AOP aspects. Furthermore, the compiled aspect classes need to be
        available on the classpath.</para>
      </section>

      <section id="aop-aj-ltw-aop_dot_xml">
        <title>'<filename>META-INF/aop.xml</filename>'</title>

        <para>The AspectJ LTW infrastructure is configured using one or more
        '<filename>META-INF/aop.xml</filename>' files, that are on the Java
        classpath (either directly, or more typically in jar files).</para>

        <para>The structure and contents of this file is detailed in the main
        AspectJ reference documentation, and the interested reader is <ulink
        url="http://www.eclipse.org/aspectj/doc/released/devguide/ltw-configuration.html">referred
        to that resource</ulink>. (I appreciate that this section is brief,
        but the '<filename>aop.xml</filename>' file is 100% AspectJ - there is
        no Spring-specific information or semantics that apply to it, and so
        there is no extra value that I can contribute either as a result), so
        rather than rehash the quite satisfactory section that the AspectJ
        developers wrote, I am just directing you there.)</para>
      </section>

      <section id="aop-aj-ltw-libraries">
        <title>Required libraries (JARS)</title>

        <para>At a minimum you will need the following libraries to use the
        Spring Framework's support for AspectJ LTW:</para>

        <orderedlist>
          <listitem>
3429 3430
            <para><filename class="libraryfile">spring-aop.jar</filename> (version
            2.5 or later, plus all mandatory dependencies)</para>
3431 3432 3433 3434
          </listitem>

          <listitem>
            <para><filename class="libraryfile">aspectjweaver.jar</filename>
3435
            (version 1.6.8 or later)</para>
3436 3437 3438 3439 3440 3441 3442 3443 3444 3445
          </listitem>
        </orderedlist>

        <para>If you are using the <link
        linkend="aop-aj-ltw-environment-generic">Spring-provided agent to
        enable instrumentation</link>, you will also need:</para>

        <orderedlist>
          <listitem>
            <para><filename
3446
            class="libraryfile">spring-instrument.jar</filename></para>
3447 3448 3449 3450 3451 3452 3453 3454 3455 3456 3457 3458 3459 3460 3461 3462 3463 3464 3465 3466 3467 3468 3469 3470 3471 3472 3473 3474 3475 3476 3477 3478 3479 3480 3481 3482 3483 3484 3485 3486 3487 3488 3489 3490 3491
          </listitem>
        </orderedlist>
      </section>

      <section id="aop-aj-ltw-spring">
        <title>Spring configuration</title>

        <para>The key component in Spring's LTW support is the
        <interfacename>LoadTimeWeaver</interfacename> interface (in the
        <literal>org.springframework.instrument.classloading</literal>
        package), and the numerous implementations of it that ship with the
        Spring distribution. A <interfacename>LoadTimeWeaver</interfacename>
        is responsible for adding one or more
        <classname>java.lang.instrument.ClassFileTransformers</classname> to a
        <classname>ClassLoader</classname> at runtime, which opens the door to
        all manner of interesting applications, one of which happens to be the
        LTW of aspects.</para>

        <tip>
          <para>If you are unfamiliar with the idea of runtime class file
          transformation, you are encouraged to read the Javadoc API
          documentation for the <literal>java.lang.instrument</literal>
          package before continuing. This is not a huge chore because there is
          - rather annoyingly - precious little documentation there... the key
          interfaces and classes will at least be laid out in front of you for
          reference as you read through this section.</para>
        </tip>

        <para>Configuring a <interfacename>LoadTimeWeaver</interfacename>
        using XML for a particular
        <interfacename>ApplicationContext</interfacename> can be as easy as
        adding one line. (Please note that you almost certainly will need to
        be using an <interfacename>ApplicationContext</interfacename> as your
        Spring container - typically a
        <interfacename>BeanFactory</interfacename> will not be enough because
        the LTW support makes use of
        <interfacename>BeanFactoryPostProcessors</interfacename>.)</para>

        <para>To enable the Spring Framework's LTW support, you need to
        configure a <interfacename>LoadTimeWeaver</interfacename>, which
        typically is done using the
        <literal>&lt;context:load-time-weaver/&gt;</literal> element. Find
        below a valid <literal>&lt;context:load-time-weaver/&gt;</literal>
        definition that uses default settings.</para>

3492
        <programlisting language="xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
3493 3494 3495 3496
&lt;beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="
C
Costin Leau 已提交
3497 3498 3499 3500
http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-3.0.xsd"&gt;
3501 3502 3503 3504 3505 3506 3507 3508 3509 3510 3511 3512 3513 3514 3515 3516 3517 3518 3519 3520 3521 3522 3523 3524 3525 3526 3527 3528 3529 3530 3531 3532 3533 3534 3535 3536 3537 3538 3539 3540 3541 3542 3543 3544 3545 3546 3547

    &lt;context:load-time-weaver/&gt;

&lt;/beans&gt;</programlisting>

        <para>The above <literal>&lt;context:load-time-weaver/&gt;</literal>
        bean definition will define and register a number of LTW-specific
        infrastructure beans for you automatically, such as a
        <interfacename>LoadTimeWeaver</interfacename> and an
        <classname>AspectJWeavingEnabler</classname>. Notice how the
        <literal>&lt;context:load-time-weaver/&gt;</literal> is defined in the
        '<literal>context</literal>' namespace; note also that the referenced
        XML Schema file is only available in versions of Spring 2.5 and
        later.</para>

        <para>What the above configuration does is define and register a
        default <interfacename>LoadTimeWeaver</interfacename> bean for you.
        The default <interfacename>LoadTimeWeaver</interfacename> is the
        <classname>DefaultContextLoadTimeWeaver</classname> class, which
        attempts to decorate an automatically detected
        <interfacename>LoadTimeWeaver</interfacename>: the exact type of
        <interfacename>LoadTimeWeaver</interfacename> that will be
        'automatically detected' is dependent upon your runtime environment
        (summarised in the following table).</para>

        <table id="aop-aj-ltw-spring-env-impls" pgwide="1">
          <title><classname>DefaultContextLoadTimeWeaver</classname>
          <interfacename>LoadTimeWeavers</interfacename></title>

          <tgroup cols="2">
            <colspec align="left" />

            <thead>
              <row>
                <entry>Runtime Environment</entry>
                <entry><interfacename>LoadTimeWeaver</interfacename> implementation</entry>
              </row>
            </thead>

            <tbody>
              <row>
                <entry><para>Running in <ulink
                url="http://www.bea.com/framework.jsp?CNT=index.htm&amp;FP=/content/products/weblogic/server">BEA's
                Weblogic 10</ulink></para></entry>
                <entry><para><classname>WebLogicLoadTimeWeaver</classname></para></entry>
              </row>

C
Costin Leau 已提交
3548 3549 3550 3551 3552 3553
              <row>
                <entry><para>Running in <ulink
                url="http://www-01.ibm.com/software/webservers/appserv/was/">IBM WebSphere Application Server 7</ulink></para></entry>
                <entry><para><classname>WebSphereLoadTimeWeaver</classname></para></entry>
              </row>

3554 3555 3556 3557 3558 3559 3560 3561 3562 3563 3564 3565
              <row>
                <entry><para>Running in <ulink
                url="http://www.oracle.com/technology/products/oc4j/index.html">Oracle's
                OC4J</ulink></para></entry>
                <entry><para><classname>OC4JLoadTimeWeaver</classname></para></entry>
              </row>

              <row>
                <entry><para>Running in <ulink url="http://glassfish.dev.java.net/">GlassFish</ulink></para></entry>
                <entry><para><classname>GlassFishLoadTimeWeaver</classname></para></entry>
              </row>

C
Costin Leau 已提交
3566 3567 3568 3569 3570
              <row>
                <entry><para>Running in <ulink url="http://www.jboss.org/jbossas/">JBoss AS</ulink></para></entry>
                <entry><para><classname>JBossLoadTimeWeaver</classname></para></entry>
              </row>

3571 3572 3573 3574
              <row>
                <entry><para>JVM started with Spring
                <classname>InstrumentationSavingAgent</classname></para>
                <para><emphasis><literal>(java
3575
                -javaagent:path/to/spring-instrument.jar)</literal></emphasis></para></entry>
3576 3577 3578 3579 3580
                <entry><para><classname>InstrumentationLoadTimeWeaver</classname></para></entry>
              </row>

              <row>
                <entry><para>Fallback, expecting the underlying ClassLoader to follow common conventions
C
Costin Leau 已提交
3581 3582
                (e.g. applicable to <classname>TomcatInstrumentableClassLoader</classname> and 
                <ulink url="http://www.caucho.com/">Resin</ulink>)</para></entry>
3583 3584 3585 3586 3587 3588 3589 3590 3591 3592 3593 3594 3595 3596 3597 3598
                <entry><para><classname>ReflectiveLoadTimeWeaver</classname></para></entry>
              </row>
            </tbody>
          </tgroup>
        </table>

        <para>Note that these are just the
        <interfacename>LoadTimeWeavers</interfacename> that are autodetected
        when using the <classname>DefaultContextLoadTimeWeaver</classname>: it
        is of course possible to specify exactly which
        <interfacename>LoadTimeWeaver</interfacename> implementation that you
        wish to use by specifying the fully-qualified classname as the value
        of the '<literal>weaver-class</literal>' attribute of the
        <literal>&lt;context:load-time-weaver/&gt;</literal> element. Find
        below an example of doing just that:</para>

3599
        <programlisting language="xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
3600 3601 3602 3603
&lt;beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="
C
Costin Leau 已提交
3604 3605 3606 3607
http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-3.0.xsd"&gt;
3608 3609 3610 3611 3612 3613 3614 3615 3616 3617 3618 3619 3620 3621 3622 3623 3624 3625 3626 3627 3628 3629 3630 3631 3632 3633 3634 3635 3636 3637 3638 3639 3640 3641 3642 3643 3644 3645 3646 3647 3648 3649 3650 3651 3652 3653 3654 3655 3656 3657 3658 3659 3660 3661 3662 3663 3664 3665 3666 3667 3668 3669 3670 3671 3672 3673 3674 3675 3676 3677 3678 3679 3680 3681 3682 3683 3684 3685

    &lt;context:load-time-weaver
            <emphasis role="bold">weaver-class="org.springframework.instrument.classloading.ReflectiveLoadTimeWeaver"</emphasis>/&gt;

&lt;/beans&gt;</programlisting>

        <para>The <interfacename>LoadTimeWeaver</interfacename> that is
        defined and registered by the
        <literal>&lt;context:load-time-weaver/&gt;</literal> element can be
        later retrieved from the Spring container using the well-known name
        '<literal>loadTimeWeaver</literal>'. Remember that the
        <interfacename>LoadTimeWeaver</interfacename> exists just as a
        mechanism for Spring's LTW infrastructure to add one or more
        <interfacename>ClassFileTransformers</interfacename>. The actual
        <classname>ClassFileTransformer</classname> that does the LTW is the
        <classname>ClassPreProcessorAgentAdapter</classname> (from the
        <literal>org.aspectj.weaver.loadtime</literal> package) class. See the
        class-level Javadoc for the
        <classname>ClassPreProcessorAgentAdapter</classname> class for further
        details, because the specifics of how the weaving is actually effected
        is beyond the scope of this section.</para>

        <para>There is one final attribute of the
        <literal>&lt;context:load-time-weaver/&gt;</literal> left to discuss:
        the '<literal>aspectj-weaving</literal>' attribute. This is a simple
        attribute that controls whether LTW is enabled or not, it is as simple
        as that. It accepts one of three possible values, summarised below,
        with the default value if the attribute is not present being '
        <literal>autodetect</literal>'</para>

        <table id="aop-aj-ltw-ltw-tag-attrs" pgwide="1">
          <title>'<literal>aspectj-weaving</literal>' attribute values</title>

          <tgroup cols="2">
            <colspec align="left" />

            <thead>
              <row>
                <entry>Attribute Value</entry>
                <entry>Explanation</entry>
              </row>
            </thead>

            <tbody>
              <row>
                <entry><para><literal>on</literal></para></entry>
                <entry><para>AspectJ weaving is on, and aspects will be woven
                at load-time as appropriate.</para></entry>
              </row>

              <row>
                <entry><para><literal>off</literal></para></entry>
                <entry><para>LTW is off... no aspect will be woven at
                load-time.</para></entry>
              </row>

              <row>
                <entry><para><literal>autodetect</literal></para></entry>
                <entry><para>If the Spring LTW infrastructure can find at
                least one '<filename>META-INF/aop.xml</filename>' file, then
                AspectJ weaving is on, else it is off. This is the default
                value.</para></entry>
              </row>
            </tbody>
          </tgroup>
        </table>
      </section>

      <section id="aop-aj-ltw-environments">
        <title>Environment-specific configuration</title>

        <para>This last section contains any additional settings and
        configuration that you will need when using Spring's LTW support in
        environments such as application servers and web containers.</para>

        <section id="aop-aj-ltw-environment-tomcat">
          <title>Tomcat</title>

C
Costin Leau 已提交
3686
		  <para><ulink url="http://tomcat.apache.org/">Apache Tomcat</ulink>'s default class loader 
C
Costin Leau 已提交
3687 3688 3689 3690 3691 3692 3693 3694 3695 3696 3697 3698 3699 3700 3701 3702 3703 3704 3705 3706 3707 3708 3709 3710 3711 3712 3713
		  does not support class transformation which is why Spring provides an enhanced implementation that
		  addresses this need. Named <classname>TomcatInstrumentableClassLoader</classname>, the loader works
		  on Tomcat 5.0 and above and can be registered individually for <emphasis>each</emphasis> web application
		  as follows:</para>
		  
          <itemizedlist>
            <listitem>
              <para>Tomcat 6.0.x or higher</para>

            <orderedlist>
              <listitem>
                <para>Copy <literal>org.springframework.instrument.tomcat.jar</literal>
                into <emphasis>$CATALINA_HOME</emphasis>/lib, where
                <emphasis>$CATALINA_HOME</emphasis> represents the root of the
                Tomcat installation)</para>
              </listitem>

              <listitem>
                <para>Instruct Tomcat to use the custom class loader (instead
                of the default) by editing the web application context
                file:</para>

                <programlisting language="xml">&lt;Context path="/myWebApp" docBase="/my/webApp/location"&gt;
    &lt;Loader
        loaderClass="org.springframework.instrument.classloading.tomcat.TomcatInstrumentableClassLoader"/&gt;
&lt;/Context&gt;</programlisting>

C
Costin Leau 已提交
3714 3715 3716 3717 3718 3719 3720 3721 3722 3723
                <para>Apache Tomcat 6.0.x (similar to 5.0.x/5.5.x) series supports several context locations:</para>
					<itemizedlist>
						<listitem>server configuration file - <emphasis>$CATALINA_HOME/conf/server.xml</emphasis> </listitem>
						<listitem>default context configuration - <emphasis>$CATALINA_HOME/conf/context.xml</emphasis> - that
						affects all deployed web applications</listitem>
						<listitem>per-web application configuration which can be deployed either on the server-side at
						<emphasis>$CATALINA_HOME/conf/[enginename]/[hostname]/[webapp]-context.xml</emphasis> or embedded inside
						the web-app archive at <emphasis>META-INF/context.xml</emphasis></listitem>
					</itemizedlist>
                <para>For efficiency, the embedded per-web-app configuration style <!--Which one is inside the web-app config style? Reword. TR: REVISED, PLS REVIEW. Same change as for 5.0/5.5-->is
C
Costin Leau 已提交
3724
                recommended because it will impact only applications that use
C
Costin Leau 已提交
3725 3726
                the custom class loader and does not require any changes to the server configuration.
                See the Tomcat 6.0.x <ulink url="http://tomcat.apache.org/tomcat-6.0-doc/config/context.html">documentation</ulink>
C
Costin Leau 已提交
3727 3728 3729
                for more details about available context locations.</para>
              </listitem>
            </orderedlist>
3730 3731 3732
	        </listitem>
              
          <listitem>
C
Costin Leau 已提交
3733 3734 3735 3736 3737 3738 3739 3740 3741 3742 3743 3744 3745 3746 3747 3748 3749 3750 3751 3752
              <para>Tomcat 5.0.x/5.5.x</para>

            <orderedlist>
              <listitem>
                <para>Copy <literal>org.springframework.instrument.tomcat.jar</literal>
                into <emphasis>$CATALINA_HOME</emphasis>/server/lib, where
                <emphasis>$CATALINA_HOME</emphasis> represents the root of the
                Tomcat installation.</para>
              </listitem>

              <listitem>
                <para>Instruct Tomcat to use the custom class loader instead
                of the default one by editing the web application context
                file:</para>

                <programlisting language="xml">&lt;Context path="/myWebApp" docBase="/my/webApp/location"&gt;
    &lt;Loader
        loaderClass="org.springframework.instrument.classloading.tomcat.TomcatInstrumentableClassLoader"/&gt;
&lt;/Context&gt;</programlisting>

C
Costin Leau 已提交
3753 3754 3755 3756 3757 3758 3759 3760 3761 3762
                <para>Tomcat 5.0.x and 5.5.x series supports several context locations:</para>
                	<itemizedlist>
						<listitem>server configuration file - <emphasis>$CATALINA_HOME/conf/server.xml</emphasis> </listitem>
						<listitem>default context configuration - <emphasis>$CATALINA_HOME/conf/context.xml</emphasis> - that
						affects all deployed web applications</listitem>
						<listitem>per-web application configuration which can be deployed either on the server-side at
						<emphasis>$CATALINA_HOME/conf/[enginename]/[hostname]/[webapp]-context.xml</emphasis> or embedded inside
						the web-app archive at <emphasis>META-INF/context.xml</emphasis></listitem>
					</itemizedlist>
                <para>For efficiency, the embedded web-app configuration style<!--Which of the preceding is *inside the web-app config style*? Two paths contain webapp. 
C
Costin Leau 已提交
3763 3764 3765 3766 3767 3768 3769 3770
TR: REVISED, PLS REVIEW. Chnaged the last one to *inside*--> is recommended
                recommended because it will impact only applications that use the class loader. See the Tomcat 5.x <ulink
                url="http://tomcat.apache.org/tomcat-5.5-doc/config/context.html">documentation</ulink>
                for more details about available context locations.</para>

                <para>Tomcat versions prior to 5.5.20 contained a bug in the
                XML configuration parsing that prevented usage of the
                <literal>Loader</literal> tag inside
C
Costin Leau 已提交
3771
                <emphasis>server.xml</emphasis> configuration, regardless of whether a class
C
Costin Leau 已提交
3772 3773 3774
                loader is specified or whether it is the official or a custom
                one. See Tomcat's bugzilla for <ulink
                url="http://issues.apache.org/bugzilla/show_bug.cgi?id=39704">more
C
Costin Leau 已提交
3775
                details</ulink>.</para><!--Will reader know what Tomcat's bugzilla is and where to find it? TR: OK AS IS. They just need to click on the hyerlink.-->
C
Costin Leau 已提交
3776

C
Costin Leau 已提交
3777
                <para>In Tomcat 5.5.x, versions 5.5.20 or later, you should set
C
Costin Leau 已提交
3778
                <emphasis>useSystemClassLoaderAsParent</emphasis> to
C
Costin Leau 已提交
3779 3780 3781
                <literal>false</literal> to fix this problem:
                </para>
                <programlisting
C
Costin Leau 已提交
3782
                language="xml">&lt;Context path="/myWebApp" docBase="/my/webApp/location"&gt;
C
Costin Leau 已提交
3783 3784
    &lt;Loader
        loaderClass="org.springframework.instrument.classloading.tomcat.TomcatInstrumentableClassLoader"
C
Costin Leau 已提交
3785
            <emphasis role="bold">useSystemClassLoaderAsParent="false"</emphasis>/&gt;
3786
&lt;/Context&gt;</programlisting><para>This setting is not needed on Tomcat 6 or higher.</para>
C
Costin Leau 已提交
3787 3788
              </listitem>
            </orderedlist>
3789 3790 3791
            
            </listitem>
            
C
Costin Leau 已提交
3792
          </itemizedlist>
3793 3794 3795 3796

          <para>Alternatively, consider the use of the Spring-provided generic
          VM agent, to be specified in Tomcat's launch script (see above).
          This will make instrumentation available to all deployed web
C
Costin Leau 已提交
3797
          applications, no matter what ClassLoader they happen to run on.</para>
3798 3799
        </section>

C
Costin Leau 已提交
3800
        <section id="aop-aj-ltw-environments-weblogic-oc4j-resin-glassfish-jboss">
C
Costin Leau 已提交
3801
          <title>WebLogic, WebSphere, OC4J, Resin, GlassFish, JBoss</title>
3802

C
Costin Leau 已提交
3803 3804
          <para>Recent versions of BEA WebLogic (version 10 and above), IBM WebSphere Application Server (version 7 and above),
          Oracle Containers for Java EE (OC4J 10.1.3.1 and above), Resin (3.1 and above) and JBoss (5.x or above)
3805 3806 3807 3808 3809
          provide a ClassLoader that is capable of local instrumentation.
          Spring's native LTW leverages such ClassLoaders to enable AspectJ weaving.
          You can enable LTW by simply activating <literal>context:load-time-weaver</literal>
          as described earlier. Specifically, you do <emphasis>not</emphasis>
          need to modify the launch script to add
3810
          <literal>-javaagent:path/to/spring-instrument.jar</literal>.</para>
3811

C
Costin Leau 已提交
3812 3813
          <para>Note that GlassFish instrumentation-capable ClassLoader is available only in its EAR environment. 
          For GlassFish web applications, follow the Tomcat setup instructions as outlined above.</para>
C
Costin Leau 已提交
3814 3815 3816 3817 3818 3819 3820
          
          <para>Note that on JBoss 6.x, the app server scanning needs to be disabled to prevent it from loading the classes
          before the application actually starts. A quick workaround is to add to your artifact a file named
          <filename class="libraryfile">WEB-INF/jboss-scanning.xml</filename> with the following content:</para>
          
          <programlisting language="xml">&lt;scanning xmlns="urn:jboss:scanning:1.0"/&gt;</programlisting>
          </section>
C
Costin Leau 已提交
3821 3822 3823 3824 3825 3826 3827 3828 3829 3830 3831 3832 3833 3834 3835 3836 3837 3838 3839 3840 3841 3842 3843 3844 3845
        
        <section id="aop-aj-ltw-environment-generic">
          <title>Generic Java applications</title>

          <para>When class instrumentation is required in environments that do not support or
          are not supported by the existing <classname>LoadTimeWeaver</classname>
          implementations<!--OK? If you mean environments that are not supported by existing impl, revise as shown. If you mean class instrumentation is not supp--><!--orted, say *For environments that require class instrumentation that is not supported...*-->,
          a JDK agent can be the only solution. For such cases, Spring
          provides <classname>InstrumentationLoadTimeWeaver</classname>,
          which requires a Spring-specific (but very general) VM agent,
          <filename class="libraryfile">org.springframework.instrument-{version}.jar</filename>
          (previously named <filename class="libraryfile">spring-agent.jar</filename>).</para>
          
          <para>To use it, you must start the virtual machine with the Spring agent, by
          supplying the following JVM options:</para>
          <programlisting>-javaagent:/path/to/org.springframework.instrument-{version}.jar</programlisting>
          
		  <para>         
          Note that this requires modification of the VM launch script which may prevent you from using this in application server
          environments (depending on your operation policies). Additionally, the JDK agent will instrument the <emphasis>entire</emphasis>
          VM which can prove expensive.</para>
          <para>For performance reasons, it is recommended to use this configuration only if your target environment 
          (such as <ulink url="http://www.eclipse.org/jetty/">Jetty</ulink>) does not have (or does not support) a dedicated LTW.</para>
        </section>
        
3846 3847 3848 3849 3850 3851 3852 3853 3854 3855 3856 3857 3858 3859 3860 3861 3862 3863 3864 3865
      </section>
    </section>
  </section>

  <section id="aop-resources">
    <title>Further Resources</title>

    <para>More information on AspectJ can be found on the <ulink
    url="http://www.eclipse.org/aspectj">AspectJ website</ulink>.</para>

    <para>The book <emphasis>Eclipse AspectJ</emphasis> by Adrian Colyer et.
    al. (Addison-Wesley, 2005) provides a comprehensive introduction and
    reference for the AspectJ language.</para>

    <para>The book <emphasis>AspectJ in Action</emphasis> by Ramnivas Laddad
    (Manning, 2003) comes highly recommended; the focus of the book is on
    AspectJ, but a lot of general AOP themes are explored (in some depth).</para>
  </section>

</chapter>