spring-projects/spring-framework · error · AopConfigException
{} uses percflow instantiation model: This is not supported
Error message
{} uses percflow instantiation model: This is not supported in Spring AOP. What it means
Thrown by AbstractAspectJAdvisorFactory.validate() when an @AspectJ aspect declares the 'percflow' instantiation model (e.g. @Aspect("percflow(...)")). Spring AOP is proxy-based and runtime-only, so it cannot implement AspectJ's control-flow-scoped aspect instantiation, which requires bytecode weaving. Only singleton (default) and, with caveats, pertarget/perthis/pertypewithin models are supported. Use AspectJ load-time or compile-time weaving (ajc) instead if you truly need percflow semantics.
Source
Thrown at spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/AbstractAspectJAdvisorFactory.java:100
protected final Log logger = LogFactory.getLog(getClass());
protected final ParameterNameDiscoverer parameterNameDiscoverer = new AspectJAnnotationParameterNameDiscoverer();
@Override
public boolean isAspect(Class<?> clazz) {
return (AnnotationUtils.findAnnotation(clazz, Aspect.class) != null &&
(!shouldIgnoreAjcCompiledAspects || !compiledByAjc(clazz)));
}
@Override
public void validate(Class<?> aspectClass) throws AopConfigException {
AjType<?> ajType = AjTypeSystem.getAjType(aspectClass);
if (!ajType.isAspect()) {
throw new NotAnAtAspectException(aspectClass);
}
if (ajType.getPerClause().getKind() == PerClauseKind.PERCFLOW) {
throw new AopConfigException(aspectClass.getName() + " uses percflow instantiation model: " +
"This is not supported in Spring AOP.");
}
if (ajType.getPerClause().getKind() == PerClauseKind.PERCFLOWBELOW) {
throw new AopConfigException(aspectClass.getName() + " uses percflowbelow instantiation model: " +
"This is not supported in Spring AOP.");
}
}
/**
* Find and return the first AspectJ annotation on the given method
* (there <i>should</i> only be one anyway...).
*/
@SuppressWarnings("unchecked")
protected static @Nullable AspectJAnnotation findAspectJAnnotationOnMethod(Method method) {
for (Class<?> annotationType : ASPECTJ_ANNOTATION_CLASSES) {
AspectJAnnotation annotation = findAnnotation(method, (Class<Annotation>) annotationType);
if (annotation != null) {View on GitHub (pinned to e8729d0438)
Solutions
- Remove the 'percflow(...)' clause from the @Aspect annotation so the aspect becomes a singleton (the default), which is all Spring AOP supports.
- If percflow semantics are genuinely required, switch to AspectJ compile-time weaving (ajc) or load-time weaving (spring-instrument + aop.xml) and remove the aspect from Spring auto-proxying.
- Re-express the cflow condition as a regular pointcut expression on a singleton advice method (approximation only; not true control-flow scoping).
Example fix
// before
@Aspect("percflow(execution(* com.acme..*(..)))")
public class CflowAspect {
@Before("execution(* com.acme..*(..))") public void check() { ... }
}
// after (Spring AOP compatible)
@Aspect
public class CflowAspect {
@Before("execution(* com.acme..*(..))") public void check() { ... }
} Defensive patterns
Strategy: validation
Validate before calling
import org.aspectj.lang.reflect.AjType;
import org.aspectj.lang.reflect.AjTypeSystem;
import org.aspectj.lang.reflect.PerClauseKind;
void ensureSpringAopCompatible(Class<?> aspectClass) {
AjType<?> t = AjTypeSystem.getAjType(aspectClass);
PerClauseKind k = t.getPerClause().getKind();
if (k == PerClauseKind.PERCFLOW) {
throw new IllegalStateException(
aspectClass + " uses percflow; switch to singleton or use AspectJ weaving.");
}
} Prevention
- Restrict Spring AOP aspects to the default singleton per-clause; never use percflow/percflowbelow.
- Keep AspectJ-native aspects in a separate module woven by ajc, not processed by @EnableAspectJAutoProxy.
- Add a startup smoke test that validates all @Aspect beans via AbstractAspectJAdvisorFactory.validate().
When it happens
Trigger: Calling AspectJProxyFactory.addAspect(), registering an aspect bean processed by AnnotationAwareAspectJAutoProxyCreator, or any path that invokes validate(Class) on a class whose AjType per-clause kind resolves to PerClauseKind.PERCFLOW. This happens when the aspect source carries @Aspect("percflow(execution(* com.acme.*.*(..)))").
Common situations: Copying an AspectJ-native aspect (designed for ajc weaving) into a Spring app that only enables @AspectJ auto-proxying. Migrating from full AspectJ to Spring AOP without rewriting the per-clause. Using @EnableAspectJAutoProxy and expecting full AspectJ language coverage.
Related errors
- {} uses percflowbelow instantiation model: This is not suppo
- PerClause {} not supported by Spring AOP for {}
- MethodInvocation is not a Spring ProxyMethodInvocation: {}
- 'argumentNames' property of AbstractAspectJAdvice contains a
- Only afterReturning advice can be used to bind a return valu
AI-assisted analysis of spring-projects/spring-framework@e8729d0438 (2026-08-04).
Data as JSON: /data/errors/b87649c79d2c4600.json.
Report an issue: GitHub.