skip to content

Contrast XML <lookup-method> and <replaced-method>. What is the MethodReplacer interface and how do they relate to CGLIB?

level: seniorimportance: should knowfreq 34%

answer

  1. <lookup-method> = XML @Lookup, returns named bean each call
  2. <replaced-method> = swap whole body via MethodReplacer
  3. reimplement(obj, method, args)
  4. <arg-type> disambiguates overloads
  5. both = CGLIB subclass, non-final required

basics

~10 s

<lookup-method> makes Spring override a method to return a named bean each call — the XML form of @Lookup. <replaced-method> swaps a method's whole implementation with a MethodReplacer bean. Both use CGLIB subclassing.

solid answer

~40 s

Both are XML method-injection features implemented by generating a **CGLIB subclass** of the target bean. `<lookup-method name="createX" bean="xPrototype"/>` overrides `createX()` so each call returns a fresh lookup of bean `xPrototype` — it is exactly the XML equivalent of `@Lookup`, aimed at pulling prototypes into singletons. `<replaced-method name="m" replacer="myReplacer"/>` is more general: it replaces the **entire body** of any method `m` with the logic of a Spring bean implementing `org.springframework.beans.factory.support.MethodReplacer`, whose single method `Object reimplement(Object obj, Method method, Object[] args)` runs instead of the original. It isn't limited to returning beans — you can rewrite arbitrary behavior. Overloaded methods are disambiguated with nested `<arg-type>` elements. Both require the class and method to be non-final so CGLIB can override them. `<replaced-method>` is rarely used today; `<lookup-method>`/`@Lookup` cover the common prototype-injection case.

go deeper

for a junior

Aware <lookup-method> exists as the XML form of @Lookup.

for a middle

Can explain <lookup-method> returns a fresh named bean per call via CGLIB.

for a senior

Must distinguish <replaced-method> + MethodReplacer.reimplement and <arg-type> overload handling, and the shared CGLIB/non-final constraints.

for a principal

Should position both below AOP and advise modern alternatives (ObjectProvider, strategy beans, aspects).

## Two XML method-injection tools Spring's XML configuration offers two ways to have the container override a bean method at runtime. Both are implemented the same way — Spring uses **CGLIB** to create a dynamic **subclass** of your bean and overrides the target method. ### 1. `<lookup-method>` — the XML twin of @Lookup ```xml <bean id="reportService" class="com.acme.ReportService"> <lookup-method name="newBuilder" bean="reportBuilder"/> </bean> <bean id="reportBuilder" class="com.acme.ReportBuilder" scope="prototype"/> ``` - `name` = the method to override (typically abstract or a no-arg concrete method). - `bean` = the bean id to return on each invocation. Spring overrides `newBuilder()` to do `getBean("reportBuilder")`, so a **fresh prototype** is returned every call. This is the classic 'prototype into singleton' fix — identical in effect to `@Lookup`, just expressed in XML. ### 2. `<replaced-method>` — arbitrary method replacement ```xml <bean id="myBean" class="com.acme.MyBean"> <replaced-method name="compute" replacer="computeReplacer"> <arg-type>java.lang.String</arg-type> </replaced-method> </bean> <bean id="computeReplacer" class="com.acme.ComputeReplacer"/> ``` ```java public class ComputeReplacer implements MethodReplacer { @Override public Object reimplement(Object obj, Method method, Object[] args) { // runs INSTEAD of MyBean.compute(...) return "replaced:" + args[0]; } } ``` - `replacer` = a bean implementing **`org.springframework.beans.factory.support.MethodReplacer`**. - `MethodReplacer` has one method: `Object reimplement(Object obj, Method method, Object[] args)`, receiving the target instance, the reflected `Method`, and the call arguments; whatever it returns becomes the method's result. - `<arg-type>` disambiguates **overloaded** methods (you can list one or more argument type fragments; substring matching is allowed). Unlike `<lookup-method>`, `<replaced-method>` is **not** about returning a bean — it lets you substitute *any* logic for a method. It is effectively a lightweight, container-native form of method interception without full AOP. ## How they compare | Aspect | `<lookup-method>` / `@Lookup` | `<replaced-method>` | |---|---|---| | Purpose | Return a fresh (usually prototype) bean per call | Replace a method's entire implementation | | Body source | Container `getBean` | Your `MethodReplacer` bean | | Return value | The looked-up bean | Whatever `reimplement` returns | | Overload handling | n/a (usually no-arg) | `<arg-type>` elements | | Annotation form | `@Lookup` | none (XML only) | | Typical use today | Common | Rare | ## Shared mechanics and constraints - Both generate a **CGLIB subclass**, so the class and the overridden method must be **non-final** (and not `private`/`static`), and the class must be instantiable. - Because a subclass is created, the bean instance you receive is a CGLIB-enhanced subtype. - These sit below full Spring AOP: they're bean-definition-level overrides, not aspect weaving. ## When to reach for each - Need a prototype inside a singleton, XML config → `<lookup-method>` (or `@Lookup` in annotations). - Need to swap a method's behavior without editing the class or writing an aspect (legacy XML apps) → `<replaced-method>`. In modern code this is almost always better handled by AOP, a strategy bean, or plain composition.

  • Why would you need <arg-type> in a <replaced-method> declaration?
    To disambiguate overloaded methods that share a name but differ in parameter types. <arg-type> pins the replacement to the specific overload by naming its argument type(s).
  • Is <replaced-method> the same as Spring AOP method interception?
    No. It's a bean-definition-level CGLIB override that replaces the whole method body with a MethodReplacer. AOP weaves advice around a join point and supports pointcuts, ordering, and proceed(); <replaced-method> is a simpler, coarser total replacement.

saying these in an interview costs you the question

  • Confusing <replaced-method> with AOP around advice
  • Thinking <replaced-method> can only return beans (it can return anything)
  • Not knowing MethodReplacer.reimplement's signature
  • Claiming these use JDK dynamic proxies instead of CGLIB

context