πŸ› Spring AOP

GunhoΒ·2024λ…„ 11μ›” 11일
1

Object Oriented Programming (OOP) & Java

λͺ©λ‘ 보기
18/29

πŸ› Spring AOP

πŸ› Spring AOP (Aspect Oriented Programming) is a complementary feature to OOP by providing modularities in aspects than a class.

AOP strictly refers to the repetitively executing logics (cross cutting concerns) across multiple types of objects and codes, and enables these logics to become modularised individually by implementing simple annotations.

AOP enables:

  • πŸ”Ί enhanced code-readability
  • πŸ”Ί easier maintainance on cross cutting concerns

Geeks for Geeks Available at here


πŸ¦‰ AOP Concepts

Foundational AOP concepts forming AOP are:

  • @Aspect

    • modularisation of a crosscutting concerns
    • declared with @Aspect either combined with @Component or @EnableAspectJAutoProxy from @AspectJ support
  • JoinPoint

    • a point during the execution of a programme, such as the execution of a method or the handling of an exception. In Spring AOP, a JoinPoint always represents a method execution.
  • Advice

    • an action taken by an aspect at a particular JoinPoint
  • Pointcut

    • a predicate that matches JoinPoints
    • an advice is associated with a pointcut expression and runs at any JoinPoint matched by the pointcut (for example, the execution of a method with a certain name)
  • AOP Proxy

    • a proxy instance created by AOP framework to implement the aspect contracts (advice method executions and so on)
    • In the Spring Framework, an AOP proxy is a JDK dynamic proxy or a CGLIB proxy.
  • @Before

    • an advice that runs before a JoinPoint
    • has no control over the JoinPoint proceedings
  • @After

    • an advice that runs after the execution of a JoinPoint
      (if a JoinPoint ran successfully).
  • @Around

    • an advice that surrounds a JoinPoint.
    • can implement customised behaviours before & after a JoinPoint.

🧾 Pointcut Expression

Supported Pointcut designators for the Pointcut expressions are:

  • execution

    • a primary pointcut designator for Spring AOP
    • matches method execution join points with regex
  • within

    • limits matching to join points within certain types
  • this

    • limits matching to join points where the bean reference is an instance of the given type
  • target

    • limits matching to join points where the target object is an instance of the given type
  • args

    • limits matching to join points where the arguments are instances of the given types
  • @target

    • limits matching to join points where the class of the executing object has an annotation of the given type.
  • @args

    • Limits matching to join points where the runtime type of the actual arguments passed have annotations of the given types.
  • @within

    • limits matching to join points within types that have the given annotation
  • @annotation

    • limits matching to join points where the subject of the join point has the given annotation.

Pointcut Expression Pattern

The format of an execution expression follows:

execution(modifiers-pattern?
			ret-type-pattern
			declaring-type-pattern?name-pattern(param-pattern)
			throws-pattern?)

where except ret-type pattern, name-pattern, and param-pattern, all other patterns are optional.

* wildcard is often used to represent any types and each pattern is emtpy space separated except for declaring-type-pattern?name-pattern(param-pattern) where the declaring-type-pattern and name-pattern has a . dot in between.

.. is often used as a wildcard at the declaring-type-pattern and (param-pattern) levels where:

  • com.xyz..a()
    • refers to a method a present in com.xyz package and its subpackages
  • (..)
    • any parameters

The following examples show some common pointcut expressions:

  • The execution of any public method:

    execution(public * *(..))
  • The execution of any method with a name that begins with set:

    execution(* set*(..))
  • The execution of any method defined by the AccountService interface:

    execution(* com.xyz.service.AccountService.*(..))
  • The execution of any method defined in the service package:

    execution(* com.xyz.service.*.*(..))
  • The execution of any method defined in the service package or one of its sub-packages:

    execution(* com.xyz.service.*.*(..))
  • The execution of any method in classes whose names end with Service within the com.myapp package and all its sub-packages:

    execution(* com.myapp..*Service.*(..))
  • Any join point (method execution only in Spring AOP) within the service package:

    within(com.xyz.service.*)
  • Any join point (method execution only in Spring AOP) within the service package or one of its sub-packages:

    within(com.xyz.service..*)
  • Any join point (method execution only in Spring AOP) where the proxy implements the AccountService interface:

    this(com.xyz.service.AccountService)
  • Any join point (method execution only in Spring AOP) where the target object implements the AccountService interface:

    target(com.xyz.service.AccountService)
  • Any join point (method execution only in Spring AOP) that takes a single parameter and where the argument passed at runtime is Serializable:

    args(java.io.Serializable)
  • Any join point (method execution only in Spring AOP) where the target object has a @Transactional annotation:

    @target(org.springframework.transaction.annotation.Transactional)
  • Any join point (method execution only in Spring AOP) where the declared type of the target object has an @Transactional annotation:

    @within(org.springframework.transaction.annotation.Transactional)
  • Any join point (method execution only in Spring AOP) where the executing method has an @Transactional annotation:

    @annotation(org.springframework.transaction.annotation.Transactional)
  • Any join point (method execution only in Spring AOP) which takes a single parameter, and where the runtime type of the argument passed has the @Classified annotation:

    @args(com.xyz.security.Classified)

🧸 Example

Example introduces a Spring AOP that measures the start and end time of method execution defined in pointcut expressions.

Spring AOP in practice, can be implemented either via:

  • @EnableAspectJAutoProxy + @Aspect
  • @Component + @Aspect

@EnableAspectJAutoProxy + @Aspect

@Configuration
@EnableAspectJAutoProxy
public class AppConfig {
}

@Aspect
public class Aspect {
}

@Component + @Aspect

@Aspect
@Component
public class Aspect {  
}

given the above @Aspect declarations, either the advices associated with @PointCut or advices with the specified JoinPoints can be further declared followed by the Pointcut expressions:

PointCuts

@Aspect
public class Aspect {
    @Pointcut("execution(* transfer(..))") // the pointcut expression
    private void anyOldTransfer() {} // the pointcut signature
}

Advices

@Aspect
@Component
public class TimeTraceAop {

  @Before("execution(* hello.hello_spring..*(..))")
  public void beforeExecute() throws Throwable{
    long start = System.currentTimeMillis();
    System.out.println("START TIME: " + start);
  }

  @After("execution(* hello.hello_spring..*(..))")
  public void afterExecute() throws Throwable{
    long end = System.currentTimeMillis();
    System.out.println("END TIME: " + end);
  }
}
@Aspect
@Component
public class TimeTraceAop {

  @Around("execution(* hello.hello_spring..*(..))")
  public Object execute(ProceedingJoinPoint joinPoint) throws Throwable {
    long start = System.currentTimeMillis();
    System.out.println("START: " + joinPoint.toString());
    try {
      return joinPoint.proceed();
    } finally {
      long finish = System.currentTimeMillis();
      long timeMs = finish - start;
      System.out.println("END: " + joinPoint.toString() + " " + timeMs + "ms");
    }
  }
}


πŸ“š References

μŠ€ν”„λ§ μž…λ¬Έμ„ μœ„ν•œ μžλ°” 객체 μ§€ν–₯의 원리와 이해
μŠ€ν”„λ§ 핡심 원리 - 기본편 (κΉ€μ˜ν•œ)
Spring DOC
Geeks for Geeks

profile
Hello

0개의 λŒ“κΈ€