spring-projects/spring-framework · error · IllegalStateException

No BeanFactory available anymore (probably due to serializat

Error message

No BeanFactory available anymore (probably due to serialization) - cannot resolve target with name '{targetName}'

What it means

freshTargetSource() must call getBean(targetName) to resolve the target. If beanFactory is null (transient field lost to serialization), it cannot resolve and throws IllegalStateException naming targetName. This path is taken only when the target was supplied via the trailing interceptorNames entry (stored into targetName) rather than as an explicit target/targetSource property.

Source

Thrown at spring-aop/src/main/java/org/springframework/aop/framework/ProxyFactoryBean.java:536

		// We need to convert to an Advisor if necessary so that our source reference
		// matches what we find from superclass interceptors.
		addAdvisor(namedBeanToAdvisor(next));
	}

	/**
	 * Return a TargetSource to use when creating a proxy. If the target was not
	 * specified at the end of the interceptorNames list, the TargetSource will be
	 * this class's TargetSource member. Otherwise, we get the target bean and wrap
	 * it in a TargetSource if necessary.
	 */
	private TargetSource freshTargetSource() {
		if (this.targetName == null) {
			// Not refreshing target: bean name not specified in 'interceptorNames'
			return this.targetSource;
		}
		else {
			if (this.beanFactory == null) {
				throw new IllegalStateException("No BeanFactory available anymore (probably due to serialization) " +
						"- cannot resolve target with name '" + this.targetName + "'");
			}
			if (logger.isDebugEnabled()) {
				logger.debug("Refreshing target with name '" + this.targetName + "'");
			}
			Object target = this.beanFactory.getBean(this.targetName);
			return (target instanceof TargetSource targetSource ? targetSource : new SingletonTargetSource(target));
		}
	}

	/**
	 * Convert the following object sourced from calling getBean() on a name in the
	 * interceptorNames array to an Advisor or TargetSource.
	 */
	private Advisor namedBeanToAdvisor(Object next) {
		try {
			return this.advisorAdapterRegistry.wrap(next);
		}

View on GitHub (pinned to e8729d0438)

Solutions

  1. Set target explicitly via setTarget/setTargetSource instead of via the trailing interceptorNames entry so it is carried as serializable state.
  2. Do not serialize prototype ProxyFactoryBean; re-resolve from the context after deserialization.
  3. Use singleton scope to avoid freshTargetSource() being invoked.

Example fix

// before
<property name="interceptorNames" value="myAdvice,myTarget"/>

// after
<property name="interceptorNames" value="myAdvice"/>
<property name="targetName" value="myTarget"/>
// or set target directly: <property name="target" ref="myTarget"/>
Defensive patterns

Strategy: validation

Validate before calling

if (pfb.getBeanFactory() == null && pfb.getTargetName() != null) {
    throw new IllegalStateException("Cannot resolve target by name post-serialization; set target explicitly.");
}

Prevention

When it happens

Trigger: ProxyFactoryBean configured with target as the last interceptorNames entry, then serialized, then asked for a fresh target source (e.g. prototype proxy instantiation) on the deserialized instance.

Common situations: Session replication / distributed caching of prototype ProxyFactoryBean whose target is named in interceptorNames; remoting scenarios where the bean factory is not reattached.

Related errors


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