1. 程式人生 > >Spring文件閱讀之AOP

Spring文件閱讀之AOP

Aspect-oriented Programming (AOP) 補充了Object-oriented Programming (OOP)。OOP最重要的概念模組是類(class),而AOP中則是切面。AOP可以在多種型別和多個類間進行操作,可以認為AOP串起了這些資料。OOP使用封裝,繼承和多型來定義物件層級的結構,OOP允許使用者定義縱向層級的關係,但是對於橫向層級的關係,比如日誌功能,日誌總是橫向分佈在程式碼中,和物件的核心功能沒有關係。其他如安全性和異常處理也是一樣,這種橫向分佈的和核心物件功能無關的程式碼稱為橫切(aspect)。

在OOP中,實現橫切功能往往需要大量重複的程式碼。而AOP中可以使用橫切來剖開物件內部,將影響多個類的公共行為抽象到尾一個可重用模組,稱為aspect。

1.AOP Concepts

AOP中的概念和定義

Aspect: 一個可以穿插多個類的模組概念。事物管理就是一個典型的AOP例子。Spring使用常規類或者@Aspect註解的類來實現Aspect。

Join point: 程式執行過程中的一個點,比如方法的執行或者異常的處理。Spring AOP中,切入點指的是方法的執行。

Advice: Aspect在切入點執行的操作。Advice包括“around”, “before”和“after” 三種類型。

Introduction: 在不影響類程式碼的前提下,在執行期動態的為類新增方法或者欄位。

Target object: 被一個或者多個切面通知的物件,也可以稱為通知物件。Spring AOP是執行時代理來實現的,所以這個物件用於是被代理的。

AOP proxy:AOP建立的用於實現切面(通知方法執行之類的)的物件。AOP是JDK動態代理或者CGLIB代理。

Weaving: 將切面和應用的其他型別或者物件連線來建立通知物件。這一步驟可以在編譯,程式碼載入,或者執行時完成(AOP在執行時完成)。

Point cut:對連線點(Join point)進行攔截的定義。

Spring AOP advice的型別:

Before advice: 在切入點之前執行的advice,不能阻止aop繼續進行織入操作。

After returning advice: 在切入點正常完成之後執行的advice(比如一個沒有丟擲異常的方法)。

After throwing advice: 在方法丟擲異常之後執行的advice。

After (finally) advice: 方法完成後執行的advice(不管方法正常執行或者丟擲異常)。

Around advice: 圍繞切入點執行的advice比如方法的呼叫。最強力的advice就是around advice。around advice可以在方法呼叫前和呼叫後執行常用操作。around advice還負責選擇繼續執行切入點或者通過放回自己的返回值或丟擲異常來停止切入點的執行。

Spring官方建議使用能滿足要求的advice就可以了,不需要總是使用功能強大的advice型別。比如需要在方法返回的時候更新快取,使用after advice要比使用around advice更妥當,使用功能更適合的advice可以防止潛在的錯誤並且可以精簡程式碼。

程式設計師使用AOP一般分為三個步驟:
①.實現基本業務程式碼
②.定義切入點,切入點可以橫切
③.定義增強處理,即AOP為不同業務織入得處理動作

2.AOP Proxies

Spring AOP預設使用標準JDK動態代理實現AOP代理器,這保證任何介面都可以被代理。如果被代理的不是介面類,則會切換到CGLIB代理。

[email protected] support

3.1.Enabling @AspectJ Support

可以使用XML配置或者Java程式碼的方式配置@AspectJ支援。

Java註解的方式使用@AspectJ

使用@EnableAspectJAutoProxy註解開啟@AspectJ支援,如以下示例:

@Configuration
@EnableAspectJAutoProxy
public class AppConfig {

}

在Spring框架的配置檔案中配置aop:aspectj-autoproxy元素也可以開啟@AspectJ代理支援:

3.2.Declaring an Aspect

開啟@AspectJ註解支援後,任何使用@Aspect註解的類都會被Spring自動檢測並且被用於配置AOP。

以下是兩個簡單的aspect例子:

package org.xyz;
import org.aspectj.lang.annotation.Aspect;

@Aspect
public class NotVeryUsefulAspect {

}

@Aspect註釋的類不能被自動檢測,需要新增額外的@Component註解才能被IOC掃描到。
Aspect類不能被其他Aspect類切入,AOP會將其從自動代理中排除,因為他被標記為一個aspect。

3.Declaring a Pointcut

Pointcut決定aspect需要在哪裡執行通知(advice)的操作,Spring中可以使用註解或者xml配置檔案的方式。

使用註解定義Pointcut:

@Pointcut("execution(* transfer(..))")// the pointcut expression
private void anyOldTransfer() {}// the pointcut signature

3.1.Supported Pointcut Designators

Spring AOP支援在@Aspect註解中使用如下標記:

匹配方法的指示器(designator)
execution:定義切入點匹配的方法,AOP將advice進行織入,完成對於被代理物件的增強操作。

匹配註解的指示器

@targer()

@args()

@within()

@annotation()

匹配包和型別

within()

//匹配ProduceService中的所有方法
@Pointcut("within(com.imooc.service.ProduceService)")
public void matchType(){...}

//匹配com.imooc包及子包下所有類的方法
@Pointcut("within(com.imooc..*)")
public void matchPackage(){...}
匹配物件

this()

bean()

target()

匹配引數

args()

Other pointcut types

功能完全的AspectJ切入點支援Spring中不支援的切入點:call, get, set, preinitialization, staticinitialization, initialization, handler, adviceexecution, withincode, cflow, cflowbelow, if, @this, and @withincode. 在Spring AOP中使用這些切入點會丟擲IllegalArgumentException異常。

3.2.Sharing Common Pointcut Definitions

execution表示式:
execution(modifiers-pattern? ret-type-pattern declaring-type-pattern?name-pattern(param-pattern)
throws-pattern?)

修飾符匹配(modifier-pattern?)
返回值匹配(ret-type-pattern)可以為表示任何返回值,全路徑的類名等
類路徑匹配(declaring-type-pattern?)
方法名匹配(name-pattern)可以指定方法名 或者
代表所有, set* 代表以set開頭的所有方法
引數匹配((param-pattern))可以指定具體的引數型別,多個引數間用“,”隔開,各個引數也可以用“”來表示匹配任意型別的引數,如(String)表示匹配一個String引數的方法;(,String) 表示匹配有兩個引數的方法,第一個引數可以是任意型別,而第二個引數是String型別;可以用(..)表示零個或多個任意引數
異常型別匹配(throws-pattern?)

其中後面跟著“?”的是可選項,除了返回型別模板ret-type-pattern外都是可選項。表示萬用字元,()匹配無引數方法,(...)匹配任意引數(零個或者多個)方法,
)匹配任意一個任意型別引數的方法,(*,String)表示第一個引數隨意,第二個引數必須是String型別。

execution常用示例:

切入點匹配任意公共方法
execution(public * *(..))

切入點匹配任意set開頭的方法
execution(* set*(..))

切入點匹配com.xyz.service.AccountService介面定義的所有方法
execution(* com.xyz.service.AccountService.*(..))

切入點匹配任何定義在com.xyz.service中的方法
execution(* com.xyz.service..(..))

切入點匹配任何定義在com.xyz.service和其子包的方法
execution(* com.xyz.service...(..))

任何在com.xyz.service包中的參與點(方法):
within(com.xyz.service.*)

任何在com.xyz.service和其子包中的參與點(方法):
within(com.xyz.service..*)

任何com.xyz.service.AccountService介面定義的參與點(方法):
this(com.xyz.service.AccountService)

任何實現了AccountService介面的target object:
target(com.xyz.service.AccountService)

任何有單個引數並且引數可序列化的連線點(方法):
args(java.io.Serializable)

任何目標類加了@Transactional註解的連線點(方法):
@target(org.springframework.transaction.annotation.Transactional)

任何代理物件型別加了@Transactional註解的連線點:
@within(org.springframework.transaction.annotation.Transactional)

任何使用@Transactional註解了執行方法的連線點:
@annotation(org.springframework.transaction.annotation.Transactional)

任何帶有一個@Classified 註解入參的連線點:
@args(com.xyz.security.Classified)

連線點名稱為tradeService:
bean(tradeService)

連線點名稱匹配Service:
bean(
Service)

3.3.Writing Good Pointcuts

現有的指示器可分為三種:

分類指示器將指示器分成特定的型別:execution, get, set, call, and handler
生命週期指示器將指示器按照其作用範圍分類:within and withincode
上下文指示器將指示器按照上下文分類:this,target,@annotation

一個比較好的連線點必須至少含有前兩種指示器,只有一種指示器也不會影響功能但會增加織入操作的時間和記憶體消耗。

3.4. Declaring Advice

Advice和切入點(join point)緊密聯絡,其在連線點方法執行之前,之後或者環繞(之前及之後)執行。Advice可以匹配一個明確的連線點或者

Before Advice

可以使用 @Before註解定義before advice:

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

@Aspect
public class BeforeExample {

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

}

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

@Aspect
public class BeforeExample {

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

}

After Returning Advice

可以使用@AfterReturning註解定義after advice:

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

@Aspect
public class AfterReturningExample {

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

}

有些情況下可能需要在@AfterReturning中訪問被代理方法的返回值,可以使用returning屬性定義返回值,被代理方法中的返回值要和returning定義的一直才能保證對應的advice可以獲取到被代理方法的返回值:

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

@Aspect
public class AfterReturningExample {

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

}

After Throwing Advice

可以使用@AfterThrowing來定義一個after throwing advice,其在被代理方法丟擲異常後開始執行:

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

@Aspect
public class AfterThrowingExample {

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

}

可以使用throwing屬性來獲取被代理方法丟擲的異常,丟擲的異常引用欄位名稱和型別必須和throwing定義的一致:
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.AfterThrowing;

@Aspect
public class AfterThrowingExample {

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

}

After (Finally) Advice

使用@After宣告的after advice在被代理方法執行完退出後執行(正常退出或者丟擲異常),一般用於釋放資源:

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

@Aspect
public class AfterFinallyExample {

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

}

Around Advice

around advice用於在被代理方法執行前和執行後進行操作,同時其還決定被代理方法何時,如何以及是否執行。一般情況下使用符合要求的advice就可以了,當需要保證執行緒安全時,可以使用around advice。

使用@Around可以宣告around advice,around advice的第一個引數必須是ProceedingJoinPoint型別的,在around advice中呼叫其proceed()方法會讓被代理方法開始執行。

以下示例演示如何使用around advice:

import org.aspectj.lang.annotation.Aspect;
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;
}

}

Advice Parameters

Spring提供了對於advice中所需引數的支援,只需要在advice中定義相關的引數即可(比如之前的returing和throwing).

Access to the Current JoinPoint

每一種advice都可以宣告一個org.aspectj.lang.JoinPoint入參(around advice必須宣告)作為第一個引數,JointPoint可提供如下方法:

getArgs(): Returns the method arguments.

getThis(): Returns the proxy object.

getTarget(): Returns the target object.

getSignature(): Returns a description of the method that is being advised.

toString(): Prints a useful description of the method being advised.

Passing Parameters to Advice

可以使用args將引數傳遞給advice,以下例子中com.xyz.myapp.SystemArchitecture.dataAccessOperation使用account作為方法的第一個入參:

@Before("com.xyz.myapp.SystemArchitecture.dataAccessOperation() && args(account,..)")
public void validateAccount(Account account) {
// ...
}

args(account,..) 實現了兩個功能:第一,當前advice僅匹配使用account作為第一個引數的方法,第二,其將account引數傳遞給了advice。

另一種方法時宣告一個提供account的接入點,然後接入點將account提供給advice

@Pointcut("com.xyz.myapp.SystemArchitecture.dataAccessOperation() && args(account,..)")
private void accountDataAccessOperation(Account account) {}

@Before("accountDataAccessOperation(account)")
public void validateAccount(Account account) {
// ...
}

proxy object(this),target object(target)和annotation ( @within, @target, @annotation, and @args) 可以使用類似的方法獲取引數,以下例子展示如何
匹配@Auditable註解的方法並獲取@Auditable介面引用:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Auditable {
AuditCode value();
}

@Before("com.xyz.lib.Pointcuts.anyPublicMethod() && @annotation(auditable)")
public void audit(Auditable auditable) {
AuditCode code = auditable.value();
// ...
}

Advice Parameters and Generics

Spring AOP可以處理用在類宣告和方法入參中的範型,比如有一個如下的範型類:

public interface Sample

如下advice可以對範型類中具體的方法生效:

@Before("execution(* ..Sample+.sampleGenericMethod(*)) && args(param)")
public void beforeSampleMethod(MyType param) {
// Advice implementation
}

如下advice對範型集合無法生效:
@Before("execution(* ..Sample+.sampleGenericCollectionMethod(*)) && args(param)")
public void beforeSampleMethod(Collection

Determining Argument Names

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 not available through Java reflection, so Spring AOP uses the following strategy to determine parameter names:

If the parameter names have been explicitly specified by the user, the specified parameter names are used. Both the advice and the pointcut annotations have an optional argNames attribute that you can use to specify the argument names of the annotated method. These argument names are available at runtime. The following example shows how to use the argNames attribute:

@Before(value="com.xyz.lib.Pointcuts.anyPublicMethod() && target(bean) && @annotation(auditable)",
argNames="bean,auditable")
public void audit(Object bean, Auditable auditable) {
AuditCode code = auditable.value();
// ... use code and bean
}

If the first parameter is of the JoinPoint, ProceedingJoinPoint, or JoinPoint.StaticPart type, you ca 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:

@Before(value="com.xyz.lib.Pointcuts.anyPublicMethod() && target(bean) && @annotation(auditable)",
argNames="bean,auditable")
public void audit(JoinPoint jp, Object bean, Auditable auditable) {
AuditCode code = auditable.value();
// ... use code, bean, and jp
}
The special treatment given to the first parameter of the JoinPoint, ProceedingJoinPoint, and JoinPoint.StaticPart types is particularly convenient for advice instances that do not collect any other join point context. In such situations, you may omit the argNames attribute. For example, the following advice need not declare the argNames attribute:

@Before("com.xyz.lib.Pointcuts.anyPublicMethod()")
public void audit(JoinPoint jp) {
// ... use jp
}
Using the 'argNames' attribute is a little clumsy, so if the 'argNames' attribute has not been specified, Spring AOP looks at the debug information for the class and tries to determine the parameter names from the local variable table. This information is present as long as the classes have been compiled with debug information ( '-g:vars' at a minimum). The consequences of compiling with this flag on are: (1) your code is slightly easier to understand (reverse engineer), (2) the class file sizes are very slightly bigger (typically inconsequential), (3) the optimization to remove unused local variables is not applied by your compiler. In other words, you should encounter no difficulties by building with this flag on.

If an @AspectJ aspect has been compiled by the AspectJ compiler (ajc) even without the debug information, you need not add the argNames attribute, as the compiler retain the needed information.
If the code has been compiled without the necessary debug information, Spring AOP tries 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 takes only one parameter, the pairing is obvious). If the binding of variables is ambiguous given the available information, an AmbiguousBindingException is thrown.

If all of the above strategies fail, an IllegalArgumentException is thrown.

Proceeding with Arguments

We remarked earlier that we would describe how to write a proceed call with arguments that works consistently across Spring AOP and AspectJ. The solution is to ensure that the advice signature binds each of the method parameters in order. The following example shows how to do so:

@Around("execution(List

Advice Ordering

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).

When two pieces of advice defined in different 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 org.springframework.core.Ordered interface in the aspect class or annotating it with the Order annotation. Given two aspects, the aspect returning the lower value from Ordered.getValue() (or the annotation value) has the higher precedence.

When two pieces of advice defined in the same aspect both need to run at the same join point, the ordering is undefined (since there is no way to retrieve the declaration order through 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 that you can order at the aspect level.

4.Introductions

Introductions使aspect可以宣告advice可以實現一個給定的介面,並且提供該介面的實現。

可以使用@DeclareParents註解來宣告一個Introduction,下例中,給定一個UsageTracked介面和DefaultUsageTracked的介面實現類,aspect宣告所有service介面的實現類同樣實現了UsageTracked介面:

@Aspect
public class UsageTracking {

@DeclareParents(value="com.xzy.myapp.service.*+", defaultImpl=DefaultUsageTracked.class)
public static UsageTracked mixin;

@Before("com.xyz.myapp.SystemArchitecture.businessService() && this(usageTracked)")
public void recordUsage(UsageTracked usageTracked) {
    usageTracked.incrementUseCount();
}

}

5.Aspect Instantiation Models

This is an advanced topic. If you are just starting out with AOP, you can safely skip it until later.
By default, there is 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 perthis and pertarget instantiation models ( percflow, percflowbelow, and pertypewithin are not currently supported).

You can declare a perthis aspect by specifying a perthis clause in the @Aspect annotation. Consider the following example:

@Aspect("perthis(com.xyz.myapp.SystemArchitecture.businessService())")
public class MyAspect {

private int someState;

@Before(com.xyz.myapp.SystemArchitecture.businessService())
public void recordServiceUsage() {
    // ...
}

}
In the preceding example, the effect of the 'perthis' clause is that one aspect instance is created for each unique service object that executes 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 executes at matched join points, but only when the service object is the one with which this aspect is associated. See the AspectJ Programming Guide for more information on per clauses.

The pertarget instantiation model works in exactly the same way as perthis, but it creates one aspect instance for each unique target object at matched join points.

6.An AOP Example

業務的執行可能會因為多執行緒問題而失敗(比如死鎖問題),如果需要進行重試,我們希望在使用者無感知的情況下進行重試操作,因此一個理想的選擇是使用aspect。

因為需要重試操作,因此使用around advice來多次呼叫proceed:

@Aspect
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 <= this.maxRetries);
    throw lockFailureException;
}

}

這個切面實現了Ordered介面並將其order設為1(高於事務advice),這樣的話每次執行都會有一個純淨的事務。

對應的spring xml配置檔案,建立對應的bean並設定maxRetries和order:

To refine the aspect so that it retries only idempotent operations, we might define the following Idempotent annotation:

@Retention(RetentionPolicy.RUNTIME)
public @interface Idempotent {
// marker annotation
}
We can then use the annotation to annotate the implementation of service operations. The change to the aspect to retry only idempotent operations involves refining the pointcut expression so that only @Idempotent operations match, as follows:

@Around("com.xyz.myapp.SystemArchitecture.businessService() && " +
"@annotation(com.xyz.myapp.service.Idempotent)")
public Object doConcurrentOperation(ProceedingJoinPoint pjp) throws Throwable {
...
}

7.基於xml配置檔案的aop配置

If you prefer an XML-based format, Spring also offers support for defining aspects using the new aop namespace tags. The exact same pointcut expressions and advice kinds as when using the @AspectJ style are supported. Hence, in this section we focus on the new syntax and refer the reader to the discussion in the previous section (@AspectJ support) for an understanding of writing pointcut expressions and the binding of advice parameters.

To use the aop namespace tags described in this section, you need to import the spring-aop schema, as described in XML Schema-based configuration. See the AOP schema for how to import the tags in the aop namespace.

Within your Spring configurations, all aspect and advisor elements must be placed within an

The

You can declare an aspect by using the


The bean that backs the aspect (aBean in this case) can of course be configured and dependency injected just like any other Spring bean.

5.5.2. Declaring a Pointcut
You can declare a named pointcut inside an

A pointcut that represents the execution of any business service in the service layer can be defined as follows:

<aop:pointcut id="businessService"
    expression="execution(* com.xyz.myapp.service.*.*(..))"/>


Note that the pointcut expression itself is using the same AspectJ pointcut expression language as described in @AspectJ support. If you use the schema based declaration style, you can refer to named pointcuts defined in types (@Aspects) within the pointcut expression. Another way of defining the above pointcut would be as follows:

<aop:pointcut id="businessService"
    expression="com.xyz.myapp.SystemArchitecture.businessService()"/>


Assume that you have a SystemArchitecture aspect as described in Sharing Common Pointcut Definitions.

Then declaring a pointcut inside an aspect is very similar to declaring a top-level pointcut, as the following example shows:

<aop:aspect id="myAspect" ref="aBean">

    <aop:pointcut id="businessService"
        expression="execution(* com.xyz.myapp.service.*.*(..))"/>

    ...

</aop:aspect>


In much the same way as an @AspectJ aspect, pointcuts declared by using the schema based definition style can collect join point context. For example, the following pointcut collects the this object as the join point context and passes it to the advice:

<aop:aspect id="myAspect" ref="aBean">

    <aop:pointcut id="businessService"
        expression="execution(* com.xyz.myapp.service.*.*(..)) &amp;&amp; this(service)"/>

    <aop:before pointcut-ref="businessService" method="monitor"/>

    ...

</aop:aspect>


The advice must be declared to receive the collected join point context by including parameters of the matching names, as follows:

public void monitor(Object service) {
...
}
When combining pointcut sub-expressions, && is awkward within an XML document, so you can use the and, or, and not keywords in place of &&, ||, and !, respectively. For example, the previous pointcut can be better written as follows:

<aop:aspect id="myAspect" ref="aBean">

    <aop:pointcut id="businessService"
        expression="execution(* com.xyz.myapp.service..(..)) and this(service)"/>

    <aop:before pointcut-ref="businessService" method="monitor"/>

    ...
</aop:aspect>


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.

5.5.3. Declaring Advice
The schema-based AOP support uses the same five kinds of advice as the @AspectJ style, and they have exactly the same semantics.

Before Advice

Before advice runs before a matched method execution. It is declared inside an

<aop:before
    pointcut-ref="dataAccessOperation"
    method="doAccessCheck"/>

...


Here, dataAccessOperation is the id of a pointcut defined at the top (

<aop:before
    pointcut="execution(* com.xyz.myapp.dao.*.*(..))"
    method="doAccessCheck"/>

...


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

The method attribute identifies a method (doAccessCheck) that provides the body of the advice. This method must be defined for the bean referenced by the aspect element that contains 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 is invoked.

After Returning Advice

After returning advice runs when a matched method execution completes normally. It is declared inside an

<aop:after-returning
    pointcut-ref="dataAccessOperation"
    method="doAccessCheck"/>

...


As in the @AspectJ style, you can get the return value within the advice body. To do so, use the returning attribute to specify the name of the parameter to which the return value should be passed, as the following example shows:

<aop:after-returning
    pointcut-ref="dataAccessOperation"
    returning="retVal"
    method="doAccessCheck"/>

...


The doAccessCheck method must declare a parameter named retVal. The type of this parameter constrains matching in the same way as described for @AfterReturning. For example, you can decleare the method signature as follows:

public void doAccessCheck(Object retVal) {...
After Throwing Advice

After throwing advice executes when a matched method execution exits by throwing an exception. It is declared inside an

<aop:after-throwing
    pointcut-ref="dataAccessOperation"
    method="doRecoveryActions"/>

...


As in the @AspectJ style, you can get the thrown exception within the advice body. To do so, use the throwing attribute to specify the name of the parameter to which the exception should be passed as the following example shows:

<aop:after-throwing
    pointcut-ref="dataAccessOperation"
    throwing="dataAccessEx"
    method="doRecoveryActions"/>

...


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

public void doRecoveryActions(DataAccessException dataAccessEx) {...
After (Finally) Advice

After (finally) advice runs no matter how a matched method execution exits. You can declare it by using the after element, as the following example shows:

<aop:after
    pointcut-ref="dataAccessOperation"
    method="doReleaseLock"/>

...


Around Advice

The last 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 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. Do not use around advice if before advice can do the job.

You can declare around advice by using the aop:around element. The first parameter of the advice method must be of type ProceedingJoinPoint. Within the body of the advice, calling proceed() on the ProceedingJoinPoint causes the underlying method to execute. The proceed method may also be called with an Object[]. The values in the array are used as the arguments to the method execution when it proceeds. See Around Advice for notes on calling proceed with an Object[]. The following example shows how to declare around advice in XML:

<aop:around
    pointcut-ref="businessService"
    method="doBasicProfiling"/>

...


The implementation of the doBasicProfiling advice can be exactly the same as in the @AspectJ example (minus the annotation, of course), as the following example shows:

public Object doBasicProfiling(ProceedingJoinPoint pjp) throws Throwable {
// start stopwatch
Object retVal = pjp.proceed();
// stop stopwatch
return retVal;
}
Advice Parameters

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 Advice Parameters for details. If you wish to explicitly specify argument names for the advice methods (not relying on the detection strategies previously described), you can do so by using the arg-names attribute of the advice element, which is treated in the same manner as the argNames attribute in an advice annotation (as described in Determining Argument Names). The following example shows how to specify an argument name in XML:

The following slightly more involved example of the XSD-based approach shows some around advice used in conjunction with a number of strongly typed parameters:

package x.y.service;

public interface PersonService {

Person getPerson(String personName, int age);

}

public class DefaultFooService implements FooService {

public Person getPerson(String name, int age) {
    return new Person(name, age);
}

}
Next up is the aspect. Notice the fact that the profile(..) 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 profile(..) is to be used as around advice, as the following example shows:

package x.y;

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());
    }
}

}
Finally, the following example XML configuration effects the execution of the preceding advice for a particular join point:

<!-- this is the object that will be proxied by Spring's AOP infrastructure -->
<bean id="personService" class="x.y.service.DefaultPersonService"/>

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

<aop:config>
    <aop:aspect ref="profiler">

        <aop:pointcut id="theExecutionOfSomePersonServiceMethod"
            expression="execution(* x.y.service.PersonService.getPerson(String,int))
            and args(name, age)"/>

        <aop:around pointcut-ref="theExecutionOfSomePersonServiceMethod"
            method="profile"/>

    </aop:aspect>
</aop:config>


Consider the following driver script:

import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import x.y.service.PersonService;

public final class Boot {

public static void main(final String[] args) throws Exception {
    BeanFactory ctx = new ClassPathXmlApplicationContext("x/y/plain.xml");
    PersonService person = (PersonService) ctx.getBean("personService");
    person.getPerson("Pengo", 12);
}

}
With such a Boot class, we would get output similar to the folloiwng on standard output:

StopWatch 'Profiling for 'Pengo' and '12'': running time (millis) = 0

ms % Task name

00000 ? execution(getFoo)
Advice Ordering

When multiple advice needs to execute at the same join point (executing method) the ordering rules are as described in Advice Ordering. The precedence between aspects is determined by either adding the Order annotation to the bean that backs the aspect or by having the bean implement the Ordered interface.

5.5.4. Introductions
Introductions (known as inter-type declarations in AspectJ) let an aspect declare that advised objects implement a given interface and provide an implementation of that interface on behalf of those objects.

You can make an introduction by using the aop:declare-parents element inside an aop:aspect. You can use the aop:declare-parents element to declare that matching types have a new parent (hence the name). For example, given an interface named UsageTracked and an implementation of that interface named DefaultUsageTracked, the following aspect declares that all implementors of service interfaces also implement the UsageTracked interface. (In order to expose statistics through JMX for example.)

<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"/>

<aop:before
    pointcut="com.xyz.myapp.SystemArchitecture.businessService()
        and this(usageTracked)"
        method="recordUsage"/>


The class that backs the usageTracking bean would then contain the following method:

public void recordUsage(UsageTracked usageTracked) {
usageTracked.incrementUseCount();
}
The interface to be implemented is determined by the implement-interface attribute. The value of the types-matching attribute is an AspectJ type pattern. Any bean of a matching type implements the UsageTracked interface. Note that, in the before advice of the preceding example, service beans can be directly used as implementations of the UsageTracked interface. To access a bean programmatically, you could write the following:

UsageTracked usageTracked = (UsageTracked) context.getBean("myService");
5.5.5. Aspect Instantiation Models
The only supported instantiation model for schema-defined aspects is the singleton model. Other instantiation models may be supported in future releases.

5.5.6. Advisors
The concept of “advisors” comes from the AOP support defined in Spring 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 Advice Types in Spring. Advisors can take advantage of AspectJ pointcut expressions.

Spring supports the advisor concept with the

<aop:pointcut id="businessService"
    expression="execution(* com.xyz.myapp.service.*.*(..))"/>

<aop:advisor
    pointcut-ref="businessService"
    advice-ref="tx-advice"/>


As well as the pointcut-ref attribute used in the preceding example, you can also use the pointcut attribute to define a pointcut expression inline.

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

5.5.7. An AOP Schema Example
This section shows how the concurrent locking failure retry example from An AOP Example looks when rewritten with the schema support.

The execution of business services can sometimes fail due to concurrency issues (for example, a deadlock loser). If the operation is retried, it is likely to succeed on the next try. For business services where it is appropriate to retry in such conditions (idempotent operations that do not need to go back to the user for conflict resolution), we want to transparently retry the operation to avoid the client seeing a PessimisticLockingFailureException. This is a requirement that clearly cuts across multiple services in the service layer and, hence, is ideal for implementing through an aspect.

Because we want to retry the operation, we need to use around advice so that we can call proceed multiple times. The following listing shows the basic aspect implementation (which is a regular Java class that uses the schema support):

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;
}

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 <= this.maxRetries);
    throw lockFailureException;
}

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

This class is identical to the one used in the @AspectJ example, but with the annotations removed.
The corresponding Spring configuration is as follows:

<aop:aspect id="concurrentOperationRetry" ref="concurrentOperationExecutor">

    <aop:pointcut id="idempotentOperation"
        expression="execution(* com.xyz.myapp.service.*.*(..))"/>

    <aop:around
        pointcut-ref="idempotentOperation"
        method="doConcurrentOperation"/>

</aop:aspect>


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 retries only genuinely idempotent operations, by introducing an Idempotent annotation and using the annotation to annotate the implementation of service operations, as the following example shows:

@Retention(RetentionPolicy.RUNTIME)
public @interface Idempotent {
// marker annotation
}
The change to the aspect to retry only idempotent operations involves refining the pointcut expression so that only @Idempotent operations match, as follows:

5.6. Choosing which AOP Declaration Style to Use
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, the @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.

5.6.1. Spring AOP or Full AspectJ?
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, Spring AOP is the right choice. If you need to advise objects not managed by the Spring container (such as domain objects, typically), you need to use AspectJ. You 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).

When you use AspectJ, you have the choice of the AspectJ language syntax (also known as the “code style”) or the @AspectJ annotation style. Clearly, if you do not use Java 5+, 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 AspectJ Development Tools (AJDT) plugin for Eclipse, the AspectJ language syntax is the preferred option. It is cleaner and simpler because the language was purposefully designed for writing aspects. If you do not use Eclipse or have only a few aspects that do not play a major role in your application, you may want to consider using the @AspectJ style, sticking with regular Java compilation in your IDE, and adding an aspect weaving phase to your build script.

5.6.2. @AspectJ or XML for Spring AOP?
If you have chosen to use Spring AOP, you have a choice of @AspectJ or XML style. There are various tradeoffs to consider.

The XML style may most familiar to existing Spring users, and it is backed by genuine POJOs. When using AOP as a tool to configure enterprise services, XML can be a good choice (a good test is whether you consider the pointcut expression to be a part of your configuration that you might want to change independently). With the XML style, it is arguably clearer from your configuration what aspects are present in the system.

The XML style has two disadvantages. First, 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 how a requirement is implemented is split across the declaration of the backing bean class and the XML in the configuration file. When you use the @AspectJ style, this information is encapsulated in a single single module: the aspect. 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 the following:

@Pointcut("execution(* get*())")
public void propertyAccess() {}

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

@Pointcut("propertyAccess() && operationReturningAnAccount()")
public void accountPropertyAccess() {}
In the XML style you can declare the first two pointcuts:

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 that 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, you can easily migrate to an AspectJ-based approach. On balance, the Spring team prefers the @AspectJ style whenever you have aspects that do more than simple configuration of enterprise services.

5.7. Mixing Aspect Types
It is perfectly possible to mix @AspectJ style aspects by using the auto-proxying support, schema-defined

5.8. Proxying Mechanisms
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).

If the target object to be proxied implements at least one interface, a JDK dynamic proxy is used. All of the interfaces implemented by the target type are proxied. If the target object does not implement any interfaces, a CGLIB proxy is created.

If you want to force the use of CGLIB proxying (for example, to proxy every method defined for the target object, not only those implemented by its interfaces), you can do so. However, you should consider the following issues:

final methods cannot be advised, as they cannot be overridden.

As of Spring 3.2, it is no longer necessary to add CGLIB to your project classpath, as CGLIB classes are repackaged under org.springframework and included directly in the spring-core JAR. This means that CGLIB-based proxy support “just works”, in the same way that JDK dynamic proxies always have.

As of Spring 4.0, the constructor of your proxied object is NOT called twice any more, since the CGLIB proxy instance is created through Objenesis. Only if your JVM does not allow for constructor bypassing, you might see double invocations and corresponding debug log entries from Spring’s AOP support.

To force the use of CGLIB proxies, set the value of the proxy-target-class attribute of the


To force CGLIB proxying when you use the @AspectJ auto-proxy support, set the proxy-target-class attribute of the

To be clear, using proxy-target-class="true" on

Consider first the scenario where you have a plain-vanilla, un-proxied, nothing-special-about-it, straight object reference, as the following code snippet shows:

public class SimplePojo implements Pojo {

public void foo() {
    // this next method invocation is a direct call on the 'this' reference
    this.bar();
}

public void bar() {
    // some logic...
}

}
If you invoke a method on an object reference, the method is invoked directly on that object reference, as the following image and listing show:

aop proxy plain pojo call
public class Main {

public static void main(String[] args) {

    Pojo pojo = new SimplePojo();

    // this is a direct method call on the 'pojo' reference
    pojo.foo();
}

}
Things change slightly when the reference that client code has is a proxy. Consider the following diagram and code snippet:

aop proxy call
public class Main {

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();

    // this is a method call on the proxy!
    pojo.foo();
}

}
The key thing to understand here is that the client code inside the main(..) method of the Main class has a reference to the proxy. This means that method calls on that object reference are calls on the proxy. As a result, the proxy can 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 SimplePojo, reference in this case), any method calls that it may make on itself, such as this.bar() or this.foo(), are going to be invoked against the this reference, and not the proxy. This has important implications. It means that self-invocation is not going to result in the advice associated with a method invocation getting a chance to execute.

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. This does entail some work on your part, but it is the best, least-invasive approach. The next approach is absolutely horrendous, and we hesitate to point it out, precisely because it is so horrendous. You can (painful as it is to us) totally tie the logic within your class to Spring AOP, as the following example shows:

public class SimplePojo implements Pojo {

public void foo() {
    // this works, but... gah!
    ((Pojo) AopContext.currentProxy()).bar();
}

public void bar() {
    // some logic...
}

}
This totally couples your code to Spring AOP, and 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, as the following example shows:

public class Main {

public static void main(String[] args) {

    ProxyFactory factory = new ProxyFactory(new SimplePojo());
    factory.adddInterface(Pojo.class);
    factory.addAdvice(new RetryAdvice());
    factory.setExposeProxy(true);

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

    // this is a method call on the proxy!
    pojo.foo();
}

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

5.9. Programmatic Creation of @AspectJ Proxies
In addition to declaring aspects in your configuration by using either

You can use the org.springframework.aop.aspectj.annotation.AspectJProxyFactory class to create a proxy for a target object that is advised by one or more @AspectJ aspects. The basic usage for this class is very simple, as the following example shows:

// create a factory that can generate a proxy for the given target object
AspectJProxyFactory factory = new AspectJProxyFactory(targetObject);

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

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

// now get the proxy object...
MyInterfaceType proxy = factory.getProxy();
See the javadoc for more information.

5.10. Using AspectJ with Spring Applications
Everything we have covered so far in this chapter is pure Spring AOP. In this section, we look at how you can use the AspectJ compiler or weaver instead of or in addition to Spring AOP if your needs go beyond the facilities offered by Spring AOP alone.

Spring ships with a small AspectJ aspect library, which is available stand-alone in your distribution as spring-aspects.jar. You need to add this to your classpath in order to use the aspects in it. Using AspectJ to Dependency Inject Domain Objects with Spring and Other Spring aspects for AspectJ discuss the content of this library and how you can use it. Configuring AspectJ Aspects by Using Spring IoC discusses how to dependency inject AspectJ aspects that are woven using the AspectJ compiler. Finally, Load-time Weaving with AspectJ in the Spring Framework provides an introduction to load-time weaving for Spring applications that use AspectJ.

5.10.1. Using AspectJ to Dependency Inject Domain Objects with Spring
The Spring container instantiates and configures beans defined in your application context. It is also possible to ask a bean factory to configure a pre-existing object, given the name of a bean definition that contains the configuration to be applied. spring-aspects.jar contains an annotation-driven aspect that exploits this capability to allow dependency injection of any object. The support is intended to be used for objects created outside of the control of any container. Domain objects often fall into this category because they are often created programmatically with the new operator or by an ORM tool as a result of a database query.

The @Configurable annotation marks a class as being eligible for Spring-driven configuration. In the simplest case, you can use purely it as a marker annotation, as the following example shows:

package com.xyz.myapp.domain;

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

@Configurable
public class Account {
// ...
}
When used as a marker interface in this way, Spring configures new instances of the annotated type (Account, in this case) by using a bean definition (typically prototype-scoped) with the same name as the fully-qualified type name (com.xyz.myapp.domain.Account). Since the default name for a bean is the fully-qualified name of its type, a convenient way to declare the prototype definition is to omit the id attribute, as the following example shows:


If you want to explicitly specify the name of the prototype bean definition to use, you can do so directly in the annotation, as the following example shows:

package com.xyz.myapp.domain;

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

@Configurable("account")
public class Account {
// ...
}
Spring now looks for a bean definition named account and uses that as the definition to configure new Account instances.

You can also use autowiring to avoid having to specify a dedicated bean definition at all. To have Spring apply autowiring, use the autowire property of the @Configurable annotation. You can specify either @Configurable(autowire=Autowire.BY_TYPE) or @Configurable(autowire=Autowire.BY_NAME 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 @Configurable beans by using @Autowired or @Inject at the field or method level (see Annotation-based Container Configuration for further details).

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

Note that using the annotation on its own does nothing. It is the AnnotationBeanConfigurerAspect in spring-aspects.jar 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 @Configurable, configure the newly created object using Spring in accordance with the properties of the annotation”. In this context, “initialization” refers to newly instantiated objects (for example, objects instantiated with the new operator) as well as to Serializable objects that are undergoing deserialization (for example, through readResolve()).

One of the key phrases in the above paragraph is “in essence”. For most cases, the exact semantics of “after returning from the initialization of a new object” are fine. In this context, “after initialization” means that the dependencies are injected after the object has been constructed. This means that the dependencies are not available for use in the constructor bodies of the class. If you want the dependencies to be injected before the constructor bodies execute and thus be available for use in the body of the constructors, you need to define this on the @Configurable declaration, as follows:

@Configurable(preConstruction=true)
You can find more information about the language semantics of the various pointcut types in AspectJ in this appendix of the AspectJ Programming Guide.
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 AspectJ Development Environment Guide) or load-time weaving (see Load-time Weaving with AspectJ in the Spring Framework). The AnnotationBeanConfigurerAspect itself needs to be configured by Spring (in order to obtain a reference to the bean factory that is to be used to configure new objects). If you use Java-based configuration, you can add @EnableSpringConfigured to any @Configuration class, as follows:

@Configuration
@EnableSpringConfigured
public class AppConfig {

}
If you prefer XML based configuration, the Spring context namespace defines a convenient context:spring-configured element, which you can use as follows:

<!-- ... -->


Do not activate @Configurable 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 @Configurable on bean classes that are registered as regular Spring beans with the container. Doing so results in double initialization, once through the container and once through the aspect.
Unit Testing @Configurable Objects

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

Working with Multiple Application Contexts

The AnnotationBeanConfigurerAspect that is used to implement the @Configurable support is an AspectJ singleton aspect. The scope of a singleton aspect is the same as the scope of static members: There is one aspect instance per classloader tha