The AspectJ runtime is a small library necessary to run Java programs enhanced by AspectJ aspects during a previous compile-time or post-compile-time (binary weaving) build step.
—
Complete set of annotations for defining aspects using the @AspectJ syntax. This annotation-based approach allows aspects to be written as regular Java classes with special annotations, making them compatible with standard Java development tools and frameworks. Supports all AspectJ language features including advice, pointcuts, inter-type declarations, and aspect instantiation models.
Declares a class as an aspect with optional instantiation model specification.
/**
* Aspect declaration
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Aspect {
/**
* The per clause expression, defaults to singleton aspect.
* Valid values are "" (singleton), "perthis(...)", "pertarget(...)",
* "pertypewithin(...)", "percflow(...)", "percflowbelow(...)"
*/
String value() default "";
}Usage Examples:
// Singleton aspect (default)
@Aspect
public class LoggingAspect {
// aspect implementation
}
// Per-object aspect
@Aspect("perthis(execution(* com.example.service.*.*(..)))")
public class ServiceMonitorAspect {
// per-instance state and behavior
}
// Per-type-within aspect
@Aspect("pertypewithin(com.example.model.*)")
public class EntityAuditAspect {
// per-type state and behavior
}Declares a named pointcut that can be referenced by advice and other pointcuts.
/**
* Pointcut declaration
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Pointcut {
/**
* The pointcut expression. Can be empty for abstract pointcuts.
*/
String value() default "";
/**
* Argument names for runtime interpretation when debug info is not available.
* Format is a simple comma-separated list.
*/
String argNames() default "";
}Usage Examples:
@Aspect
public class SecurityAspect {
@Pointcut("execution(* com.example.service.*.*(..))")
public void serviceLayer() {}
@Pointcut("@annotation(com.example.security.Secured)")
public void securedMethods() {}
@Pointcut("serviceLayer() && securedMethods()")
public void securedServiceMethods() {}
@Pointcut("execution(* *.save*(..)) && args(entity)")
public void saveOperations(Object entity) {}
}Declares before advice that executes before join point execution.
/**
* Before advice
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Before {
/**
* The pointcut expression where to bind the advice
*/
String value();
/**
* Argument names for runtime interpretation when debug info is not available
*/
String argNames() default "";
}Declares after advice that executes after join point completion (finally behavior).
/**
* After advice (after finally)
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface After {
/**
* The pointcut expression where to bind the advice
*/
String value();
/**
* Argument names for runtime interpretation when debug info is not available
*/
String argNames() default "";
}Declares after returning advice that executes after successful join point completion.
/**
* After returning advice
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface AfterReturning {
/**
* The pointcut expression where to bind the advice
*/
String value() default "";
/**
* Alternative pointcut expression, overrides "value" when specified
*/
String pointcut() default "";
/**
* The name of the argument in the advice signature to bind the returned value to
*/
String returning() default "";
/**
* Argument names for runtime interpretation when debug info is not available
*/
String argNames() default "";
}Declares after throwing advice that executes when join point throws an exception.
/**
* After throwing advice
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface AfterThrowing {
/**
* The pointcut expression where to bind the advice
*/
String value() default "";
/**
* Alternative pointcut expression, overrides "value" when specified
*/
String pointcut() default "";
/**
* The name of the argument in the advice signature to bind the thrown exception to
*/
String throwing() default "";
/**
* Argument names for runtime interpretation when debug info is not available
*/
String argNames() default "";
}Declares around advice that can control join point execution.
/**
* Around advice
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Around {
/**
* The pointcut expression where to bind the advice
*/
String value();
/**
* Argument names for runtime interpretation when debug info is not available
*/
String argNames() default "";
}Complete Advice Usage Example:
@Aspect
public class ComprehensiveLoggingAspect {
@Pointcut("execution(* com.example.service.*.*(..))")
public void serviceLayer() {}
@Before("serviceLayer()")
public void logBefore(JoinPoint joinPoint) {
System.out.println("==> Entering: " + joinPoint.getSignature().toShortString());
}
@AfterReturning(pointcut = "serviceLayer()", returning = "result")
public void logAfterReturning(JoinPoint joinPoint, Object result) {
System.out.println("<== Successfully returned from: " +
joinPoint.getSignature().toShortString() +
" with result: " + result);
}
@AfterThrowing(pointcut = "serviceLayer()", throwing = "ex")
public void logAfterThrowing(JoinPoint joinPoint, Throwable ex) {
System.out.println("*** Exception in: " +
joinPoint.getSignature().toShortString() +
" - " + ex.getMessage());
}
@After("serviceLayer()")
public void logAfter(JoinPoint joinPoint) {
System.out.println("--- Completed: " + joinPoint.getSignature().toShortString());
}
@Around("serviceLayer()")
public Object logAround(ProceedingJoinPoint pjp) throws Throwable {
long start = System.currentTimeMillis();
try {
Object result = pjp.proceed();
long duration = System.currentTimeMillis() - start;
System.out.println("Executed " + pjp.getSignature().toShortString() +
" in " + duration + " ms");
return result;
} catch (Throwable t) {
long duration = System.currentTimeMillis() - start;
System.out.println("Failed " + pjp.getSignature().toShortString() +
" after " + duration + " ms");
throw t;
}
}
}Declares inter-type declarations (mixins) for adding interfaces and implementations to existing types.
/**
* Declare parents mixin annotation
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface DeclareParents {
/**
* The target types expression (type pattern)
*/
String value();
/**
* Optional class defining default implementation of interface members.
* Equivalent to defining a set of interface member ITDs for the
* public methods of the interface.
*/
Class defaultImpl() default DeclareParents.class;
}Usage Examples:
@Aspect
public class MixinAspect {
// Add Auditable interface to all model classes
@DeclareParents(value = "com.example.model.*", defaultImpl = AuditableImpl.class)
private Auditable auditableIntroduction;
// Add Cacheable interface without implementation (must be implemented elsewhere)
@DeclareParents("com.example.service.*")
private Cacheable cacheableIntroduction;
}
public interface Auditable {
void setLastModified(Date date);
Date getLastModified();
void setModifiedBy(String user);
String getModifiedBy();
}
public class AuditableImpl implements Auditable {
private Date lastModified;
private String modifiedBy;
public void setLastModified(Date date) { this.lastModified = date; }
public Date getLastModified() { return lastModified; }
public void setModifiedBy(String user) { this.modifiedBy = user; }
public String getModifiedBy() { return modifiedBy; }
}Declare compile-time errors and warnings for specific join points.
/**
* Declare compile-time error
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface DeclareError {
/**
* The pointcut expression where to trigger the error
*/
String value();
}
/**
* Declare compile-time warning
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface DeclareWarning {
/**
* The pointcut expression where to trigger the warning
*/
String value();
}Usage Examples:
@Aspect
public class ComplianceAspect {
@DeclareError("call(* java.sql.Connection.createStatement(..))")
public static final String NO_DIRECT_SQL =
"Direct SQL statements are prohibited - use prepared statements";
@DeclareWarning("execution(* com.example.*.*(..)) && !@annotation(Deprecated)")
public static final String MISSING_DOCUMENTATION =
"Public methods should have proper documentation";
}Provides explicit names for advice methods to improve debugging and profiling.
/**
* Names advice for better debugging/profiling
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface AdviceName {
/**
* The name for the advice
*/
String value();
}Suppresses AspectJ compiler warnings for specific advice or aspects.
/**
* Suppress AspectJ compiler warnings
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
public @interface SuppressAjWarnings {
/**
* Warning types to suppress
*/
String[] value();
}Usage Examples:
@Aspect
public class OptimizedAspect {
@AdviceName("performanceTracker")
@Around("execution(* com.example.critical.*.*(..))")
public Object trackPerformance(ProceedingJoinPoint pjp) throws Throwable {
// Performance tracking logic
return pjp.proceed();
}
@SuppressAjWarnings({"adviceDidNotMatch", "uncheckedArgTypes"})
@Before("call(* com.legacy..*.*(..))")
public void handleLegacyCall() {
// Legacy integration code that may trigger warnings
}
}When compiling without debug information or interpreting pointcuts at runtime, argument names must be explicitly provided:
@Aspect
public class ArgumentBindingAspect {
@Before(value = "execution(* com.example.service.*.save(..)) && args(entity, options)",
argNames = "entity,options")
public void validateSave(Object entity, Map<String, Object> options) {
// Validation logic
}
@AfterReturning(pointcut = "execution(* com.example.service.*.find(..))",
returning = "result",
argNames = "result")
public void logResult(Object result) {
// Result logging
}
}@AspectJ aspects are regular Java classes and can:
@Aspect
@Component // Spring annotation
@Transactional // JPA annotation
public class IntegratedAspect {
@Autowired
private AuditService auditService;
@PostConstruct
public void initialize() {
System.out.println("Aspect initialized");
}
@Before("@annotation(Audited)")
public void auditOperation(JoinPoint joinPoint) {
auditService.recordOperation(joinPoint.getSignature().getName());
}
}Install with Tessl CLI
npx tessl i tessl/maven-org-aspectj--aspectjrt