skip to content

ProxyFactory, Advised & TargetSource

ProxyFactory builds proxies programmatically, Advised exposes the advisor chain on any proxy, and TargetSource abstracts where the target comes from. Handy for debugging live proxies and for senior questions about pooled or hot-swappable targets.

part ofSpring Frameworkoverview, primer and where to startread it →
on this pageshow

questions

5

What is Spring's ProxyFactory and how do you use it to create an AOP proxy programmatically?

level: juniorimportance: should knowfreq 45%

answer

  1. setTarget -> addAdvice -> getProxy
  2. extends AdvisedSupport, implements Advised
  3. JDK proxy if interfaces, else CGLIB
  4. cast to interface not concrete class
  5. same engine as container auto-proxy

basics

~20 s

ProxyFactory is a Spring class that builds an AOP proxy in plain code (no Spring container). You give it a target object, add one or more advices, then call getProxy() to get a wrapped object that runs the advice around the target's methods.

solid answer

~40 s

ProxyFactory is Spring AOP's programmatic entry point for building a proxy without a Spring context. You set a target object with setTarget(), attach behavior with addAdvice() (or addAdvisor() for advice plus a pointcut), optionally declare setInterfaces() or setProxyTargetClass(true), then call getProxy() which returns an Object you cast to your interface. Calls to the returned proxy pass through the advisor chain before hitting the target. Under the hood it decides between a JDK dynamic proxy (if the target exposes interfaces) and a CGLIB subclass proxy. It is the same machinery Spring uses internally when it auto-proxies your beans; ProxyFactory just exposes it for standalone use, tests, or library code that needs to wrap an object by hand.

code

java · 17 lines
java
public interface Greeter { String hello(String name); }

public class GreeterImpl implements Greeter {
    public String hello(String name) { return "Hi " + name; }
}

// Build a proxy programmatically
ProxyFactory pf = new ProxyFactory(new GreeterImpl());
pf.addAdvice((MethodInterceptor) invocation -> {
    System.out.println("before " + invocation.getMethod().getName());
    Object result = invocation.proceed(); // call the target
    System.out.println("after");
    return result;
});

Greeter proxy = (Greeter) pf.getProxy(); // cast to the INTERFACE
proxy.hello("Ada"); // prints before/after around "Hi Ada"

go deeper

for a junior

Know the three steps: target, advice, getProxy(); and that the result is cast to the interface.

for a middle

Explain JDK vs CGLIB selection and the addAdvice-vs-addAdvisor distinction.

for a senior

Connect ProxyFactory to the same AdvisedSupport machinery the container's auto-proxy creator uses; discuss exposeProxy/self-invocation.

for a principal

Reason about when hand-rolled proxies belong in library code vs. relying on container auto-proxying, and the maintenance cost of each.

**What it is.** `org.springframework.aop.framework.ProxyFactory` is the programmatic (code-driven) way to create a Spring AOP proxy, as opposed to the declarative auto-proxying the container does for you when you use `@Aspect`/`@EnableAspectJAutoProxy`. A *proxy* here is an object that looks like your target (same interfaces or a subclass of its type) but intercepts method calls so extra behavior (*advice*) can run before/after/around the real call. **Class hierarchy.** `ProxyFactory` extends `ProxyCreatorSupport`, which extends `AdvisedSupport`, which extends `ProxyConfig` and implements the `Advised` interface. That means a `ProxyFactory` *is* an `Advised` config object holding the target, the interfaces, the advisor chain, and flags like `proxyTargetClass`, `exposeProxy`, `frozen`. **Core steps / API.** 1. `new ProxyFactory(targetObject)` or `new ProxyFactory()` then `setTarget(target)`. 2. Add behavior: `addAdvice(Advice)` — e.g. a `MethodInterceptor` — which Spring wraps in a `DefaultPointcutAdvisor` matching all methods; or `addAdvisor(Advisor)` when you want a `Pointcut` to limit which methods are advised. 3. Optional config: `setInterfaces(...)` to force which interfaces the proxy exposes; `setProxyTargetClass(true)` to force a CGLIB class-based proxy; `setExposeProxy(true)` to publish the proxy via `AopContext.currentProxy()`. 4. `getProxy()` (or `getProxy(ClassLoader)`) returns the proxy as `Object`; cast to your interface/class. **Advice types you can add.** `MethodInterceptor` (AOP Alliance, around advice), `MethodBeforeAdvice`, `AfterReturningAdvice`, `ThrowsAdvice`. Around advice must call `invocation.proceed()` to continue the chain and reach the target. **JDK vs CGLIB choice.** If the target implements at least one interface and `proxyTargetClass` is false (default), you get a JDK dynamic proxy implementing those interfaces — so you must cast the result to the *interface*, not the concrete class. If the target has no interfaces, or `proxyTargetClass=true`, Spring uses CGLIB to generate a runtime subclass, so `final` classes/methods can't be proxied and a no-arg-constructor-free class still works because CGLIB uses Objenesis. **When to use it.** Standalone/library code that needs to wrap an object outside a Spring context; tests that verify an interceptor; frameworks building decorators dynamically. In ordinary application code you rarely call it directly — the container's auto-proxy infrastructure (`AnnotationAwareAspectJAutoProxyCreator`) uses the same `AdvisedSupport`/`ProxyFactory` machinery for you. **Gotchas.** (1) Casting a JDK-proxy to the concrete class throws `ClassCastException` — cast to the interface. (2) Self-invocation (target calling its own `this.method()`) bypasses the proxy unless you enable `exposeProxy` and call `AopContext.currentProxy()`. (3) `getProxy()` builds a fresh proxy each call reflecting the current advisor chain. (4) `AspectJProxyFactory` is the sibling that additionally lets you add whole `@Aspect` classes via `addAspect(...)`.

  • Why must you cast the result of getProxy() to the interface and not GreeterImpl?
    Because with an interface-implementing target and default settings Spring creates a JDK dynamic proxy, which is a new class implementing Greeter but is NOT a subclass of GreeterImpl, so casting to the concrete class throws ClassCastException. Set proxyTargetClass(true) for a CGLIB subclass proxy if you need the concrete type.
  • What's the difference between addAdvice() and addAdvisor()?
    addAdvice() takes just the behavior and Spring wraps it in a DefaultPointcutAdvisor with Pointcut.TRUE, so it applies to every method. addAdvisor() takes an Advisor = pointcut + advice, letting you restrict which methods are intercepted.

saying these in an interview costs you the question

  • Thinking ProxyFactory requires a running Spring ApplicationContext
  • Believing you can always cast the proxy to the concrete target class
  • Confusing addAdvice (all methods) with a pointcut-scoped advisor

context

open as a page

What is the Advised interface and what can you do by casting a live Spring AOP proxy to it?

level: middleimportance: should knowfreq 40%

basics

~20 s

Advised is the interface every Spring AOP proxy implements. Cast a proxy to Advised to inspect or change it at runtime: read the list of advisors, add or remove advice, and see the target and proxy settings.

open as a page

What problem does the TargetSource interface solve, and how do singleton, prototype, and pooled TargetSources differ?

level: seniorimportance: should knowfreq 35%

basics

~20 s

TargetSource decides where the real target object comes from for each proxied call. By default it's a fixed singleton, but you can make it return a fresh prototype instance per call, borrow one from a pool, or keep a per-thread instance — all behind the same proxy.

open as a page

How does AspectJProxyFactory differ from ProxyFactory, and when would you reach for it?

level: middleimportance: nice to knowfreq 25%

basics

~10 s

ProxyFactory works with low-level advices and advisors. AspectJProxyFactory adds a convenience: you can hand it whole @Aspect-annotated classes with addAspect(), and it turns their @Before/@Around/etc. methods into the proxy's advisor chain for you.

open as a page

Walk through what happens internally when a method is called on a Spring AOP proxy, from ProxyFactory config down to the advisor chain and TargetSource.

level: principalimportance: nice to knowfreq 20%

basics

~20 s

A call hits the proxy's invoke handler. It asks the TargetSource for the target, builds the list of matching interceptors for that method from the advisors, then runs them one by one via a MethodInvocation whose proceed() steps through the chain and finally calls the target method by reflection.

open as a page