You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring中lookup-method与AOP scoped-proxy的使用场景及疑问

Understanding Lookup Method Injection vs. AOP Scoped Proxies in Spring

Great questions—these are super common points of confusion when working with beans of different scopes in Spring, so let’s break them down clearly and practically.

1. When to Use Lookup Method Injection vs. AOP Scoped Proxies?

Let’s start with AOP scoped proxies—this is your first choice for most scenarios where you need to inject a context-bound scoped bean (like request-scoped or session-scoped) into a singleton bean. Here’s why:

  • It’s nearly invisible in your code: You use @Autowired or constructor injection just like you would with a singleton bean. Spring creates a proxy that wraps the scoped bean, and every time you call a method on that proxy, it pulls the correct instance from the current request/session context.
  • Minimal code intrusion: No extra methods or abstract classes required—your code stays focused on its actual business logic.

Use this when:

  • You’re working with web scopes (request/session) and need to inject them into singletons.
  • You want the "natural" dependency injection experience without modifying your bean classes beyond standard injection annotations.

Now, lookup method injection (either via XML <lookup-method> or the @Lookup annotation) is for scenarios where you need to explicitly fetch a new instance of a bean, most commonly prototype-scoped beans. Here’s the core use case:

  • Singleton beans only get their dependencies injected once at initialization. If you inject a prototype bean directly into a singleton, you’ll only get one instance of the prototype forever—not a new one each time you need it. Lookup methods solve this by having Spring dynamically implement a method that fetches a fresh prototype instance every time you call it.
  • It’s also the fallback when scoped proxies don’t fit (like the prototype case we’ll cover next), since it directly interacts with the Spring container to retrieve new beans.

Use this when:

  • You need to get a new prototype bean instance from a singleton bean on demand.
  • Scoped proxies don’t support the bean scope you’re working with (hint: prototypes).

2. Why Don’t AOP Scoped Proxies Work for Prototype Beans?

This comes down to a fundamental mismatch between how scoped proxies operate and what prototype beans are designed to do:

  • AOP scoped proxies rely on a persistent context to retrieve existing bean instances. For request or session scopes, there’s a clear context (the current HTTP request/session) where the bean instance lives—every time you call the proxy, it looks up that existing instance in the context.
  • Prototype beans, by definition, don’t live in any persistent context. Spring creates a new prototype instance every time you ask for one (via getBean() or a lookup method). There’s no "current prototype instance" to retrieve from a context—because there is no context for prototypes.

If Spring tried to use a scoped proxy for a prototype, the proxy wouldn’t know what to do: it can’t look up an existing instance (there isn’t one), and it’s not designed to create a new instance on every method call. That’s why lookup methods are the right tool here—they explicitly tell Spring "give me a new instance every time this method is called."

Quick Code Examples to Illustrate

AOP Scoped Proxy (Request Scope → Singleton)

// Request-scoped bean with proxy enabled
@Component
@Scope(value = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS)
public class CurrentRequestBean {
    private String requestId;

    // Getters/setters for requestId
}

// Singleton bean injecting the request-scoped proxy
@Component
public class SingletonService {
    private final CurrentRequestBean currentRequestBean;

    // Constructor injection (clean, no extra code)
    public SingletonService(CurrentRequestBean currentRequestBean) {
        this.currentRequestBean = currentRequestBean;
    }

    public void logRequest() {
        // Every call here gets the instance from the current request
        System.out.println("Processing request: " + currentRequestBean.getRequestId());
    }
}

Lookup Method (Prototype → Singleton)

// Prototype bean
@Component
@Scope("prototype")
public class FreshPrototypeBean {
    private int instanceId = new Random().nextInt(1000);

    public void doWork() {
        System.out.println("Working with prototype instance: " + instanceId);
    }
}

// Singleton bean using @Lookup to get fresh prototypes
@Component
public class SingletonService {
    // Lookup method—Spring dynamically implements this to return new prototypes
    @Lookup
    protected FreshPrototypeBean getFreshPrototypeBean() {
        // Empty implementation; Spring replaces this at runtime
        return null;
    }

    public void performMultipleTasks() {
        // Each call gets a brand new prototype instance
        getFreshPrototypeBean().doWork();
        getFreshPrototypeBean().doWork();
    }
}

内容的提问来源于stack exchange,提问作者S. Najim

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 09:03:08