1. What is AOP
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
==Provide declarative transactions; Allows you to customize the cut plane==
-
Crosscutting concerns: methods or functions that span multiple modules of an application. That is, the part that has nothing to do with our business logic, but we need to focus on is crosscutting concerns. Such as logging, security, caching, transactions, etc
-
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 a 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:
That is, Aop adds new functions without changing the original code
3. Using Spring to implement Aop
[key] 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
First, write our business interface and implementation class
public interface UserService { public void add(); public void delete(); public void update(); public void search(); }
public class UserServiceImpl implements UserService{ @Override public void add() { System.out.println("Add user"); } @Override public void delete() { System.out.println("delete user"); } @Override public void update() { System.out.println("Update user"); } @Override public void search() { 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 //objects: parameters of the called method //Object: target object @Override public void before(Method method, Object[] objects, Object o) throws Throwable { System.out.println( o.getClass().getName() + "of" + method.getName() + "Method was executed"); } }
public class AfterLog implements AfterReturningAdvice { //returnValue return value //Method called method //args parameter of the object of the called method //Target the called target object @Override public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable { System.out.println("Yes" + target.getClass().getName() +"of"+method.getName()+"method," +"Return value:"+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 { @Test public void test(){ ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml"); UserService userService = (UserService) context.getBean("userService"); userService.search(); } }
The importance of Aop: very important. We must understand the ideas, mainly the understanding of ideas
Spring's Aop combines public business (log, security, etc.) with domain business. When executing domain business, public business will be added to realize the reuse of public business. Domain business is more pure, and programs focus on domain business. Its essence is still dynamic agent
Custom classes to implement Aop
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---------"); } }
To configure in spring
<!--The second way is to customize the implementation--> <!--register bean--> <bean id="diy" class="com.kuang.config.DiyPointcut"/> <!--aop Configuration of--> <aop:config> <!--The second way: use AOP Label Implementation of--> <aop:aspect ref="diy"> <aop:pointcut id="diyPonitcut" expression="execution(* com.kuang.service.UserServiceImpl.*(..))"/> <aop:before pointcut-ref="diyPonitcut" method="before"/> <aop:after pointcut-ref="diyPonitcut" method="after"/> </aop:aspect> </aop:config>
Test:
public class MyTest { @Test public void test(){ ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml"); UserService userService = (UserService) context.getBean("userService"); userService.add(); } }
Implementation using annotations
Step 1: write an enhanced class for annotation implementation
package com.kuang.config; import org.aspectj.lang.ProceedingJoinPoint; 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 public class AnnotationPointcut { @Before("execution(* com.kuang.service.UserServiceImpl.*(..))") public void before(){ System.out.println("---------Before method execution---------"); } @After("execution(* com.kuang.service.UserServiceImpl.*(..))") public void after(){ System.out.println("---------After method execution---------"); } @Around("execution(* com.kuang.service.UserServiceImpl.*(..))") public void around(ProceedingJoinPoint jp) throws Throwable { System.out.println("Surround front"); System.out.println("autograph:"+jp.getSignature()); //Execute target method Object proceed = jp.proceed(); System.out.println("After surround"); System.out.println(proceed); } }
Step 2: register the bean in the Spring configuration file and add the configuration supporting annotation
<!--The third way:Annotation implementation--> <bean id="annotationPointcut" class="com.kuang.config.AnnotationPointcut"/> <aop:aspectj-autoproxy/>
AOP: AspectJ AutoProxy: description
- Through the < aop: aspectJ AutoProxy / > declaration of the aop namespace, automatically create a proxy for those bean s configured with the @ aspectJ aspect in the spring container and weave the aspect in. Of course, spring still uses AnnotationAwareAspectJAutoProxyCreator internally to create automatic proxy, but the specific implementation details have been hidden by < aop: aspectJ AutoProxy / >
- < AOP: AspectJ AutoProxy / > has a proxy target class attribute, which is false by default, indicating that jdk dynamic proxy is used for weaving enhancement. When it is configured as < AOP: AspectJ AutoProxy poxy target class = "true" / /, it indicates that CGLib dynamic proxy technology is used for weaving enhancement. However, even if proxy target class is set to false, if the target class does not declare an interface, spring will automatically use CGLib dynamic proxy.
This article is mainly from the crazy God notes of SSM series