AOP (aspect oriented programming)
1. What is AOP
AOP definition
AOP (Aspect Oriented Programming) means: Aspect Oriented Programming, which realizes the unified maintenance of program functions through precompiled mode and runtime dynamic agent. AOP is the continuation of OOP, a hot spot in software development, an important content in Spring framework, and a derivative paradigm of functional programming. AOP can isolate each part of business logic, reduce the coupling between each part of business logic, improve the reusability of program, and improve the efficiency of development.
2. The role of Aop in Spring
The role of AOP in Spring
Provide declarative transactions; Allows you to customize the cut plane
Proper nouns:
- Crosscutting concerns: methods or functions that span multiple modules of an application. That is, it has nothing to do with our business logic, but what we need to focus on is crosscutting concerns. Such as log, security, cache, transaction and so on
- ASPECT: a special object whose crosscutting concerns are modularized. That is, it is a class.
- Advice: work that must be completed in all aspects. That is, it is a method in the class.
- Target: the notified object.
- Proxy: an object created after notification is applied to the target object.
- PointCut: the definition of the "place" where the aspect notification is executed.
- Join point: the execution point that matches the pointcut.
In spring AOP, crosscutting logic is defined through Advice. Spring supports five types of Advice:
3. Using Spring to implement Aop
Using Spring to implement Aop
To use AOP weaving, you need to import a dependency package!
<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver --> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.9.4</version> </dependency>
The first way
Implemented through Spring API [mainly through Spring API interface]
First, write our business interface and implementation class
public interface UserService { public void add(); public void delete(); public void update(); public void select(); } public class UserServiceImpl implements UserService{ public void add() { System.out.println("Add user"); } public void delete() { System.out.println("delete user"); } public void update() { System.out.println("Update user"); } public void select() { System.out.println("Query user"); } }
Then write our enhancement class. We write two, one pre enhancement and one post enhancement
public class Log implements MethodBeforeAdvice { //Method: the method of the target object to execute //args: parameter of the called method //Target: target object public void before(Method method, Object[] args, Object target) throws Throwable { System.out.println(target.getClass().getName()+"of"+method.getName()+"Executed"); } } public class AfterLog implements AfterReturningAdvice { //returnValue Return value //method Called method //args Parameters of the object of the called method //target Called target object //returnValue Return value public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable { System.out.println("Yes"+method.getName()+"The returned result is:"+returnValue); } }
Finally, register in the spring file and implement aop cut in implementation. Pay attention to import constraints
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <!--register bean--> <bean id="userService" class="com.kuang.service.UserServiceImpl"/> <bean id="log" class="com.kuang.log.Log"/> <bean id="afterLog" class="com.kuang.log.AfterLog"/> <!--aop Configuration of--> <aop:config> <!--breakthrough point expression:The expression matches the method to execute--> <aop:pointcut id="pointcut" expression="execution(* com.kuang.service.UserServiceImpl.*(..))"/> <!--Perform wrap; advice-ref Execution method . pointcut-ref breakthrough point--> <aop:advisor advice-ref="log" pointcut-ref="pointcut"/> <aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"/> </aop:config> </beans>
test
public class MyTest { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); //The dynamic proxy is the interface UserService userService = (UserService) context.getBean("userService"); userService.add(); } }
The second way
User defined classes to implement AOP [mainly section definitions]
The target business class remains the same as userServiceImpl
Step 1: write our own cut in class
public class DiyPointcut { public void before(){ System.out.println("---------Before method execution---------"); } public void after(){ System.out.println("---------After method execution---------"); } }
Configuration in spring
<!--Method 2: custom implementation--> <!--register Bean--> <bean id="diy" class="com.zhu.diy.DiyPointCut"/> <!--aop Configuration of--> <aop:config> <!-- Custom cut, ref Class to reference--> <aop:aspect ref="diy"> <!-- breakthrough point--> <aop:pointcut id="point" expression="execution(* com.zhu.service.UserServiceImpl.*(..))"/> <!-- notice--> <aop:before method="before" pointcut-ref="point"/> <aop:after method="after" pointcut-ref="point"/> </aop:aspect> </aop:config>
Test:
public class MyTest { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); //The dynamic proxy is the interface UserService userService = (UserService) context.getBean("userService"); userService.add(); } }
The third way
Implementation using annotations
Step 1: write an enhanced class for annotation implementation
package com.zhu.diy; //Method 3: implement AOP by annotation import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.Signature; import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; @Aspect//Label this class as a facet public class AnnotationPointCut { @Before("execution(* com.zhu.service.UserServiceImpl.*(..))") public void before(){ System.out.println("=====Before method execution======="); } @After("execution(* com.zhu.service.UserServiceImpl.*(..))") public void after(){ System.out.println("=====After method execution======="); } //In surround enhancement, we can give a parameter representing the point where we want to get the processing pointcut @Around("execution(* com.zhu.service.UserServiceImpl.*(..))") public void around(ProceedingJoinPoint jp) throws Throwable { System.out.println("Surround front"); Object proceed = jp.proceed(); //Execution method System.out.println("After surround"); //Signature signature = jp.getSignature();// Get signature //System.out.println("signature:"+signature); //System.out.println(proceed); } }
Step 2: register the bean in the Spring configuration file and add the configuration supporting annotation
<!-- Mode III**Implementation using annotations**--> <bean id="annotationPointCut"class="com.zhu.diy.AnnotationPointCut"/> <!--Enable annotation support! JDK(default proxy-target-class="false") cglib--> <aop:aspectj-autoproxy/>
AOP: AspectJ AutoProxy: description
adopt aop Namespace<aop:aspectj-autoproxy /> Declaration is automatically spring Which configurations are in the container@aspectJ Tangential bean Create a proxy and weave in the cut. of course, spring It is still used internally AnnotationAwareAspectJAutoProxyCreator To create an automatic proxy, But the details of the implementation have been<aop:aspectj-autoproxy />It's hidden <aop:aspectj-autoproxy /> There is one proxy-target-class Property, default to false,Indicates use jdk Dynamic proxy weaving enhancements, When matched as<aop:aspectj-autoproxy poxy-target-class="true"/>When, it means to use CGLib Dynamic agent technology weaving enhancement. But even if proxy-target-class Set to false,If the target class does not declare an interface, then spring Will be used automatically CGLib Dynamic proxy.