spring-projects/spring-framework · error · AopConfigException

{} uses percflowbelow instantiation model: This is not suppo

Error message

{} uses percflowbelow instantiation model: This is not supported in Spring AOP.

What it means

Thrown by AbstractAspectJAdvisorFactory.validate() when an @AspectJ aspect declares the 'percflowbelow' instantiation model. Like percflow, this requires AspectJ's control-flow weaving machinery that Spring's runtime proxy-based AOP cannot provide. Spring AOP only supports the singleton per-clause (plus pertarget/perthis/pertypewithin with limitations).

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 e8729d0438)

Solutions

  1. Drop the 'percflowbelow(...)' per-clause so the aspect defaults to singleton instantiation.
  2. Use AspectJ compile-time or load-time weaving if percflowbelow semantics are required.
  3. Approximate with a standard pointcut expression that excludes the aspect's own join points.

Example fix

// before
@Aspect("percflowbelow(execution(* com.acme..*(..)))")
public class AuditAspect { ... }
// after
@Aspect
public class AuditAspect { ... }
Defensive patterns

Strategy: validation

Validate before calling

import org.aspectj.lang.reflect.*;

void checkNotPercflowbelow(Class<?> c) {
  PerClauseKind k = AjTypeSystem.getAjType(c).getPerClause().getKind();
  if (k == PerClauseKind.PERCFLOWBELOW)
    throw new IllegalStateException(c + " uses percflowbelow, unsupported by Spring AOP");
}

Prevention

When it happens

Trigger: Any code path invoking validate(Class) on a class annotated @Aspect("percflowbelow(execution(* com.acme..*(..)))") — e.g. AspectJProxyFactory.addAspect(Class) or auto-proxy creator processing.

Common situations: Porting a full AspectJ aspect into Spring AOP; declaring percflowbelow expecting Spring to honor it under @EnableAspectJAutoProxy.

Related errors


AI-assisted analysis of spring-projects/spring-framework@e8729d0438 (2026-08-04). Data as JSON: /data/errors/7ac77638db9d8609.json. Report an issue: GitHub.