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

  1. Remove the percflowbelow clause and use a plain @Aspect (singleton) with ThreadLocal-based state if you need control-flow-scoped behavior.
  2. Adopt AspectJ compile-time or load-time weaving for that specific aspect if percflowbelow semantics are essential.
  3. 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

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


AI-assisted analysis of spring-projects/spring-framework@69bf83ad71 (2026-08-09). Data as JSON: /api/errors/317c0c4708f77e2c. Report an issue: GitHub.