spring AOP 练习 配置(XML)切入点 表达式

本文详细介绍了面向切面编程(AOP)的概念,包括连接点、切入点、通知、切面等核心术语,并阐述了AOP在提高代码可重用性、简化编码、高效维护等方面的优势。通过Spring框架,讲解了AOP的XML配置方式,包括切入点表达式、通知类型以及AOP的配置元素。此外,还强调了切入点的配置经验和最佳实践。
摘要由CSDN通过智能技术生成

AOP 面向切面编程,一种编程的范式,开发的一种思路,重点在于组织程序的结构。

AOP也可以说是

一种程序的设计思路,设计模式。是将相同的代码做平级抽取,没有什么子父类联系。

AOP弥补了OOP的不足,基于OOP基础之上进行横向开发

  • uOOP规定程序开发以类为主体模型,一切围绕对象进行,完成某个任务先构建模型

  • uAOP程序开发主要关注基于OOP开发中的共性功能,一切围绕共性功能进行,完成某个任务先构建可能遇到的所有共性功能(当所有功能都开发出来也就没有共性与非共性之分)

AOP优势

  • 提高代码的可重用性;
  • 业务代码编码更简洁;
  • 业务代码维护更高效;
  • 业务功能扩展更便捷;

AOP核心概念 及 术语含义
1.- Joinpoint(连接点):就是方法

2.- Pointcut(切入点):就是挖掉共性功能的方法(要增强的方法)

3.- Advice(通知):就是共性功能,最终以一个方法的形式呈现(怎样增强,增强的内容)

4.- Aspect(切面):就是共性功能与挖的位置的对应关系(切入点+通知=切面)

5.- Target(目标对象):就是挖掉功能的方法对应的类产生的对象,这种对象是无法直接完成最终工作的

6- Weaving(织入):就是将挖掉的功能回填的动态过程

7- Proxy(代理):目标对象无法直接完成工作,需要对其进行功能回填,通过创建原始对象的代理对象实现

8- Introduction(引入/引介) :就是对原始对象无中生有的添加成员变量或成员方法

使用AOP 开发过程

开发阶段
1.制作切入点方法,
2.将共性的代码独立抽取出来,制作成通知
3.在配置文件中,声明切入点
4.在配置文件中,声明切入点与通知的关系(含通知类型),即切面

运行阶段

  • Spring容器加载配置文件,监控所有配置的切入点方法的执行
  • 当监控到切入点方法被运行,使用代理机制,动态创建目标对象代理对象,根据通知类别,在代理对象的对应位置将通知对应的功能织入,完成完整的代码逻辑并运行

AOP开发方式

  • XML方式
  • XML+注解方式
  • 注解方式

AOP开发 XML方式

1.导入相关坐标

 <dependency>
      <groupId>org.aspectj</groupId>
      <artifactId>aspectjweaver</artifactId>
      <version>1.9.4</version>
    </dependency>
 <!--3.开启AOP命名空间-->
    <bean id="userService" class="com.itheima.service.impl.UserServiceImpl"/>
    <!--2.配置共性功能成功spring控制的资源-->
    <bean id="myAdvice" class="com.itheima.aop.AOPAdvice"/>

表明,是从UserServiceImpl抽取出来的

2.确认要抽取的功能,并将其制作成方法保存到专用的类中,删除原始
业务中对应的功能

public class AOPAdvice {
    public  void function(){
        System.out.println("共性功能");
    }
}

3.将所有进行AOP操作的资源加载到IoC容器中
class aop类中抽取出来的通知类的全类名 id 用来获取这个bean的id名称

<bean id="myAdvice" class="com.itheima.aop.AOPAdvice"/>

4.使用配置的方式描述被抽取功能的位置,并描述被抽取功能与对应位置的关系

   <!--4.配置AOP-->
    <aop:config>
        <!--5.配置切入点-->
        <aop:pointcut id="pt" expression="execution(* *..*(..))"/>
        <!--6.配置切面(切入点与通知的关系)-->
        <aop:aspect ref="myAdvice">
            <!--7.配置具体的切入点对应通知中那个操作方法-->
            <aop:before method="function" pointcut-ref="pt"/>
        </aop:aspect>
    </aop:config>

pointcut-ref是 pointcut id;
method 是 aop类中抽取出来的通知类的方法名
ref=“myAdvice” 是 bean 的id 用来找到这个aop类注入的bean

5.运行程序
失败:原因:没有运行主方法、没写坐标、maven配置错误
单词写错

记得在spring配置文件开头加入aop命名空间

       xmlns:aop="http://www.springframework.org/schema/aop"
 http://www.springframework.org/schema/aop
        https://www.springframework.org/schema/aop/spring-aop.xsd

AOP配置(XML)

AspectJ

  • Aspect(切面)用于描述切入点与通知间的关系,是AOP编程中的一个概念

  • AspectJ是基于java语言对Aspect的实现

aop:config 标签
  • 名称:aop:config
  • 类型:标签
  • 归属:beans标签
  • 作用:设置AOP

格式:

<beans>
    <aop:config>……</aop:config>
    <aop:config>……</aop:config>
</beans>

说明:一个beans标签中可以配置多个aop:config标签

aop:aspect
  • 名称:aop:aspect

  • 类型:标签

  • 归属:aop:config标签

  • 作用:设置具体的AOP通知对应的切入点

  • 格式:

<aop:config>
    <aop:aspect ref="beanId">……</aop:aspect>
    <aop:aspect ref="beanId">……</aop:aspect>
</aop:config>
  • 说明:
    一个aop:config标签中可以配置多个aop:aspect标签
  • 基本属性:
    • ref :通知所在的bean的id

aop:pointcut

  • 名称:aop:pointcut
  • 类型:标签
  • 归属:aop:config标签、aop:aspect标签
  • 作用:设置切入点
  • 格式:
<aop:config>
    <aop:pointcut id="pointcutId" expression="……"/>
    <aop:aspect>
        <aop:pointcut id="pointcutId" expression="……"/>
    </aop:aspect>
</aop:config>
  • 说明:
    一个aop:config标签中可以配置多个aop:pointcut标签,且该标签可以配置在aop:aspect标签内

  • 基本属性:

    • id :识别切入点的名称
    • expression :切入点表达式

切入点**

  • 切入点描述的是某个方法
  • 切入点表达式是一个快速匹配方法描述的通配格式,类似于正则表达式

切入点表达式的组成**

  • 切入点描述的是某个方法
  • 切入点表达式是一个快速匹配方法描述的通配格式,类似于正则表达式
    关键字(访问修饰符  返回值  包名.类名.方法名(参数)异常名)
    

​ 关键字:描述表达式的匹配模式(参看关键字列表)
​ 访问修饰符:方法的访问控制权限修饰符
​ 类名:方法所在的类(此处可以配置接口名称)
​ 异常:方法定义中指定抛出的异常
范例:

execution(public User com.itheima.service.UserService.findById(int))

切入点表达式——关键字

  • execution :匹配执行指定方法

  • args :匹配带有指定参数类型的方法

  • within :……

  • this :……

  • target :……

  • @within :……

  • @target :……

  • @args :……

  • @annotation :……

  • bean :……

  • reference pointcut :……

切入点表达式——通配符
  • *:单个独立的任意符号,可以独立出现,也可以作为前缀或者后缀的匹配符出现

    execution(public * com.itheima.*.UserService.find*(*))
    

​ 匹配com.itheima包下的任意包中的UserService类或接口中所有find开头的带有一个参数的方法

  • … :多个连续的任意符号,可以独立出现,常用于简化包名与参数的书写

    execution(public User com..UserService.findById(..))
    

​ 匹配com包下的任意包中的UserService类或接口中所有名称为findById的方法

  • +:专用于匹配子类类型

    execution(* *..*Service+.*(..))
    
切入点表达式——逻辑运算符
  • && :连接两个切入点表达式,表示两个切入点表达式同时成立的匹配

  • || :连接两个切入点表达式,表示两个切入点表达式成立任意一个的匹配

  • ! :连接单个切入点表达式,表示该切入点表达式不成立的匹配

切入点表达式——范例

execution(* *(..))
execution(* *..*(..))
execution(* *..*.*(..))
execution(public * *..*.*(..))
execution(public int *..*.*(..))
execution(public void *..*.*(..))
execution(public void com..*.*(..)) 
execution(public void com..service.*.*(..))
execution(public void com.itheima.service.*.*(..))
execution(public void com.itheima.service.User*.*(..))
execution(public void com.itheima.service.*Service.*(..))
execution(public void com.itheima.service.UserService.*(..))
execution(public User com.itheima.service.UserService.find*(..))
execution(public User com.itheima.service.UserService.*Id(..))
execution(public User com.itheima.service.UserService.findById(..))
execution(public User com.itheima.service.UserService.findById(int))
execution(public User com.itheima.service.UserService.findById(int,int))
execution(public User com.itheima.service.UserService.findById(int,*))
execution(public User com.itheima.service.UserService.findById(*,int))
execution(public User com.itheima.service.UserService.findById())
execution(List com.itheima.service.*Service+.findAll(..))

切入点的三种配置方式

<aop:config>
    <!--配置公共切入点-->
    <aop:pointcut id="pt1" expression="execution(* *(..))"/>
    <aop:aspect ref="myAdvice">
        <!--配置局部切入点-->
        <aop:pointcut id="pt2" expression="execution(* *(..))"/>
        <!--引用公共切入点-->
        <aop:before method="logAdvice" pointcut-ref="pt1"/>
        <!--引用局部切入点-->
        <aop:before method="logAdvice" pointcut-ref="pt2"/>
        <!--直接配置切入点-->
        <aop:before method="logAdvice" pointcut="execution(* *(..))"/>
    </aop:aspect>
</aop:config>

切入点配置经验**

  • 企业开发命名规范严格遵循规范文档进行
  • 先为方法配置局部切入点
  • 再抽取类中公共切入点
  • 最后抽取全局切入点
  • 代码走查过程中检测切入点是否存在越界性包含
  • 代码走查过程中检测切入点是否存在非包含性进驻
  • 设定AOP执行检测程序,在单元测试中监控通知被执行次数与预计次数是否匹配
  • 设定完毕的切入点如果发生调整务必进行回归测试
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

普希托夫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值