Spring-AOP concept and usage tutorial

Spring-AOP

1. Basic concepts of AOP

​ (1) Aspect-oriented programming (aspect), the use of AOP can isolate various parts of business logic, thereby reducing the coupling between various parts of business logic, improving the reusability of the program, and improving the efficiency of development at the same time.

​ (2) Popular description:Do not modify the source code, add new functions in the main function

​ (3) Use login examples to illustrate AOP

Insert picture description here

2. AOP (underlying principle)

​ a) AOP uses dynamic proxy at the bottom layer. There are two situations for dynamic proxy:

The first If there are interfaces, use JDK dynamic proxy; Create a proxy object for the interface implementation class to enhance the method of the class
Insert picture description here

In the second case without an interface, use CGLIB dynamic proxy; Create a proxy object of the subclass, enhance the method of the class
Insert picture description here

3. AOP (JDK dynamic proxy)

​ 1) Use JDK dynamic proxy, use the method in the Proxy class to create proxy objects

Call the newProxyInstance method, which has three parameters:

public static Object newProxyInstance(ClassLoader loader,
                                      Class<?>[] interfaces,
                                      InvocationHandler h)

​ The first parameter, the class loader

​ The second parameter, the class where the enhancement method is located, the interface that this class implements, supports multiple interfaces

​ The third parameter, implement this interface InvocationHandler, create a proxy object, and write the enhanced part

​ 2) Write JDK dynamic proxy code

//(1)创建接口,定义方法
public interface UserDao {
    
    
 public int add(int a,int b);
 public String update(String id);
}
//(2)创建接口实现类,实现方法
public class UserDaoImpl implements UserDao {
    
    
 @Override
 public int add(int a, int b) {
    
    
 return a+b;
 }
 @Override
 public String update(String id) {
    
    
 return id;
 }
}
//(3)使用 Proxy 类创建接口代理对象
public class JDKProxy {
    
    
 public static void main(String[] args) {
    
    
 //创建接口实现类代理对象
 Class[] interfaces = {
    
    UserDao.class};
 UserDaoImpl userDao = new UserDaoImpl(); 
/** 第一参数,类加载器 
	第二参数,增强方法所在的类,这个类实现的接口,(支持多个接口)
	第三参数,实现这个接口 InvocationHandler,创建代理对象,写增强的部分  */
 UserDao dao =(UserDao)Proxy.newProxyInstance(JDKProxy.class.getClassLoader(), interfaces,
					new UserDaoProxy(userDao));
 int result = dao.add(1, 2);
 System.out.println("result:"+result);
 }
}

//创建代理对象代码
class UserDaoProxy implements InvocationHandler {
    
    
 //1 把创建的是谁的代理对象,把谁传递过来
 //有参数构造传递
 private Object obj;
 public UserDaoProxy(Object obj) {
    
    
 this.obj = obj;
 }
 //增强的逻辑
 @Override
 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    
    
 //方法之前
 System.out.println("方法之前执行...."+method.getName()+" :传递的参数..."+ Arrays.toString(args));
 //被增强的方法执行
 Object res = method.invoke(obj, args);
 //方法之后
 System.out.println("方法之后执行...."+obj);
 return res;
 }
}

4. AOP (term)

​ a) Connection points: Which methods in the class can be enhanced, these methods are called connection points

​ b) Entry point: The method that is actually enhanced is called entry point

​ c) Notification (enhancement): The logical part of the actual enhancement is called notification, and it is divided into the following five types:

​ 1) Pre-notification 2) Post-notification 3) Surrounding notification 4) Exception notification 5) Final notification

​ d) Aspects: the process of applying notifications to the point of entry

5. AOP operation

​ a) The Spring framework is generally based on AspectJ to implement AOP operations. AspectJ is not a part of Spring. It is an independent AOP framework. Generally, AspectJ and Spirng frameworks are used together to perform AOP operations.

​ b) Implementation of AOP operations based on AspectJ: 1) Implementation based on xml configuration file (2) Implementation based on annotation method (use)

​ c) Introduce related jar packages

​ d) The entry point expression is as follows:

1)切入点表达式作用:知道对哪个类里面的哪个方法进行增强 
(2)语法结构: execution([权限修饰符] [返回类型] [类全路径] [方法名称]([参数列表]) )3)例子如下:
    例 1:对 com.atguigu.dao.BookDao 类里面的 add 进行增强
		execution(* com.atguigu.dao.BookDao.add(..))2:对 com.atguigu.dao.BookDao 类里面的所有的方法进行增强
		execution(* com.atguigu.dao.BookDao.* (..))3:对 com.atguigu.dao 包里面所有类,类里面所有方法进行增强
		execution(* com.atguigu.dao.*.* (..))

6. AOP operation (AspectJ annotation)

//1、创建类,在类里面定义方法
public class User {
    
    
 public void add() {
    
    
 System.out.println("add.......");
 }
}
//2、创建增强类(编写增强逻辑)
//(1)在增强类里面,创建方法,让不同方法代表不同通知类型
//增强的类
public class UserProxy {
    
    
 public void before() {
    
    //前置通知
 System.out.println("before......");
 }
}

<!--3、进行通知的配置-->
<?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 http://www.springframework.org/schema/context/spring-context.xsd
                        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
    <!-- 开启注解扫描 -->
    <context:component-scan base-package="com.atguigu.spring5.aopanno"></context:component-scan>

    <!-- 开启Aspect生成代理对象-->
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>
//增强的类
@Component
@Aspect  //生成代理对象
public class UserProxy {
    
    }

//被增强的类
@Component
public class User {
    
    }

//4、配置不同类型的通知
@Component
@Aspect  //生成代理对象
public class UserProxy {
    
    
      //相同切入点抽取
    @Pointcut(value = "execution(* com.atguigu.spring5.aopanno.User.add(..))")
    public void pointdemo() {
    
    

    }

    //前置通知
    //@Before注解表示作为前置通知
    @Before(value = "pointdemo()")//相同切入点抽取使用!
    public void before() {
    
    
        System.out.println("before.........");
    }

    //后置通知(返回通知)
    @AfterReturning(value = "execution(* com.atguigu.spring5.aopanno.User.add(..))")
    public void afterReturning() {
    
    
        System.out.println("afterReturning.........");
    }

    //最终通知
    @After(value = "execution(* com.atguigu.spring5.aopanno.User.add(..))")
    public void after() {
    
    
        System.out.println("after.........");
    }

    //异常通知
    @AfterThrowing(value = "execution(* com.atguigu.spring5.aopanno.User.add(..))")
    public void afterThrowing() {
    
    
        System.out.println("afterThrowing.........");
    }

    //环绕通知
    @Around(value = "execution(* com.atguigu.spring5.aopanno.User.add(..))")
    public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
    
    
        System.out.println("环绕之前.........");

        //被增强的方法执行
        proceedingJoinPoint.proceed();

        System.out.println("环绕之后.........");
    }
}

7. There are multiple enhanced classes to enhance the same method, set the priority of the enhanced class

//(1)在增强类上面添加注解 @Order(数字类型值),数字类型值越小优先级越高
@Component
@Aspect
@Order(1)
public class PersonProxy{
    
     }

8. AOP operation (AspectJ configuration file)

<!--1、创建两个类,增强类和被增强类,创建方法(同上一样)-->
<!--2、在 spring 配置文件中创建两个类对象-->
<!--创建对象-->
<bean id="book" class="com.atguigu.spring5.aopxml.Book"></bean>
<bean id="bookProxy" class="com.atguigu.spring5.aopxml.BookProxy"></bean>
<!--3、在 spring 配置文件中配置切入点-->
<!--配置 aop 增强-->
<aop:config>
 <!--切入点-->
 <aop:pointcut id="p" expression="execution(* com.atguigu.spring5.aopxml.Book.buy(..))"/>
 <!--配置切面-->
 <aop:aspect ref="bookProxy">
 <!--增强作用在具体的方法上-->
 <aop:before method="before" pointcut-ref="p"/>
 </aop:aspect>
</aop:config>

Guess you like

Origin blog.csdn.net/weixin_45496190/article/details/107082732