skip to content

What is <aop:advisor> and how does it differ from <aop:aspect>? When would you wire a plain bean as an advisor?

level: seniorimportance: should knowfreq 40%

answer

  1. Advisor = one advice + one pointcut
  2. advice-ref (must implement Advice/MethodInterceptor), no method attr
  3. aspect = POJO + named methods; advisor = ready-made interceptor
  4. canonical use: <tx:advice> + <aop:advisor> for transactions
  5. order attribute sets precedence across both

basics

~20 s

aop:advisor pairs a pointcut with a reusable advice bean that already implements a Spring Advice interface (like MethodInterceptor). aop:aspect instead groups multiple advice methods on a plain POJO. Advisors are how tx:advice transactions get applied.

solid answer

~40 s

An Advisor in Spring is the low-level pairing of one piece of advice with a pointcut. <aop:advisor> wires an existing advice/interceptor bean — something implementing an AOP Alliance interface like MethodInterceptor, or Spring's MethodBeforeAdvice/AfterReturningAdvice — to a pointcut via advice-ref plus pointcut or pointcut-ref. There's no aspect POJO and no named advice methods; the whole advice is that one bean. <aop:aspect>, by contrast, references a POJO and exposes several of its methods as before/after/around advice through XML. You reach for <aop:advisor> to reuse framework or generic interceptors — the canonical case being declarative transactions, where <tx:advice> generates a transaction interceptor and <aop:advisor advice-ref="txAdvice" pointcut="..."/> binds it to your service methods. Advisors also take an order attribute for precedence.

code

java · 32 lines
java
// A reusable interceptor bean (AOP Alliance MethodInterceptor).
package com.app;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;

public class TimingInterceptor implements MethodInterceptor {
    @Override
    public Object invoke(MethodInvocation mi) throws Throwable {
        long t0 = System.nanoTime();
        try {
            return mi.proceed();          // invoke the target method
        } finally {
            System.out.println(mi.getMethod().getName()
                + " took " + (System.nanoTime() - t0) + "ns");
        }
    }
}

/*
<bean id="timing" class="com.app.TimingInterceptor"/>

<aop:config>
    <aop:pointcut id="svc" expression="execution(* com.app.service..*(..))"/>

    <!-- Wire the interceptor bean directly as an advisor: no POJO, no method= -->
    <aop:advisor advice-ref="timing" pointcut-ref="svc" order="2"/>
</aop:config>

<!-- Classic transaction wiring uses the same advisor mechanism: -->
<!-- <tx:advice id="txAdvice" transaction-manager="txManager"/>            -->
<!-- <aop:advisor advice-ref="txAdvice" pointcut-ref="svc" order="1"/>     -->
*/

go deeper

for a junior

Know that aop:advisor connects a ready-made advice bean to a pointcut, unlike the POJO-based aop:aspect.

for a middle

Identify the transaction wiring pattern (tx:advice + aop:advisor) and that advice-ref must implement an advice interface.

for a senior

Explain the Advisor = advice+pointcut model, single-advice-per-advisor, and cross-cutting ordering with 'order'.

for a principal

Reason about interceptor thread-safety/singleton semantics, precedence between transactional and non-transactional advice, and when to expose reusable interceptors as advisors vs aspects.

**The Advisor concept.** In Spring AOP's internal model, an **Advisor** is the smallest complete unit of advice: it bundles exactly one piece of **advice** with a **pointcut** that decides where that advice applies. Every aspect you write is ultimately decomposed by Spring into a set of Advisors. The `<aop:advisor>` element lets you declare one directly, in the case where you already have an advice bean and just need to say *where* it runs. **`<aop:advisor>` element.** Attributes: - `advice-ref` — references a bean that **implements an advice interface**. Supported types include the AOP Alliance `org.aopalliance.intercept.MethodInterceptor` (for around-style interception via `invoke(MethodInvocation)`) and Spring's advice interfaces `MethodBeforeAdvice`, `AfterReturningAdvice`, `ThrowsAdvice`. - `pointcut` (inline expression) or `pointcut-ref` (a named `<aop:pointcut>`). - `order` — precedence relative to other advisors/aspects. Unlike `<aop:aspect>`, there is **no `ref` to a POJO and no `method` attribute**, because the advice isn't a named method — the entire advice bean *is* the advice. **`<aop:aspect>` vs `<aop:advisor>` — the contrast:** | | `<aop:aspect>` | `<aop:advisor>` | |---|---|---| | Backing bean | plain POJO (`ref`) | bean implementing an Advice interface (`advice-ref`) | | Advice source | named POJO methods via `<aop:before>` etc. | the whole interceptor/advice bean | | Multiple advice | yes, group many | one advice per advisor | | Typical use | your own cross-cutting logic | reusing framework/generic interceptors | **Why advisors exist / when to use them.** 1. **Reusing an existing interceptor.** If you have (or a library gives you) a `MethodInterceptor`, you don't want to wrap it in a POJO aspect — you bind it directly with an advisor. 2. **Declarative transactions — the headline case.** `<tx:advice id="txAdvice" transaction-manager="txManager">` produces a `TransactionInterceptor` (a `MethodInterceptor`). You then apply it: `<aop:advisor advice-ref="txAdvice" pointcut="execution(* com.app.service..*(..))"/>`. This is the classic XML transaction wiring and a very common interview example. 3. **Reusing Spring's stock interceptors** — e.g. caching, performance-monitoring (`PerformanceMonitorInterceptor`), or custom `Advice` implementations shared across projects. **Ordering and interaction.** Both aspects and advisors participate in one precedence chain via `order`. When a transaction advisor and a logging aspect both match a method, their relative `order` determines whether logging wraps the transaction or vice versa — an important correctness detail (e.g. you usually want logging *outside* the transaction boundary or explicitly decide). **Gotchas.** - The `advice-ref` bean **must** implement a recognized advice interface; a random POJO won't work there — that's what `<aop:aspect>` is for. - An advisor carries exactly one advice; to attach several behaviors you declare several advisors (or use an aspect). - Advisors are proxied through the same auto-proxy creator, so all the standard Spring AOP limitations (method-execution join points only, self-invocation bypass) still apply. - The `advice-ref` bean is typically a **singleton**; if it holds per-invocation state it must be thread-safe, since one interceptor instance serves all concurrent calls. **Mental model.** `<aop:aspect>` is 'here's my POJO, expose these methods as advice.' `<aop:advisor>` is 'here's a ready-made advice bean, apply it at this pointcut.' Transactions are the reason most developers meet `<aop:advisor>` at all.

  • What kind of bean can you reference from advice-ref?
    One that implements a recognized advice interface: the AOP Alliance MethodInterceptor, or Spring's MethodBeforeAdvice / AfterReturningAdvice / ThrowsAdvice. A plain POJO without such an interface can't be an advisor's advice — that's what <aop:aspect> is for.
  • How are declarative transactions wired in XML using advisors?
    <tx:advice> creates a TransactionInterceptor (a MethodInterceptor) driven by transaction attributes; then <aop:advisor advice-ref="txAdvice" pointcut="..."/> applies that interceptor to the matched service methods through the same proxy machinery.

saying these in an interview costs you the question

  • Saying <aop:advisor> takes a method attribute like <aop:aspect> (it doesn't — the whole bean is the advice).
  • Claiming any POJO can be an advice-ref (it must implement a Spring/AOP-Alliance advice interface).
  • Thinking advisor and aspect precedence are separate chains (they share one ordering via 'order').

context