spring-projects/spring-framework · error · AopConfigException
Advice must be declared inside an aspect type: Offending met
Error message
Advice must be declared inside an aspect type: Offending method '{}' in class [{}] What it means
Thrown by ReflectiveAspectJAdvisorFactory.getAdvice() when a method carries an AspectJ advice annotation (@Before/@Around/@After/@AfterReturning/@AfterThrowing) but the declaring class is not recognized as an aspect by isAspect() (i.e. it lacks @Aspect, or it is ajc-compiled and spring.aop.ajc.ignore is on). Advice methods are only valid inside @Aspect types in Spring AOP.
Source
Thrown at spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/ReflectiveAspectJAdvisorFactory.java:257
@Override
public @Nullable Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut expressionPointcut,
MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {
Class<?> candidateAspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
validate(candidateAspectClass);
AspectJAnnotation aspectJAnnotation =
AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
if (aspectJAnnotation == null) {
return null;
}
// If we get here, we know we have an AspectJ method.
// Check that it's an AspectJ-annotated class
if (!isAspect(candidateAspectClass)) {
throw new AopConfigException("Advice must be declared inside an aspect type: " +
"Offending method '" + candidateAdviceMethod + "' in class [" +
candidateAspectClass.getName() + "]");
}
if (logger.isDebugEnabled()) {
logger.debug("Found AspectJ method: " + candidateAdviceMethod);
}
AbstractAspectJAdvice springAdvice;
switch (aspectJAnnotation.getAnnotationType()) {
case AtPointcut -> {
if (logger.isDebugEnabled()) {
logger.debug("Processing pointcut '" + candidateAdviceMethod.getName() + "'");
}
return null;
}
case AtAround -> springAdvice = new AspectJAroundAdvice(View on GitHub (pinned to e8729d0438)
Solutions
- Annotate the declaring class with @Aspect.
- If spring.aop.ajc.ignore is set and the class is ajc-compiled, unset the flag or convert the aspect to annotation style.
- Move the advice method into an existing @Aspect class.
Example fix
// before
@Component
public class AuditBean {
@Before("execution(* com.acme..*(..))") public void audit() { ... }
}
// after
@Aspect
@Component
public class AuditAspect {
@Before("execution(* com.acme..*(..))") public void audit() { ... }
} Defensive patterns
Strategy: validation
Validate before calling
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.*;
import org.springframework.core.annotation.AnnotationUtils;
import java.lang.reflect.Method;
void ensureAdviceOnlyInAspects(Class<?> c) {
for (Method m : c.getDeclaredMethods()) {
boolean hasAdvice = AnnotationUtils.findAnnotation(m, Before.class) != null
|| AnnotationUtils.findAnnotation(m, Around.class) != null
|| AnnotationUtils.findAnnotation(m, After.class) != null
|| AnnotationUtils.findAnnotation(m, AfterReturning.class) != null
|| AnnotationUtils.findAnnotation(m, AfterThrowing.class) != null;
if (hasAdvice && c.getAnnotation(Aspect.class) == null)
throw new IllegalStateException("Advice method " + m + " is not inside an @Aspect class");
}
} Prevention
- Always annotate the declaring class with @Aspect before adding advice methods.
- Lint-check via reflection that every advice-bearing method's class has @Aspect.
- Do not enable spring.aop.ajc.ignore unless you understand it hides ajc aspects from isAspect().
When it happens
Trigger: Processing a method with an advice annotation whose declaring class has no @Aspect annotation (or whose @Aspect is hidden because isAspect() returns false under the ajc-ignore flag). Reached via getAdvice() while building the advisor for such a method.
Common situations: Adding @Before to a method in a regular @Component (not @Aspect). Putting advice annotations in a utility class. Enabling spring.aop.ajc.ignore=true and then defining advice in an ajc-compiled class. Meta-annotating without the actual @Aspect.
Related errors
- MethodInvocation is not a Spring ProxyMethodInvocation: {}
- 'argumentNames' property of AbstractAspectJAdvice contains a
- Only afterReturning advice can be used to bind a return valu
- Only afterThrowing advice can be used to bind a thrown excep
- Advice method [{}] requires {} arguments to be bound by name
AI-assisted analysis of spring-projects/spring-framework@e8729d0438 (2026-08-04).
Data as JSON: /data/errors/8893a7b329d76d10.json.
Report an issue: GitHub.