Learn about AOP following the previous DI. Please note that the content will be super-introductory.
AOP(Aspect-Oriented Programming)
Aspect-oriented programming is one of the concepts of development methods like object-oriented programming.
When writing a method, processing that is not directly related to what you want to do, such as logging processing and authentication processing, will be mixed in.
It is a development method to describe such auxiliary processing (concerns) separately.
For example, suppose you have the following drinkAlcohol ()
method.
➀ Start log: I'll drink!
↓
➁ Drink alcohol
↓
➂ End log: I got drunk!
In this case, ① and ③ are processes that are not directly related to the act of "drinking alcohol", so they will be described separately in different places.
Then, set ① before executing the method and ③ after execution.
Now the drinkAlcohol ()
method doesn't care about the logging process, just focus on ② "drinking" processing.
The idea of separating and modularizing auxiliary processing (concerns) in this way is called AOP. It's old, but [here](http://netail.net/aosdwiki/index.php?%A5%A2%A5%B9%A5%DA%A5%AF%A5%C8%BB%D8%B8%FE The explanation of% A5% D7% A5% ED% A5% B0% A5% E9% A5% DF% A5% F3% A5% B0) was easy to understand.
the term | meaning |
---|---|
Aspect | A summary of common processing (concerns) behavior and points to apply =A collection of Advice and Pointcut |
Advice | Separate common processing behavior The process itself that is actually executed |
JoinPoint | Timing to put advice Before or after executing a method, etc. |
PointCut | Conditions to apply Advice Conditional expression to determine whether to execute Advice when JoinPoint is reached |
Annotations are provided to set the timing of advice execution.
Annotation | timing |
---|---|
@Before | Executed before method execution |
@After | Executed after method execution Execution result does not matter |
@Around | Executed instead of the method. Processing before and after the method |
@AfterReturning | Executed when the method ends normally |
@AfterThrowing | Executed when an exception occurs in the method |
Describes the conditional expression that executes the advice. Let's take a look at the commonly used ʻexecution` format.
ʻExecution (method modifier return value package name.class name.method name (argument type) throws exception) `
Method qualifiers and throwing exceptions are optional.
@Before("execution(* com.sample..*(..))")
In the above example, it will be executed before the method under the com.sample
package is executed.
Wildcards can be used in conditional expressions.
Wildcard | meaning |
---|---|
* | Instead of any type, or part of a class or package name |
.. | Instead of any argument, or part of the class or package name |
+ | Specify all subclass and interface implementations by writing to the right of the class name and interface name |
In addition to ʻexecution`, the following directives are available.
PointCut directive | Execution condition |
---|---|
within(name of the class) | Applies to methods of the specified class |
target(name of the class) | Applies to methods of classes that inherit the specified class (applies to both parent and child classes) |
args(Argument type) | Applies to methods with arguments that match the specified arguments |
@annotation(Annotation) | 指定したAnnotationが付いているメソッドに適用 |
I tried to realize the above drinkAlcohol ()
method with AOP.
Drink.java
public class Drink {
public void drinkAlcohol() {
System.out.println("drinking...");
}
}
Do not write the logging process, but describe only (2) the process of drinking alcohol.
SampleAspect.java
@Aspect
@Component
public class SampleAspect {
@Before("execution(* com.sample..*(..))")
public void beforeDrinking() {
System.out.println("[@Before]start drinking alcohol!");
}
@After("execution(* com.sample..*(..))")
public void afterDrinking() {
System.out.println("[@After]I got drunk...zzZ");
}
}
Annotate the class with @Aspect and @Component. @Before is (1) start log and @After is (3) end log.
The execution result is as follows.
[@Before]start drinking alcohol!
drinking...
[@After]I got drunk...zzZ
Logs are output before and after the method properly.
@Around
Now, let's realize the same process with @Around.
SampleAspect.java
@Aspect
@Component
public class SampleAspect {
@Around("execution(* com.sample..*(..))")
public void aroundDrinking(ProceedingJoinPoint pjp) {
System.out.println("[@Around]start drinking alcohol!"); //All processing (➀ start log)
try {
pjp.proceed(); //Call the method (➁ drinkAlcohol())
} catch (Throwable e) {
e.printStackTrace();
}
System.out.println("[@Around]I got drunk...zzZ"); //Post-processing (➂ end log)
}
}
@Around will execute Around advice instead of the target method.
You can call the method with ProceedingJoinPoint.proceed ()
, so it feels like putting logging processing before and after that.
AOP in Spring Roughly interpret AOP used in Spring Spring Aspect Oriented Programming Spring AOP-Blog of Paper SE
Recommended Posts