Spring的AOP编程(面向切面编程)

目录

前言:
      该文章主要使用XML的方法配置AOP

一、AOP概念

二、AOP的优势

三、使用步骤

   1.导入依赖

   2.创建目标接口,并创建实现类,定义目标方法(连接点)

   3.创建通知类,定义通知方法

   4.创建Spring核心配置文件(基于xml配置方法)

   5.测试

   6.测试结果

注意事项:



前言:

       该文章主要使用XML的方法配置AOP

一、AOP概念

1、AOP(Aspect Oriented Programing)面向切面编程,一种编程范式,隶属于软工范畴,指导开发者如何组织程序结构

2、AOP弥补了OOP的不足,基于OOP基础之上进行横向开发
  2.1  OP规定程序开发以类为主体模型,一切围绕对象进行,完成某个任务先构建模型
  2.2  
AOP程序开发主要关注基于OOP开发中的共性功能,一切围绕共性功能进行,完成某个任务先构建可能遇到的所有共性功能(当所有功能都开发出来也就没有共性与非共性之分)


二、AOP的优势

  • 提高代码的可重用性

  • 业务代码编码更简洁

  • 业务代码维护更高效

  • l业务功能扩展更便捷

三、使用步骤

1.导入依赖

<dependencies>
        <!--Spring上下文核心包-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.1.2.RELEASE</version>
        </dependency>
        
        <!--AOP的实现包-->
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.9.4</version>
        </dependency>
        
 </dependencies>

2.创建目标接口,并创建实现类,定义目标方法(连接点)

代码如下(示例):

/**
 * @Author:Yan
 * @Date 2022/01/21 17:21
 * @Description  目标接口
 **/
public interface Target {

    String method(String name);
}
/**
 * @Author:Yan
 * @Date 2022/01/21 17:22
 * @Description 目标接口实现类
 **/
public class TargetImpl implements Target {
    //需要增强的目标方法
    @Override
    public String method(String name) {
        System.out.println("TargetImpl..."+name);
        return name;
    }
}

3.创建通知类,定义通知方法

public class MyAdvice {
    //前置通知
    public void before() {
        System.out.println("前置增强-->打印日志");
    }

    //最终通知
    public void after() {
        System.out.println("最终通知-->打印日志");
    }

    //返回后通知
    public void afterRun() {
        System.out.println("返回后通知-->打印日志");
    }

    //抛出异常后通知
    public void afterThrow() {
        System.out.println("抛出异常后通知-->打印日志");
    }

    /**
     * 环绕通知 形参需要传入ProceedingJoinPoint(由Spring提供,不用自己创建)
     *  必须传入ProceedingJoinPoint,否则跟前置通知没有区别
     *  ProceedingJoinPoint的方法
     *       1、public Object proceed(Object[] args) throws Throwable   用于调用目标方法
     *       2、Object[] getArgs();  用于获取目标方法的参数,可用于修改目标方法的参数
     * @param pjp
     * @return
     * @throws Throwable
     */
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
        Object proceed = null;
        //前置通知
        before();
        try {
            //获取参数
            pjp.getArgs()[0] = "李四";
            System.out.println("环绕通知-->打印日志");
            //调用proceed()方法   这里就会去调用目标方法
            // pjp.proceed();

            //调用proceed()方法  并将设置好的值传递回去 这样子就可以修改目标方法的参数值
            proceed = pjp.proceed(pjp.getArgs());

            //返回后通知
            afterRun();

        } catch (Throwable throwable) {
            //抛异常时通知
            afterThrow();
            throwable.printStackTrace();
        } finally {
            //最终通知
            after();
        }
        return proceed;
    }
}

4.创建Spring核心配置文件(基于xml配置方法)

<!--
      步骤:
       1、使用bean标签创建目标实现类对象,并交给Spring的IOC容器管理
       2、使用bean标签创建通知类对象,并交给Spring的IOC容器管理
       3、使用<aop:config>定义aop的配置
          3.1  在<aop:config>里面使用<aop:aspect ref="通知类的唯一标识">配置切面,使用ref属性,获取IOC容器中已经创建好的通知类
          3.2  在<aop:aspect>里面使用<aop:pointcut>设置切入点
          3.3  配置切入点的标签<aop:通知类型 method="通知类中的方法" pointcut="切入点表达式">可以定义多个切入点
-->
 <!--  1、使用bean标签创建MyAdvice通知类,交给Spring管理 -->
    <bean id="myAdvice" class="com.itheima.Advice.MyAdvice"/>

    <!--   2、使用bean标签创建TargetImpl的对象的,交给Spring管理 -->
    <bean id="target" class="com.itheima.service.impl.TargetImpl"/>

    <!--
         3、使用<aop:com.itheima.config>标签设置AOP
             <aop:aspect> 设置通知对应的和切入点
     -->
    <aop:config>
        <!-- 配置切入点表达式 这里直接指定目标方法名(method)-->
        <aop:pointcut id="po" expression="execution(* com.itheima..*.method(..))"/>
        <aop:aspect ref="myAdvice">
           <!-- <aop:before method="before" pointcut="execution(* com.itheima..*.method(..))"/>
            <aop:after method="after" pointcut="execution(* com.itheima..*.method(..))"/>
            <aop:after-returning method="afterRun" pointcut="execution(* com.itheima..*.method(..))"/>
            <aop:after-throwing method="afterThrow" pointcut="execution(* com.itheima..*.method(..))"/>-->
            <!-- 指定了通知类的方法 -->
            <aop:around method="around" pointcut-ref="po"/>
        </aop:aspect>
    </aop:config>

5.测试

 /**
     *  ClassPathXmlApplicationContext对象是用于读取xml格式的配置文件,需要传入xml格式的Spring文件
     *     <T> T getBean(Class<T> requiredType) 方法,需要传入由IOC容器管理的目标对象
     */
    @Test
    public void method() {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        Target target = context.getBean(Target.class);
        String s = target.method("哈哈");
        System.out.println(s);
    }

6.测试结果

前置增强-->打印日志
环绕通知-->打印日志
TargetImpl...李四
返回后通知-->打印日志
最终通知-->打印日志
李四

注意事项:

  1.  环绕通知方法必须传入ProceedingJoinPoint对象的形参,并且需要调用目标方法,否则目标方法不会执行
  2.  Application.xml文件中 
     ref=通知类的唯一标识(必须已经由IOC容器管理的通知类)
    <aop:aspect ref="myAdvice"> 
        其中<aop:通知类型  method=通知方法 pointcut-ref=切入点表达式(用于匹配目标方法的)>
        <aop:around method="around" pointcut-ref="po"/>   
    </aop:aspect>
    当修改了通知方法时,记得要修改通知类型,否则可能达不到想要的效果
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值