spring-projects/spring-framework · error · IllegalArgumentException
Cannot use PrototypeAspectInstanceFactory with bean named
Error message
Cannot use PrototypeAspectInstanceFactory with bean named '{name}': not a prototype What it means
Thrown as an IllegalArgumentException from the PrototypeAspectInstanceFactory constructor when the bean named in the BeanFactory is not a prototype-scoped bean (beanFactory.isPrototype(name) returns false). This factory is designed to back perthis/pertarget aspects that must yield a fresh instance each time; using it against a singleton bean would violate those semantics, so Spring rejects the mismatch at construction.
Solutions
- Set the bean's scope to prototype: add @Scope("prototype") or scope="prototype" in XML.
- If the aspect is genuinely singleton, do not use PrototypeAspectInstanceFactory; use SingletonMetadataAwareAspectInstanceFactory instead.
- Verify the bean name passed to the constructor resolves to the intended prototype bean.
Example fix
// before
@Bean
@Aspect("perthis(execution(* com.example.Target.*(..)))")
public static PerTargetAspect perTargetAspect() { return new PerTargetAspect(); }
// PrototypeAspectInstanceFactory(beanFactory, "perTargetAspect") throws (singleton)
// after
@Bean
@Scope("prototype")
@Aspect("perthis(execution(* com.example.Target.*(..)))")
public static PerTargetAspect perTargetAspect() { return new PerTargetAspect(); } Defensive patterns
Strategy: validation
Validate before calling
import org.springframework.beans.factory.BeanFactory;
public static boolean isPrototype(BeanFactory bf, String name) {
return bf.containsBean(name) && bf.isPrototype(name);
}
// before new PrototypeAspectInstanceFactory(bf, name):
if (!isPrototype(bf, name)) {
throw new IllegalStateException("Bean '" + name + "' must be prototype-scoped");
} Type guard
import org.springframework.beans.factory.BeanFactory;
public static boolean canUsePrototypeAspectFactory(BeanFactory bf, String name) {
return bf.containsBean(name) && bf.isPrototype(name);
} Try / catch
try {
new PrototypeAspectInstanceFactory(beanFactory, name);
} catch (IllegalArgumentException ex) {
if (ex.getMessage().contains("not a prototype")) {
// set the bean scope to prototype or use SingletonMetadataAwareAspectInstanceFactory
} else throw ex;
} Prevention
- Pair PrototypeAspectInstanceFactory only with prototype-scoped beans.
- For singleton aspects, use SingletonMetadataAwareAspectInstanceFactory instead.
- Validate bean scope programmatically before constructing the factory.
When it happens
Trigger: Constructing new PrototypeAspectInstanceFactory(beanFactory, name) where the bean 'name' is singleton-scoped; BeanFactoryAspectJAdvisorsBuilder internally creating a PrototypeAspectInstanceFactory for a perthis/pertarget aspect whose bean scope was not set to prototype (companion to error 52).
Common situations: Directly instantiating PrototypeAspectInstanceFactory in framework code with a singleton bean; a misconfigured aspect where @Scope("prototype") was omitted or overridden; XML wiring pointing the factory at a singleton bean.
Related errors
- Bean with name ' ' is a singleton, but aspect instantiation…
- Advice must be declared inside an aspect type: Offending…
- 'argumentNames' property of AbstractAspectJAdvice contains…
- is not an @AspectJ aspect
- uses percflow instantiation model: This is not supported in…
AI-assisted analysis of spring-projects/spring-framework@69bf83ad71 (2026-08-09).
Data as JSON: /api/errors/2670ce9c7891b7b1.
Report an issue: GitHub.
Appendix: source
Thrown at spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/PrototypeAspectInstanceFactory.java:50
* @author Juergen Hoeller
* @since 2.0
* @see org.springframework.beans.factory.BeanFactory
* @see LazySingletonAspectInstanceFactoryDecorator
*/
@SuppressWarnings("serial")
public class PrototypeAspectInstanceFactory extends BeanFactoryAspectInstanceFactory implements Serializable {
/**
* Create a PrototypeAspectInstanceFactory. AspectJ will be called to
* introspect to create AJType metadata using the type returned for the
* given bean name from the BeanFactory.
* @param beanFactory the BeanFactory to obtain instance(s) from
* @param name the name of the bean
*/
public PrototypeAspectInstanceFactory(BeanFactory beanFactory, String name) {
super(beanFactory, name);
if (!beanFactory.isPrototype(name)) {
throw new IllegalArgumentException(
"Cannot use PrototypeAspectInstanceFactory with bean named '" + name + "': not a prototype");
}
}
}
View on GitHub (pinned to 69bf83ad71)