1. AOP introduction
1.1 basic concepts of AOP
AOP (Aspect Oriented Programming) is a technology of Aspect Oriented Programming, which realizes the unified maintenance of program functions through precompiled mode and dynamic agent during operation. AOP is the continuation of OOP, a hot spot in software development and an important content of Spring framework.
1.2 role of AOP
The core function of AOP is to enhance the function of the program without modifying the code during the program running. Make the essential public functions into aspects, and cut into the code to run as the program runs. When writing business, we only focus on the core functions, and no longer consider the public functions such as transaction and log, which reduces the coding burden and focuses more on business.
1.3 AOP terminology
1. Aspect
The concerns about which methods to intercept and how to deal with them after interception are called facets
2. Join point
The intercepted point. Because Spring only supports connection points of method types, connection points in Spring refer to the intercepted methods. In fact, connection points can also be fields or constructors
3. pointcut
Definition of interception of connection points
4. advice
The so-called notification refers to the code to be executed after intercepting the connection point. Notifications are divided into five categories: pre, post, exception, final and surround notifications
5. Target object
The process of applying facets to the target object and causing the proxy object to be created
6. Import \ weave (introduction, weave)
Without modifying the code, you can dynamically add some methods or fields to the class at run time
2. Implementation of AOP
2.1 AOP configuration steps
2.1.1 import dependency
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>5.2.8.RELEASE</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjrt</artifactId> <version>1.9.5</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.9.5</version> </dependency>
2.1.2 preparation notice
/** * Log output notification class */ public class LogAdvise { public void beforeLog(){ System.out.println("Method starts execution!"); } public void afterLog(){ System.out.println("Method post execution!"); } public void afterReturning(){ System.out.println("Method returned data"); } public void afterThrowing(){ System.out.println("Method threw an exception"); } public void around(ProceedingJoinPoint joinPoint) throws Throwable { System.out.println("around Method name:" + joinPoint.getSignature().getName()); System.out.println("around --Front"); //Original method joinPoint.proceed(); System.out.println("around --Post"); } }
2.1.3 AOP configuration
<?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:context="http://www.springframework.org/schema/context" 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/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd"> <!--Configure scanning of packages--> <context:component-scan base-package="com.blb.aop_demo"></context:component-scan> <!--Configure notification class--> <bean id="logAdvise" class="com.blb.aop_demo.util.LogAdvise"></bean> <!--Configure section--> <aop:config> <!--Configure pointcuts--> <aop:pointcut id="pc" expression="execution(* com.blb.aop_demo.service.*Service.*(..))"/> <!--Configure section ref Is a notification class bean--> <aop:aspect id="aspect1" ref="logAdvise"> <!--Before advice method Is the corresponding notification method pointcut-ref Is the entry point--> <aop:before method="beforeLog" pointcut-ref="pc"></aop:before> <!--Post--> <aop:after method="afterLog" pointcut-ref="pc"></aop:after> <!--Post return--> <aop:after-returning method="afterReturning" pointcut-ref="pc"></aop:after-returning> <!--Post throw anomaly--> <aop:after-throwing method="afterThrowing" pointcut-ref="pc"></aop:after-throwing> <!--surround--> <aop:around method="around" pointcut-ref="pc"></aop:around> </aop:aspect> </aop:config> </beans>
2.1.4 testing
At com.blb.aop_ Add several Service classes under demo.Service package for testing
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring-aop.xml"); GoodsService goodsService = context.getBean(GoodsService.class); goodsService.queryGoods(); goodsService.queryGoodsById(1); goodsService.createGoods(); goodsService.updateGoods(); goodsService.deleteGoodsById(1);
2.1.5 configuration details
aop:pointcut is the pointcut configuration
The core is expression, which controls the application scope of the section through the expression
Syntax:
Execution (return value of access modifier package name. Class name. Method name (parameter type, parameter type...))
Wildcard:
*Represents characters of any length .. Instead of a sub package or any parameter
3. Annotation configuration of AOP
3.1 common AOP related notes
@The Aspect is configured on the Aspect class
@PointCut("expression") configures the pointcut and adds it to the method
@Before configuring the pre notification method
@After configure post notification method
@Around configure surround notification method
@AfterReturning configures the post return value notification method
@AfterThrowing configures the post throw exception notification method
3.2 AOP configuration
1) Configuration class
@ComponentScan(basePackages = "com.blb.aop_demo") @Configuration //Start annotation configuration for AspectJ @EnableAspectJAutoProxy public class AopConfig { }
2) Log section
/** * Log section */ @Aspect @Component public class LogAspect { //Configure pointcuts @Pointcut("execution(* com.blb.aop_demo.service.*Service.*(..))") public void pointcut(){ } //Configure notification method @Before("pointcut()") public void beforeLog(){ System.out.println("This is the pre notification method!!"); } }
3) Testing
AnnotationConfigApplicationContext context2 = new AnnotationConfigApplicationContext(AopConfig.class); GoodsService goodsService = context2.getBean(GoodsService.class); goodsService.queryGoods(); goodsService.queryGoodsById(1); goodsService.createGoods(); goodsService.updateGoods(); goodsService.deleteGoodsById(1);
4. Log tracking cases
4.1 case overview
After the actual project is deployed online, it is necessary to locate the bug s through log collection. If the log tracking code is written in all methods, it will be very cumbersome and the code is not conducive to maintenance. If AOP is used, this problem can be well solved.
4.2 case realization
1) Import log4j dependency
2) Add log4j.properties
3) Write log section
/** * Log4j Log output section */ @Aspect @Component public class Log4jAspect { //Create log object private Logger logger = Logger.getLogger(Log4jAspect.class); //Add log trace to all methods of all service classes @Pointcut("execution(* com.blb.aop_demo.service.*Service.*(..))") public void logPointcut(){ } //Configure surround notifications @Around("logPointcut()") public Object aroundLog(ProceedingJoinPoint point) throws Throwable { //Record time before method execution long start = System.currentTimeMillis(); //Print method name if(logger.isDebugEnabled()){ logger.debug("Current execution method:" + point.getSignature().getName()); } //Print parameters Object[] args = point.getArgs(); for(Object arg : args){ if(logger.isDebugEnabled()){ logger.debug("Parameters:"+arg); } } //Print return value Object result = point.proceed(); if(logger.isDebugEnabled()){ logger.debug("Method return value:" +result); } //Print execution time long end = System.currentTimeMillis(); if(logger.isDebugEnabled()){ logger.debug("Method execution time:" +(end - start)); } return result; } }