spring-projects/spring-framework · error · IllegalStateException

Cannot invoke instance method without factoryBeanName: {}

Error message

Cannot invoke instance method without factoryBeanName: {}

What it means

When BeanInstanceSupplier.instantiate invokes a factory method that is an instance (non-static) method, it needs a factory-bean instance to call it on. The factory bean name is taken from the merged bean definition's factoryBeanName; if that is null for a non-static method, Spring cannot determine the receiver and throws IllegalStateException.

Source

Thrown at spring-beans/src/main/java/org/springframework/beans/factory/aot/BeanInstanceSupplier.java:361

	}

	private Object instantiate(RegisteredBean registeredBean, Executable executable, @Nullable Object[] args) {
		if (executable instanceof Constructor<?> constructor) {
			if (registeredBean.getBeanFactory() instanceof DefaultListableBeanFactory dlbf &&
					registeredBean.getMergedBeanDefinition().hasMethodOverrides()) {
				return dlbf.getInstantiationStrategy().instantiate(registeredBean.getMergedBeanDefinition(),
						registeredBean.getBeanName(), registeredBean.getBeanFactory());
			}
			return BeanUtils.instantiateClass(constructor, args);
		}
		if (executable instanceof Method method) {
			Object target = null;
			String factoryBeanName = registeredBean.getMergedBeanDefinition().getFactoryBeanName();
			if (factoryBeanName != null) {
				target = registeredBean.getBeanFactory().getBean(factoryBeanName, method.getDeclaringClass());
			}
			else if (!Modifier.isStatic(method.getModifiers())) {
				throw new IllegalStateException("Cannot invoke instance method without factoryBeanName: " + method);
			}
			try {
				ReflectionUtils.makeAccessible(method);
				return method.invoke(target, args);
			}
			catch (Throwable ex) {
				throw new BeanInstantiationException(method, ex.getMessage(), ex);
			}
		}
		throw new IllegalStateException("Unsupported executable " + executable.getClass().getName());
	}


	private static String toCommaSeparatedNames(Class<?>... parameterTypes) {
		return Arrays.stream(parameterTypes).map(Class::getName).collect(Collectors.joining(", "));
	}

View on GitHub (pinned to e8729d0438)

Solutions

  1. Set the factory-bean/factoryBeanName on the bean definition to the bean that owns the instance factory method.
  2. Alternatively make the factory method static so no receiver is needed.
  3. If using programmatic BeanDefinitionBuilder, call .factoryBean("factoryBeanName").factoryMethod("method").

Example fix

// before
BeanDefinitionBuilder.rootBeanDefinition(Svc.class).factoryMethod("create"); // create() is non-static
// after
BeanDefinitionBuilder.rootBeanDefinition(Svc.class)
  .factoryBean("svcFactory").factoryMethod("create");
Defensive patterns

Strategy: validation

Validate before calling

RootBeanDefinition bd = registeredBean.getMergedBeanDefinition();
if (bd.getFactoryMethodName() != null) {
  Method m = findFactoryMethod(bd);
  if (!Modifier.isStatic(m.getModifiers()) && bd.getFactoryBeanName() == null) {
    throw new IllegalStateException("Instance factory method needs factoryBeanName: " + m);
  }
}

Type guard

boolean factoryMethodResolvable(RootBeanDefinition bd, Method m) {
  return Modifier.isStatic(m.getModifiers()) || bd.getFactoryBeanName() != null;
}

Prevention

When it happens

Trigger: A bean defined with an instance factory-method but no factory-bean (or factoryBeanName resolved to null), encountered during AOT instance-supplier execution at runtime.

Common situations: Programmatic bean registration that sets a factory method via setFactoryMethodName on a non-static method but forgets setFactoryBeanName; XML config with factory-method but a missing or misspelled factory-bean attribute; refactoring that made a static factory method non-static without adding a factory-bean.

Related errors


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