Spring——AOP的相关概念、理解

AOP:面向切面编程

AOP意为: 面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的技术。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各个部分之间的耦合度降低,提高程序的可重用性,同时提高了开发效率。

AOP的作用:
在程序运行期间,不修改源码对已有方法进行增强。

优势:
减少重复代码;提高开发效率;维护方便。

AOP相关术语:

连接点: 指那些被拦截到的点。在spring中这些点指的是方法。spring中只支持方法类型的连接点。

切入点: 指要对连接点进行拦截的定义。
所有的切入点,都是连接点。连接点,并不一定是切入点。

通知: 拦截到连接点之后要做的事情就是通知。
通知类型分为: 前置通知、后置通知、最终通知、环绕通知。
Spring——AOP的相关概念、理解_第1张图片

Spring基于XML的AOP配置

配置XML

Spring中基于XML的AOP配置步骤:


<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">

    
    <bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl">bean>

    
    
    
    <bean id="logger" class="com.itheima.utils.Logger">bean>
    
    <aop:config>
        
        <aop:aspect id="logAdvice" ref="logger">
            
            <aop:before method="printLog" pointcut="execution(* com.itheima.service.impl.*.*(..))">aop:before>aop:before>
        aop:aspect>
    aop:config>
beans>

测试AOP的配置
Spring——AOP的相关概念、理解_第2张图片
四种常用的通知类型
Spring——AOP的相关概念、理解_第3张图片
Spring——AOP的相关概念、理解_第4张图片
通用化切入点表达式:
Spring——AOP的相关概念、理解_第5张图片

Spring中的环绕通知

Spring——AOP的相关概念、理解_第6张图片

Spring基于注解的AOP的配置

XML配置:


<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"
       xmlns:context="http://www.springframework.org/schema/context"
       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
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">

    
    <context:component-scan base-package="com.itheima">context:component-scan>

    
    <aop:aspectj-autoproxy>aop:aspectj-autoproxy>

beans>
package com.itheima.utils;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.stereotype.Component;

/**
 * 用于记录日志的工具类,它里面提供了公共的代码
 */
@Component("logger")
@Aspect //表示当前类是一个切面类
@EnableAspectJAutoProxy
public class Logger {
     

    @Pointcut("execution(* com.itheima.service.impl.*.*(..))")
    private void pt1(){
     

    }

    /**
     * 前置通知
     */
    //@Before("pt1()")
    public void beforePrintLog(){
     
        System.out.println("前置通知Logger类中的beforePrintLog方法开始记录日志了");
    }

    /**
     * 后置通知
     */
    //@AfterReturning("pt1()")
    public void afterReturningPrintLog(){
     
        System.out.println("后置通知Logger类中的afterReturningPrintLog方法开始记录日志了");
    }

    /**
     * 异常通知
     */
    //@AfterThrowing("pt1()")
    public void afterThrowingPrintLog(){
     
        System.out.println("异常通知Logger类中的afterThrowingPrintLog方法开始记录日志了");
    }

    /**
     * 最终通知
     */
    //@After("pt1()")
    public void afterPrintLog(){
     
        System.out.println("最终通知Logger类中的afterPrintLog方法开始记录日志了");
    }

    /**
     * 环绕通知
     * 问题:配置了环绕通知以后,切入点方法没有执行,通知方法执行了。
     * 分析:通过对比动态代理中的环绕通知代码,发现动态代理的环绕通知有明确的切入点方法调用,在该代码中没有
     * 解决:Spring框架提供了一个ProceedingJoinPoint接口,该接口有一个proceed()方法,该方法相当于明确调用切入点方法。
     *      该接口可以作为环绕通知的方法参数,在程序执行时,Spring框架会提供该接口的实现类,供我们使用。
     * Spring框架的环绕通知:
     *      是Spring框架为我们提供的一种可以在代码中手动控制增强方法何时执行的方式。
     * @return
     */
    @Around("pt1()")
    public Object aroundPrintLog(ProceedingJoinPoint pjp){
     
        Object rtValue = null;
        try {
     
            Object[] args = pjp.getArgs();  //得到方法执行所需的参数
            System.out.println("环绕通知Logger类中的aroundPrintLog方法开始记录日志了———前置");
            rtValue = pjp.proceed(args);    //明确调用切入点方法(业务层方法)
            System.out.println("环绕通知Logger类中的aroundPrintLog方法开始记录日志了———后置");
            return rtValue;
        } catch (Throwable throwable) {
     
            System.out.println("环绕通知Logger类中的aroundPrintLog方法开始记录日志了———异常");
            throw new RuntimeException(throwable);
        }finally {
     
            System.out.println("环绕通知Logger类中的aroundPrintLog方法开始记录日志了———最终");
        }
    }
}

Spring——AOP的相关概念、理解_第7张图片
Spring——AOP的相关概念、理解_第8张图片

你可能感兴趣的:(java,spring)