2, AOP aspect oriented programming
Official download address
Video viewing address
https://www.bilibili.com/video/BV1nz4y1d7uy
2.1 general
AOP(Aspect Orient Programming). Aspect oriented programming is to consider the program running process from a dynamic point of view
- The bottom layer of AOP is realized by dynamic agent mode. Two kinds of agents are used: dynamic agent of JDK and dynamic agent of CGLIB. AOP is the standardization of dynamic agent. The implementation steps and methods of dynamic agent are defined, so that developers can use dynamic agent in a unified way
- Aspect: aspect is the function added to your target class. Like the logs used above, transactions are faceted. Characteristics of aspect: generally, it is non business method and used independently
- Orient: face, face
- Programming: Programming
2.2 related terms
1. Aspect: aspect, which indicates enhanced functions, that is, a pile of code to complete a function. Non business functions. Common aspect functions include log, transaction, statistics, parameter check and permission verification. The aspect is used to organize multiple advice. Advice is defined in the aspect, which is actually an enhancement to the main business logic
2. JoinPoint: connection point, the location of the connection business method and section. For business methods in a certain class, clear points in the process of program execution, such as method call or exception throw. In Spring AOP, join points are always method calls
3. Pointcut: pointcut refers to the collection of multiple connection point methods. Multiple methods. You can insert connection points for enhanced processing. In short, when a connection point meets the specified requirements, the connection point will be added with enhancement processing, and the connection point will become a pointcut
4. Advice: enhanced processing performed by the AOP framework at specific pointcuts. There are "around", "before" and "after" types of processing, which can represent the execution time of the cutting function. The cutting point defines the cutting position and notifies the cutting time
5. Target: target object, which refers to the object to be enhanced. That is, the object of the class containing the main business logic
2.3 AspectJ
2.3.1 general
AspectJ is an AOP framework based on Java language, which provides powerful AOP functions. It mainly includes two parts:
- One part defines how to express and define the syntax specification in AOP programming;
- The other part is the tool part, including compiling and debugging tools
aspectJ framework implements aop in two ways:
- Configuration file using xml: configuring global transactions
- Using annotations, we need to do aop functions in the project. Generally, we use annotations. aspectj has five annotations
- @Before
- @AfterReturning
- @Around
- @AfterThrowing
- @After
2.3.2 pointcut expression of AspectJ
Expression prototype:
execution(modifiers-pattern? ret-type-pattern declaring-type-pattern?name-pattern(param-pattern) throws-pattern?)
![/upload-images.jianshu.io/upload_images/27220553-f998cc2391d3017d.gif?imageMogr2/auto-orient/strip)
Relevant explanations:
- modifiers-pattern? Access type
- RET type pattern return value type
- declaring-type-pattern? Package name class name
- Name pattern (param pattern) method name (parameter type and number of parameters)
- Throws pattern throw exception type
- ? Represents an optional part
The above expression consists of four parts
Execution (access permission method return value method declaration (parameter) exception type)
Symbol | significance |
---|---|
* | 0 cannot contain more than any characters |
. . | Used in method parameters to represent any number of parameters; Used after the package name to indicate the current package and sub package path |
+ | Used after the class name to represent the current class and its subclasses; Used after an interface to represent the current interface and its implementation class |
Relevant examples:
- execution(public (..)): Arbitrary public method
- execution( set(..)): Any method that starts with "set"
- execution( com.xyz.service..*(..)): Any method of any class defined in the service package
- execution( com.xyz.service...(..)): Any method of any class defined in the service package or sub package. “..” When it appears in the class name, it must be followed by '', indicating all classes under the package and sub package
- execution( ..service..(..)): Specify all methods in all classes (interfaces) under serivce sub packages under all packages as pointcuts
- execution( com.xyz.service.IAccountService+.(..)): If iaccountservice is an interface, it is any method in the interface and any method in all its implementation classes; If it is a class, it is any method in the class and its subclasses
- Execution (* joke(String,int)): all joke(String,int) methods, and the first parameter of the joke() method is String and the second parameter is int; If the parameter type in the method is Java For classes under Lang package, you can directly use the class name, otherwise you must use the fully qualified class name, such as Joe (Java. Util. List, int)
2.3.3 advance notice: @ Before
1. Definition requirements of method:
- Public method public
- Method has no return value
- Method name customization
- Methods can have parameters or no parameters
2.@Before: pre notification note
Attribute: value, is the pointcut expression, indicating the execution position of the function in the aspect
Location: above the method
1. Configuration dependency
<!--spring rely on--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.2.5.RELEASE</version> </dependency> <!--aspectj rely on--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> <version>5.2.5.RELEASE</version> </dependency>
2. Create business interface and implementation class objects
Service.interface public interface Service { public void doSome(); }
ServiceImpl.java @org.springframework.stereotype.Service("myService") public class ServiceImpl implements Service { @Override public void doSome() { System.out.println("This is my business method!!!"); } }
3. Create facet class: myaspect java
@Aspect @Component("myAspect") public class MyAspect { /** *Specify the parameter in the notification method: JoinPoint * */ @Before(value = "execution(void *..doSome(..))") public void before(){ System.out.println("This is an advance notice"); } }
4. Configure ApplicationContext XML file
<!--Scan file--> <context:component-scan base-package="com.jjh.*"/> <!--Declare automatic proxy generator--> <aop:aspectj-autoproxy/>
5. Test class call
@org.junit.Test public void demo01(){ String config = "applicationContext.xml"; ApplicationContext app = new ClassPathXmlApplicationContext(config); Service proxy = (Service) app.getBean("myService"); //Output the information of the current class: com sun. proxy.$ Proxy17 //It is proved that it uses JDK dynamic agent System.out.println(proxy.getClass().getName()); proxy.doSome(); }
2.3.4 JoinPoint
- Specify the parameter in the notification method: JoinPoint
- JoinPoint: business method, which is the business method to add aspect function
- Function: you can get the information of method execution in the notification method, such as method name and method arguments
- If you need information about the methods in the section function, join point
- The value of JoinPoint parameter is given by the framework and must be the parameter of the first position
- More than pre notification methods can contain a JoinPoint type parameter, which can be included in all notification methods
MyAspect.java
@Aspect @Component("myAspect") public class MyAspect { @Before(value = "execution(void *..doSome(..))") public void before(JoinPoint joinPoint){ //Gets the definition of the method System.out.println("Signature of method (definition):" + joinPoint.getSignature()); System.out.println("Name of method:" + joinPoint.getSignature().getName()); //Gets the argument of the method Object[] args = joinPoint.getArgs(); for (Object arg : args) { System.out.println("Parameters:" + arg); } System.out.println("This is a pre notification!!!"); } }
Test class
@org.junit.Test public void demo01(){ String config = "applicationContext.xml"; ApplicationContext app = new ClassPathXmlApplicationContext(config); Service proxy = (Service) app.getBean("myService"); proxy.doSome("Zhang San",20); }
Print results
2.3.5 post notification: @ AfterReturning
- Execute after target method execution
- Since it is executed after the target method, the return value of the target method can be obtained
- The returning attribute of this annotation is used to specify the variable name that receives the return value of the method
- Therefore, a method annotated as a post notification can contain not only the JoinPoint parameter, but also a variable for receiving the return value
- This variable is preferably of type Object, because the return value of the target method may be of any type
Business method
@Component("myService2") public class SomeServiceImpl implements SomeService { @Override public void doSome() { System.out.println("This is the business method!!!"); } @Override public String doOther(String str, int i) { return "Business method doOther Return value of!!!"; } }
Post notification
1. The returning attribute of this annotation is used to specify the variable name of the returned value of the receiving method
2. In addition to the JoinPoint parameter, it can also contain variables used to receive the return value
3. The variable should preferably be of Object type, because the return value of the target method may be of any type
4. Definition requirements of method:
- Public method public
- Method has no return value
- Method name customization
- If the method has parameters, Object is recommended, and the parameter name is user-defined
5.@AfterReturning: Post notification
- value: pointcut expression
- returning: a user-defined variable that represents the return value of the target method. The name of the user-defined variable must be the same as the formal parameter name of the notification method
- You can make corresponding operations according to the return value of the business method
@AfterReturning(value = "execution(String *..doOther(..))",returning = "res") public void myAfterReturning(JoinPoint joinPoint,Object res){ //Get the check-in (definition) of the method System.out.println(joinPoint.getSignature()); //Gets the parameters of the method Object[] args = joinPoint.getArgs(); for (Object arg : args) { System.out.println("Target method parameters:" + arg); } //Return value of the target method System.out.println(res); //Post notification System.out.println("Post notification!!!"); }
Test class
@Test public void demo02(){ String config = "applicationContext.xml"; ApplicationContext app = new ClassPathXmlApplicationContext(config); SomeService proxy = (SomeService)app.getBean("myService2"); proxy.doOther("Dick",20); }
2.3.6 surround notification: @ Around
Before and after the target method is executed. Methods annotated as surround enhancement should have return values
Methods annotated as surround enhancement should have return values and Object types. And the method can contain a parameter of type ProceedingJoinPoint
Interface ProceedingJoinPoint, which has a processed () method to execute the target method
If the target method has a return value, the return value of the method is the return value of the target method. Finally, the surround enhancement method returns its return value. The enhancement method actually intercepts the execution of the target method
- Section class
1. Definition format of surround notification method:
- public
- There must be a return value. Object is recommended
- Method name customization
- Method has parameters. The fixed parameter is ProceedingJoinPoint
2. Features
- Enhancements can be made before and after the target method
- Controls whether the target method is called and executed
- Modify the execution result of the original target method and affect the final call result
- It is the most powerful notification
3. Surround notification is equivalent to the InvocationHandler interface of jdk dynamic agent
4. Parameter: ProceedingJoinPoint is equivalent to Method, which is used to execute the target Method
5. Return value: it is the execution result of the target method and can be modified
6. Surround notification: do transactions frequently, start transactions before the target method, execute the target method, and submit transactions after the target method
@Around(value = "execution(String *..do(..))") public Object myAround(ProceedingJoinPoint p) throws Throwable { Object result = null; //Pre function enhancement System.out.println("Enhanced front function!!"); //Equivalent to method invoke(); Object result = doFirst(); result = p.proceed(); //Post function enhancement System.out.println("Post function enhancement"); return result; }
Test class
@Test public void demo01(){ ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml"); SomeService proxy = (SomeService)app.getBean("Service3"); String result = proxy.doFirst("Dick", 99); //Output return result System.out.println(result); }
2.3.7 exception notification: @ AfterThrowing
Execute after the target method throws an exception
The throwing attribute of this annotation is used to specify the exception class object that occurs
The method annotated as exception notification can contain a parameter Throwable. The parameter name is the name specified by throwing, indicating the exception object
- Business method
@Override public void doSecond() { System.out.println("Execute business methods doSecond()" + (10/0)); }
- Section class
1. Definition format of exception notification method:
- Access rights public
- no return value
- Method name customization
- Method has an Exception. You can also use JoinPoint
2. @AfterThrowing: exception notification
- Properties:
value pointcut expression
Throw in a custom variable that represents the exception object thrown by the target method. The variable name must be the same as the parameter name of the method
- characteristic:
Executed when the target method throws an exception
You can do an exception monitoring program to monitor whether there are exceptions when the target method is executed. If there are exceptions, you can send e-mail and SMS for notification
@AfterThrowing(value = "execution(* *..SomeServiceImpl.doSecond(..))", throwing = "ex") public void myAfterThrowing(Exception ex) { System.out.println("Exception notification: when an exception occurs in the method, execute:"+ex.getMessage()); //Send e-mail, SMS and notify developers }
2.3.8 final notice: @ After
This enhancement is performed whether or not the target method throws an exception
- Business method
@Override public void doThird() { System.out.println("Execute business methods doThird()"); }
Section class
1. Definition format of final notice:
- Access permission public
- no return value
- Method name customization
- Method has no parameters, but you can use JoinPoint
2. @After: features of final notice
- Always execute
- Execute after target method
//Equivalent to the following execution methods try{ SomeServiceImpl.doThird(..) }catch(Exception e){ }finally{ myAfter() }
@After(value = "execution(* *..SomeServiceImpl.doThird(..))") public void myAfter(){ System.out.println("Code that will always be executed when the final notification is executed"); //Generally do resource cleanup. }
2.3.9 @Pointcut definition entry point
When more notification enhancement methods use the same execution Pointcut expression, it is troublesome to write and maintain; AspectJ provides the @ Pointcut annotation to define the execution Pointcut expression
Annotate @ Pointcut on a method. In the future, all the value attribute values of execution can use the method name as the Pointcut
Represents the Pointcut defined by @ Pointcut. This method using @ Pointcut annotation generally uses the private identification method, that is, the method that has no practical effect
- Section class
1.@Pointcut: define and manage pointcuts. If multiple pointcut expressions in your project are repeated, they can be reused.
2. Features:
When @ Pointcut is defined on a method, the name of the method is the alias of the Pointcut expression
In other notifications, the value attribute can use this method name instead of the pointcut expression
@After(value = "mypt()") public void myAfter(){ System.out.println("Code that will always be executed when the final notification is executed"); //Generally do resource clearance. } @Before(value = "mypt()") public void myBefore(){ System.out.println("Pre notification, which is executed before the target method"); } @Pointcut(value = "execution(* *..SomeServiceImpl.doThird(..))" ) private void mypt(){ //No code required, }
2.4 replacement of agency mode
If the target class has an interface, jdk dynamic proxy is used by default. If the target class has no interface, CGlib dynamic proxy is used
If you want the target class with interface to use CGlib's proxy mode, you need the following configuration file
<aop:aspectj-autoproxy proxy-target-class="true"/>