spring-projects/spring-framework · error · IllegalArgumentException

'target' needs to be a bean reference, not a bean name as va

Error message

'target' needs to be a bean reference, not a bean name as value

What it means

Thrown by AbstractSingletonProxyFactoryBean.afterPropertiesSet when setTarget was given a String value. Spring requires the actual target object (or a TargetSource), not the bean's name; this guard catches the classic XML mistake of using value="beanName" (which injects a literal String) instead of ref="beanName" (which injects the bean instance). It prevents silent, confusing failures downstream where the proxy would try to wrap a java.lang.String.

Source

Thrown at spring-aop/src/main/java/org/springframework/aop/framework/AbstractSingletonProxyFactoryBean.java:141

	public void setProxyClassLoader(ClassLoader classLoader) {
		this.proxyClassLoader = classLoader;
	}

	@Override
	public void setBeanClassLoader(ClassLoader classLoader) {
		if (this.proxyClassLoader == null) {
			this.proxyClassLoader = classLoader;
		}
	}


	@Override
	public void afterPropertiesSet() {
		if (this.target == null) {
			throw new IllegalArgumentException("Property 'target' is required");
		}
		if (this.target instanceof String) {
			throw new IllegalArgumentException("'target' needs to be a bean reference, not a bean name as value");
		}
		if (this.proxyClassLoader == null) {
			this.proxyClassLoader = ClassUtils.getDefaultClassLoader();
		}

		ProxyFactory proxyFactory = new ProxyFactory();

		if (this.preInterceptors != null) {
			for (Object interceptor : this.preInterceptors) {
				proxyFactory.addAdvisor(this.advisorAdapterRegistry.wrap(interceptor));
			}
		}

		// Add the main interceptor (typically an Advisor).
		proxyFactory.addAdvisor(this.advisorAdapterRegistry.wrap(createMainInterceptor()));

		if (this.postInterceptors != null) {
			for (Object interceptor : this.postInterceptors) {

View on GitHub (pinned to e8729d0438)

Solutions

  1. Change value="beanName" to ref="beanName" in the target property declaration.
  2. If configuring in Java, inject the actual bean instance: factoryBean.setTarget(context.getBean("myService")) or better, the autowired instance directly.
  3. Run a quick grep over the config for name="target" value= as a sanity check.

Example fix

// before
<property name="target" value="myService"/>

// after
<property name="target" ref="myService"/>
Defensive patterns

Strategy: type-guard

Type guard

// Guard at the boundary where you wire targets programmatically:
static void ensureTargetIsReference(Object target) {
  if (target == null) throw new IllegalArgumentException("target required");
  if (target instanceof String s) {
    throw new IllegalArgumentException(
      "'target' must be a bean reference (the instance), not the bean name '" + s + "'");
  }
}

Prevention

When it happens

Trigger: In XML, writing <property name="target" value="myService"/> instead of ref="myService"/>. Programmatically, calling factoryBean.setTarget("myServiceName") passing a String instead of the bean instance. Any path that assigns a String literal where a target object is required.

Common situations: Editors/IDEs auto-completing value= instead of ref=; converting annotations to XML and forgetting the ref semantics; beginners confusing bean name with bean reference.

Related errors


AI-assisted analysis of spring-projects/spring-framework@e8729d0438 (2026-08-04). Data as JSON: /data/errors/76caa402b4ef38b6.json. Report an issue: GitHub.