π Spring AOP (Aspect Oriented Programming)
is a complementary feature toOOP
by providingmodularities
inaspects
than aclass
.
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:
code-readability
cross cutting concerns
Geeks for Geeks Available at here
Foundational AOP concepts
forming AOP
are:
@Aspect
modularisation
of a crosscutting concerns
@Aspect
either combined with @Component
or @EnableAspectJAutoProxy
from @AspectJ support
JoinPoint
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
aspect
at a particular JoinPoint
Pointcut
predicate
that matches JoinPoints
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
proxy instance
created by AOP framework
to implement the aspect contracts
(advice method executions
and so on) Spring Framework
, an AOP proxy
is a JDK dynamic proxy
or a CGLIB proxy
.@Before
advice
that runs before a JoinPoint
JoinPoint proceedings
@After
advice
that runs after the execution of a JoinPoint
JoinPoint
ran successfully). @Around
advice
that surrounds a JoinPoint
. before
& after
a JoinPoint
.Supported Pointcut designators
for the Pointcut expressions
are:
execution
pointcut designator
for Spring AOP
method execution
join points
with regex
within
join points
within certain typesthis
join points
where the bean reference
is an instance
of the given type
target
join points
where the target object
is an instance
of the given type
args
join points
where the arguments
are instances
of the given types@target
join points
where the class
of the executing object
has an annotation
of the given type
.@args
join points
where the runtime type
of the actual arguments
passed have annotations
of the given types
.@within
join points
within types
that have the given annotation
@annotation
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()
a
present in com.xyz
package
and its subpackages
(..)
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 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");
}
}
}
μ€νλ§ μ
λ¬Έμ μν μλ° κ°μ²΄ μ§ν₯μ μ리μ μ΄ν΄
μ€νλ§ ν΅μ¬ μ리 - κΈ°λ³ΈνΈ (κΉμν)
Spring DOC
Geeks for Geeks