spring-projects/spring-framework · error · AopConfigException
{aspectClass.getName()} uses percflowbelow instantiation mod
Error message
{aspectClass.getName()} uses percflowbelow instantiation model: This is not supported in Spring AOP. What it means
Thrown by AbstractAspectJAdvisorFactory.validate() as an AopConfigException when the aspect's per-clause kind is PerClauseKind.PERCFLOWBELOW. Like percflow, percflowbelow (one aspect instance per control-flow-below a pointcut) is unsupported by Spring AOP's proxy mechanism and requires native AspectJ weaving. This is the companion guard to the percflow check.
Source
Thrown at spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/AbstractAspectJAdvisorFactory.java:104
@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) {
return annotation;
}
}
return null;View on GitHub (pinned to 69bf83ad71)
Solutions
- Remove the percflowbelow clause and use a plain @Aspect (singleton) with ThreadLocal-based state if you need control-flow-scoped behavior.
- Adopt AspectJ compile-time or load-time weaving for that specific aspect if percflowbelow semantics are essential.
- Isolate unsupported aspects into a separate module that uses AspectJ weaving, not the Spring AOP auto-proxy.
Example fix
// before
@Aspect("percflowbelow(execution(* com.example.Service.*(..)))")
public class BelowFlowAspect { ... }
// after
@Aspect
public class BelowFlowAspect {
@Around("execution(* com.example.Service.*(..))")
public Object profile(ProceedingJoinPoint pjp) throws Throwable { ... }
} Defensive patterns
Strategy: validation
Validate before calling
import org.aspectj.lang.reflect.AjTypeSystem;
import org.aspectj.lang.reflect.PerClauseKind;
public static boolean isSpringAopCompatible(Class<?> aspectClass) {
var kind = AjTypeSystem.getAjType(aspectClass).getPerClause().getKind();
return kind != PerClauseKind.PERCFLOWBELOW && kind != PerClauseKind.PERCFLOW;
}
if (!isSpringAopCompatible(MyAspect.class)) {
throw new IllegalStateException("Aspect uses percflowbelow, unsupported by Spring AOP");
} Type guard
import org.aspectj.lang.reflect.AjTypeSystem;
import org.aspectj.lang.reflect.PerClauseKind;
public static boolean isPercflowbelow(Class<?> c) {
return AjTypeSystem.getAjType(c).getPerClause().getKind() == PerClauseKind.PERCFLOWBELOW;
} Try / catch
try {
advisorFactory.validate(aspectClass);
} catch (AopConfigException ex) {
if (ex.getMessage().contains("percflowbelow")) {
// adopt AspectJ weaving or rewrite as singleton
} else throw ex;
} Prevention
- Reserve control-flow-scoped aspects for AspectJ weaving modules, not Spring AOP modules.
- Static-analyze aspect annotations to flag percflow/percflowbelow in Spring AOP modules.
- Prefer ThreadLocal-based state in singleton aspects over per-flow instantiation.
When it happens
Trigger: Annotating a class with @Aspect("percflowbelow(pointcut)") and exposing it to Spring AOP auto-proxying or AspectJProxyFactory; calling validate() on the class.
Common situations: Using an aspect designed for native AspectJ weaving in a Spring-managed context; migrating from full AspectJ to Spring AOP without rewriting the per-clause; copying aspect definitions from AspectJ documentation.
Related errors
- {aspectClass.getName()} uses percflow instantiation model: T
- PerClause {ajType.getPerClause().getKind()} not supported by
- Bean with name '{beanName}' is a singleton, but aspect insta
- '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@69bf83ad71 (2026-08-09).
Data as JSON: /api/errors/317c0c4708f77e2c.
Report an issue: GitHub.