Spring AOP pre-notification and post-notification, and Spring AOP pre-post-Notification
Spring AOP
AspectJ: the most complete and popular AOP framework in the Java Community
In Spring2.0 or later versions, you can use AspectJ-based annotations or XML-based AOP
Enable AspectJ annotation support in Spring
To use the AspectJ annotation in Spring applications, the AspectJ Class Library: aopalliance. jar, aspectj. weaver. jar, and spring-aspects.jar must be included in classpath.
Add the aop Schema to the <beans> root element.
To enable AspectJ annotation support in the Spring IOC container, you only need to define an empty XML Element in the early bean configuration file <aop: aspectj-autoproxy>
When the Spring IOC container detects the <aop: aspectj-autoproxy> element in the bean configuration file, it automatically creates a proxy for the bean that matches the AspectJ aspect.
Use AspectJ annotations to declare a cut surface
To declare the AspectJ aspect in Spring, you only need to declare the aspect as a bean instance in the IOC container. After the AspectJ aspect is initialized in the Spring IOC container, the Spring IOC container creates a proxy for the beans that match the AspectJ aspect.
In the AspectJ annotation, the aspect is just a Java class with the @ AspectJ Annotation
A notification is a simple Java method for annotation.
AspectJ supports five types of notification Annotations:
@ Before: pre-notification, which is returned Before method execution
@ After: Post-notification, executed After method execution
@ AfterRunning: Return notification, executed after the method returns the result
@ AfterThrowing: exception notification, after the method throws an exception
@ Around: the surround notification is executed Around the method.
Use method signature to compile the AspectJ entry point expression
When the most typical entry-point expression is used, various methods are matched based on the method signature:
-Execution * com. yl. spring. aop. arithmeticCalculator. *(..): matches all the methods declared in ArithmeticCalculator. The first * represents any modifier and any return value, and the second * represents any method ,.. match any number of parameters. If the target class and interface are in the same package, the package name can be omitted.
-Execution public * ArithmeticCalculator. * (...): matches all public methods of the ArithmeticCalculator interface.
-Execution public double ArithmeticCalculator. * (...): Method for matching the double type value returned by ArithmeticCalculator
-Execution public double ArithmeticCalculator. * (double,...): matches the method with the first parameter of the double type.
-Execution public double ArithmeticCalculator. * (double, double): Method for matching parameter types: double and double
Post notification
The post-notification is executed after the connection point is complete, that is, when the connection point returns the result or throws an exception, the following post-Notification records the termination of the method.
One aspect can contain one or more notifications.
LoggingAspect. java
1 package com. yl. spring. aop. impl; 2 3 import java. util. arrays; 4 import java. util. list; 5 6 import org. aspectj. lang. joinPoint; 7 import org. aspectj. lang. annotation. after; 8 import org. aspectj. lang. annotation. aspect; 9 import org. aspectj. lang. annotation. before; 10 import org. springframework. stereotype. component; 11 12 // This class is declared as a plane: the class needs to be put into the IOC container; then declare it as a front-side 13 @ Aspect14 @ Component15 public class LoggingAspect {16 17 // declare this method as a front-end notification: run 18 // @ Before ("execution (public int com. yl. spring. aop. impl. arithmeticCalculatorImpl. add (int, int) ") 19 @ Before (" execution (* com. yl. spring. aop. impl. *. *(..)) ") 20 public void beforeMethod (JoinPoint joinpoint) {21 String methodName = joinpoint. getSignature (). getName (); 22 List <Object> args = Arrays. asList (joinpoint. getArgs (); 23 System. out. println ("The method" + methodName + "begins with" + args); 24} 25 // post notification: after The target method is executed (whether or not an exception occurs ), executed notification 26 // In the post notification, the result of the target method execution is not allowed 27 @ After ("execution (* com. yl. spring. aop. impl. *. *(..)) ") 28 public void afterMethod (JoinPoint joinPoint) {29 String methodName = joinPoint. getSignature (). getName (); 30 List <Object> args = Arrays. asList (joinPoint. getArgs (); 31 System. out. println ("The method" + methodName + "end with" + args); 32} 33 34}
Configuration File applicationContext. xml:
1 <? Xml version = "1.0" encoding = "UTF-8"?> 2 <beans xmlns = "http://www.springframework.org/schema/beans" 3 xmlns: xsi = "http://www.w3.org/2001/XMLSchema-instance" 4 xmlns: aop = "http://www.springframework.org/schema/aop" 5 xmlns: context = "http://www.springframework.org/schema/context" 6 xsi: schemaLocation = "http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.1.xsd 7 http://www.springframework.org/schem A/beans http://www.springframework.org/schema/beans/spring-beans.xsd 8 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd "> 9 10 <! -- Configure the automatically scanned package --> 11 <context: component-scan base-package = "com. yl. spring. aop. impl "> </context: component-scan> 12 13 <! -- Enable AspectJ annotation to take effect: automatically generate proxy objects for matching classes --> 14 <aop: aspectj-autoproxy> </aop: aspectj-autoproxy> 15 16 </beans>
Test class:
1 package com.yl.spring.aop.impl; 2 3 import org.springframework.context.ApplicationContext; 4 import org.springframework.context.support.ClassPathXmlApplicationContext; 5 6 public class Main { 7 public static void main(String[] args) { 8 9 ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");10 11 ArithmeticCalculator arithmeticCalculator = ctx.getBean(ArithmeticCalculator.class);12 13 int result = arithmeticCalculator.add(4, 6);14 System.out.println("result: " + result);15 16 result = arithmeticCalculator.mul(4, 6);17 System.out.println("result: " + result);18 } 19 }