AOP Core Concepts
还记得我们Spring有两个核心的概念嘛?一个是IOC/DI,另一个是AOP咯。
Let's first understand two concepts:
- AOP (Aspect Oriented Programming) aspect-oriented programming; function: to enhance its function without disturbing the original design, similar to the proxy mode.
- OOP (Object Oriented Programming) object-oriented programming
- Join Point (JoinPoint): Any position in the program execution process, the granularity is executing methods, throwing exceptions, setting variables, etc. In Spring AOP, it is understood as the execution of methods
- Pointcut: Match the expression of the connection point. In Spring AOP, a pointcut can describe a specific method, or it can also match multiple methods
- A specific method: such as the save method with no formal parameters and no return value in the BookDao interface under the com.iheima.dao package
- Matches multiple methods: all save methods, all methods starting with get, any method in any interface ending with Dao, all methods with one parameter
- The scope of the connection point is larger than that of the entry point. The method that is the entry point must also be the connection point, but the method that is the connection point does not have to be enhanced, so it may not be the entry point.
- Advice: The operation performed at the entry point, that is, the common function. In Spring AOP, the function is finally presented in the form of a method
- Notification class: the class that defines the notification
- Aspect: Describes the correspondence between notifications and entry points.
- Advice: Enhanced handling in the AOP framework. Advice describes when the aspect is executed and how to perform enhancement processing.
- Join point: A join point represents a point in the process of application execution where an aspect can be inserted. This point can be a method call or an exception thrown. In Spring AOP, a join point is always a method invocation.
- PointCut: Join points for enhanced processing can be inserted.
- Aspect: An aspect is a combination of advice and pointcut.
Knowledge point 1: @EnableAspectJAutoProxy
name | @EnableAspectJAutoProxy |
---|---|
type | Configuration class annotation |
Location | Above the configuration class definition |
effect | Enable annotation format AOP function |
Knowledge point 2: @Aspect
name | @Aspect |
---|---|
type | class annotation |
Location | Above the aspect class definition |
effect | Set the current class as an AOP aspect class |
Knowledge point 3: @Pointcut
name | @Pointcut |
---|---|
type | method annotation |
Location | above the pointcut method definition |
effect | Set pointcut method |
Attributes | value (default): pointcut expression |
Knowledge point 4: @Before
name | @Before |
---|---|
type | method annotation |
Location | notification method definition above |
effect | Set the binding relationship between the current advice method and the pointcut, the current advice method runs before the original pointcut method |
AOP example
project preparation
Create a Maven project
-
pom.xml adds Spring dependency
<dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.2.10.RELEASE</version> </dependency> </dependencies>
-
Add BookDao and BookDaoImpl classes
public interface BookDao { public void save(); public void update(); } @Repository public class BookDaoImpl implements BookDao { public void save() { System.out.println(System.currentTimeMillis()); System.out.println("book dao save ..."); } public void update(){ System.out.println("book dao update ..."); } }
-
Create a Spring configuration class
@Configuration @ComponentScan("com.taro") public class SpringConfig { }
-
Write App running class
public class App { public static void main(String[] args) { ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class); BookDao bookDao = ctx.getBean(BookDao.class); bookDao.save(); } }
Implementation function description:
- At present, when printing the save method, because the system time is printed in the method, the system time can be seen when running
- For the update method, there is no such function
- We want to use the Spring AOP method to allow it to print the system time without changing the update method.
Specific AOP operation steps
Step 1: Add dependencies
pom.xml
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.4</version>
</dependency>
- Because
spring-context
it has already been importedspring-aop
, there is no need to import it separatelyspring-aop
- Import the jar package of AspectJ, AspectJ is a concrete implementation of AOP thought, Spring has its own AOP implementation, but compared to AspectJ, it is more troublesome, so we directly use Spring to integrate ApsectJ for AOP development.
Step 2: Define the interface and implementation class
环境准备的时候,BookDaoImpl已经准备好,不需要做任何修改
Step 3: Define notification classes and notifications
Notification is a method formed by extracting common functions. The common function refers to the printing of the current system time.
public class MyAdvice {
public void method(){
System.out.println(System.currentTimeMillis());
}
}
The class name and method name are not required and can be arbitrary.
Step 4: Define the entry point
There are two methods in BookDaoImpl, namely save and update. What we want to enhance is the update method. How to define it?
public class MyAdvice {
@Pointcut("execution(void com.taro.dao.BookDao.update())")
private void pt(){
}
public void method(){
System.out.println(System.currentTimeMillis());
}
}
illustrate:
- The pointcut definition relies on a method that has no practical significance, that is, no parameters, no return value, and no actual logic in the method body.
Step 5: Make the cut sides
The aspect is used to describe the relationship between the notification and the entry point. How to bind the relationship?
public class MyAdvice {
@Pointcut("execution(void com.taro.dao.BookDao.update())")
private void pt(){
}
@Before("pt()")
public void method(){
System.out.println(System.currentTimeMillis());
}
}
Bind the pointcut to the advice relationship, and specify the specific execution that the advice adds to the original join pointLocation
Explanation: @Before is translated as before, that is to say, the notification will be executed before the execution of the pointcut method, and there are four other types before it. Let's talk slowly.
Step 6: Assign the notification class to the container and identify it as an aspect class
@Component
@Aspect
public class MyAdvice {
@Pointcut("execution(void com.taro.dao.BookDao.update())")
private void pt(){
}
@Before("pt()")
public void method(){
System.out.println(System.currentTimeMillis());
}
}
Step 7: Enable the annotation format AOP function
@Configuration
@ComponentScan("com.taro")
@EnableAspectJAutoProxy
public class SpringConfig {
}
Step 8: Run class writing
public class App {
public static void main(String[] args) {
ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
BookDao bookDao = ctx.getBean(BookDao.class);
bookDao.update();
}
}
Then you'll find out. . . update can also print the system time, this is not the point, how AOP defines the operation is worth learning.