spring-projects/spring-framework · error · IllegalStateException
CustomAutowireConfigurer needs to operate on a…
Error message
CustomAutowireConfigurer needs to operate on a DefaultListableBeanFactory
What it means
Thrown by CustomAutowireConfigurer.postProcessBeanFactory() when the BeanFactory it receives is not an instance of DefaultListableBeanFactory. CustomAutowireConfigurer must install custom qualifier types on the AutowireCandidateResolver, which is only available on DefaultListableBeanFactory. Any other BeanFactory type is incompatible.
Solutions
- Use a context backed by DefaultListableBeanFactory (GenericApplicationContext, AnnotationConfigApplicationContext, ClassPathXmlApplicationContext all use it by default).
- If using a custom BeanFactory, extend DefaultListableBeanFactory rather than implementing BeanFactory from scratch.
- Remove CustomAutowireConfigurer if custom qualifier types are not actually needed — @Qualifier works without it.
Defensive patterns
Strategy: validation
Validate before calling
// Verify the BeanFactory type before deploying CustomAutowireConfigurer
if (!(beanFactory instanceof DefaultListableBeanFactory)) {
throw new IllegalStateException(
"CustomAutowireConfigurer requires DefaultListableBeanFactory, got: "
+ beanFactory.getClass().getName());
} Type guard
// Type guard: check before using CustomAutowireConfigurer
if (beanFactory instanceof DefaultListableBeanFactory dlbf) {
CustomAutowireConfigurer configurer = new CustomAutowireConfigurer();
configurer.setCustomQualifierTypes(Set.of(MyQualifier.class));
configurer.postProcessBeanFactory(dlbf);
} else {
// use standard ApplicationContext instead
} Prevention
- Use standard Spring ApplicationContext types which are backed by DefaultListableBeanFactory.
- If using a custom context, ensure its BeanFactory extends DefaultListableBeanFactory.
- Avoid CustomAutowireConfigurer unless you truly need custom qualifier types — @Qualifier works out of the box.
When it happens
Trigger: Registering CustomAutowireConfigurer as a BeanFactoryPostProcessor in a context whose underlying BeanFactory is not a DefaultListableBeanFactory (e.g., a custom BeanFactory implementation or certain test fixtures).
Common situations: Using a custom ApplicationContext with a non-standard BeanFactory. Manually wiring CustomAutowireConfigurer against a SimpleJndiBeanFactory or StaticListableBeanFactory. Test setups with mock/custom BeanFactory implementations.
Related errors
- Invalid value [ ] for custom qualifier type: needs to be…
- Qualifier type [ ] needs to be annotation type
- ServiceLocatorFactoryBean needs to run in a BeanFactory…
- AdvisorAutoProxyCreator requires a…
- BeanFactory must be set on
AI-assisted analysis of spring-projects/spring-framework@69bf83ad71 (2026-08-09).
Data as JSON: /api/errors/cdaf4d8cf3cdda82.
Report an issue: GitHub.
Appendix: source
Thrown at spring-beans/src/main/java/org/springframework/beans/factory/annotation/CustomAutowireConfigurer.java:94
* when autowiring beans. Each element of the provided set may
* be either a Class instance or a String representation of the
* fully-qualified class name of the custom annotation.
* <p>Note that any annotation that is itself annotated with Spring's
* {@link org.springframework.beans.factory.annotation.Qualifier}
* does not require explicit registration.
* @param customQualifierTypes the custom types to register
*/
public void setCustomQualifierTypes(Set<?> customQualifierTypes) {
this.customQualifierTypes = customQualifierTypes;
}
@Override
@SuppressWarnings("unchecked")
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
if (this.customQualifierTypes != null) {
if (!(beanFactory instanceof DefaultListableBeanFactory dlbf)) {
throw new IllegalStateException(
"CustomAutowireConfigurer needs to operate on a DefaultListableBeanFactory");
}
if (!(dlbf.getAutowireCandidateResolver() instanceof QualifierAnnotationAutowireCandidateResolver)) {
dlbf.setAutowireCandidateResolver(new QualifierAnnotationAutowireCandidateResolver());
}
QualifierAnnotationAutowireCandidateResolver resolver =
(QualifierAnnotationAutowireCandidateResolver) dlbf.getAutowireCandidateResolver();
for (Object value : this.customQualifierTypes) {
Class<? extends Annotation> customType = null;
if (value instanceof Class) {
customType = (Class<? extends Annotation>) value;
}
else if (value instanceof String className) {
customType = (Class<? extends Annotation>) ClassUtils.resolveClassName(className, this.beanClassLoader);
}
else {
throw new IllegalArgumentException(
"Invalid value [" + value + "] for custom qualifier type: needs to be Class or String.");View on GitHub (pinned to 69bf83ad71)