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

  1. Remove the 'percflow(...)' clause from the @Aspect annotation so the aspect becomes a singleton (the default), which is all Spring AOP supports.
  2. 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.
  3. 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

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


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