• Spring-AOP配置(XML)


    目录

    AOP基本配置

    AspectJ

    AOP配置

    切入点表达式

    切入点表达式的组成

    切入点表达式-关键字

    切入点表达式-通配符

    切入点表达式-逻辑运算符

    切入点配置经验

    五种通知类型配置

    通知类型

    实例演示

    通知顺序

    通知获取参数数据

    通知获取返回值数据

    通知获取异常数据


    • AOP基本配置

    • AspectJ

    • Aspect(切面)用于描述切入点与通知间的关系,是AOP编程中的一个概念
    • Aspectj是基于java语言对Aspect的实现
    • AOP配置

    • 名称:aop:config
    • 类型:标签
    • 归属:beans标签
    • 作用:设置AOP
    • 格式:
    • .....
    • .....
    • < beans>
    • 说明:一个beans标签中可以配置多个aop:config标签
    • 名称:aop:aspect
    • 类型:标签
    • 归属:aop:config标签
    • 作用:设置具体的AOP通知对应的切入点
    • 格式:
    • .......
    • ..….
    • 说明:
    • 一个aop:config标签中可以配置多个aop:aspect标签
    • 基本属性:
    • ref:通知所在的bean的id
    • 名称:aop:pointcut
    • 类型:标签
    • 归属:aop:config标签、aop:aspect标签
    • 作用:设置切入点
    • 格式:
    • 说明:
    • 一个aop:config标签中可以配置多个aop:pointcut标签,且该标签可以配置在aop:aspect标签内
    • 基本属性:
    • id:识别切入点的名称
    • expression:切入点表达式
    • 切入点表达式

    • 切入点表达式的组成

    • 切入点描述的是某个方法
    • 切入点表达式是一个快速匹配方法描述的通配格式,类似于正则表达式
    • 关健字(访问修饰符 返回值 包名.类名.方法名(参数)异常名)
    • 关键字:描述表达式的匹配模式(参考关键字列表)
    • 访问修饰符:方法的访问控制权限修饰符
    • 类名:方法所在的类(此处可以配置接口名称)
    • 异常:方法定义中指定抛出的异常
    • 范例:
    • execution (public User com.superdemo.service.UserService.findById (int) )
    • 切入点表达式-关键字

    • execution:匹配执行指定方法
    • args:匹配带有指定参数类型的方法
    • within :......
    • this :......
    • target : ......
    • @within : ......
    • @target : ......
    • @args : ......
    • @annotation : ......
    • bean:......
    • reference pointcut : .......
    • 切入点表达式-通配符

    • *:单个独立的任意符号,可以独立出现,也可以作为前缀或者后缀的匹配符出现
    • execution (public * com.superdemo.*.UserService.find* (*) )
    • 匹配com.superdemo包下的任意包中的UserService类或接口中所有find开头的带有一个参数的方法
    • ..:多个连续的任意符号,可以独立出现,常用于简化包名与参数的书写
    • execution (public User com.UserService.findById (..) )
    • 匹配com包下的任意包中的UserService类或接口中所有名称为findByld的方法
    • +:专用于匹配子类类型
    • execution (* *..*Service+.*(..))
    • 切入点表达式-逻辑运算符

    • &&:连接两个切入点表达式,表示两个切入点表达式同时成立的匹配
    • ||:连接两个切入点表达式,表示两个切入点表达式成立任意一个的匹配
    • !:连接单个切入点表达式,表示该切入点表达式不成立的匹配
    • 切入点配置经验

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

    • 通知类型

    • AOP的通知类型共5种
    • 前置通知:原始方法执行前执行,如果通知中抛出异常,阻止原始方法运行
    • 应用:数据校验
    • 后置通知:原始方法执行后执行,无论原始方法中是否出现异常,都将执行通知
    • 应用:现场清理
    • 返回后通知:原始方法正常执行完毕并返回结果后执行,如果原始方法中抛出异常,无法执行
    • 应用:返回值相关数据处理
    • 抛出异常后通知:原始方法抛出异常后执行,如果原始方法没有抛出异常,无法执行
    • 应用:对原始方法中出现的异常信息进行处理
    • 环绕通知:在原始方法执行前后均有对应执行执行,还可以阻止原始方法的执行
    • 应用:十分强大,可以做任何事情
    • 环绕通知方法相关说明
    • 方法须设定Object类型的返回值,否则会拦截原始方法的返回
    • 如果原始方法返回值类型为void, 通知方法也可以设定返回值类型为void,最终返回null
    • 方法需在第一个参数位置设定ProceedingJoinPoint对象,通过该对象调用proceed()方法,实现对原始方法的调用
    • 如省略该参数,原始方法将无法执行
    • 使用proceed()方法调用原始方法时,因无法预知原始方法运行过程中是否会出现异常,强制抛出Throwable对象,封装原始方法中可能出现的异常信息
    • 实例演示

    • 前置通知
    • 后置通知
    • 返回后通知
    • 抛出异常后通知
    • 环绕通知
      1. public class AOPAdvice {
      2. public void before(){
      3. System.out.println("before");
      4. }
      5. public void after(){
      6. System.out.println("after");
      7. }
      8. public void afterReturing(){
      9. System.out.println("afterReturing");
      10. }
      11. public void afterThrowing(){
      12. System.out.println("afterThrowing");
      13. }
      14. public void around(ProceedingJoinPoint pjp) throws Throwable {
      15. System.out.println("around before");
      16. //对原始方法的调用
      17. pjp.proceed();
      18. System.out.println("around after");
      19. }
      20. }
      1. <aop:aspect ref="myAdvice">
      2. <aop:around method="around" pointcut-ref="pt"/>
      3. aop:aspect>
    • 通知顺序

    • 当同一个切入点配置了多个通知时
    • 通知会存在运行的先后顺序,该顺序以通知配置的顺序为准
    • 通知获取参数数据

    • 设定通知方法第一个参数为JoinPoint
    • 通过该对象调用getArgs()方法,获取原始方法运行的参数数组
    • 所有的通知均可以获取参数
    • 实例:
    • 通知获取返回值数据

    • 注意:
    • before时,程序还没有运行,肯定得不了
    • after-throwing绝对不会有,程序都异常了不会有正确结果
    • after在抛异常时也运行,有可能拿不到,不能确定,所以它不会有
    • 实例:
    • after-returning
    • around
    • 通知获取异常数据

    • 注意:
    • before时,程序还没有运行,肯定拦截不了
    • after-returning时,因为能正常返回,也拦截不到
    • after还是那问题,可能能,可能不能,所以不能
    • 实例:
    • after-throwing
    • around
      1. public class UserServiceImpl implements UserService {
      2. public void save(int i){
      3. //0.将共性功能抽取出来
      4. //System.out.println("共性功能");
      5. System.out.println("user service running..."+i);
      6. //int i=1/0;
      7. }
      8. @Override
      9. public int update() {
      10. System.out.println("user service update running...");
      11. return 100;
      12. }
      13. @Override
      14. public void delete() {
      15. System.out.println("user service delete running...");
      16. int i = 1/0;
      17. }
      18. }
      1. <aop:aspect ref="myAdvice">
      2. <aop:after-throwing method="afterThrowing" pointcut-ref="pt" throwing="t"/>
      3. <aop:around method="around" pointcut-ref="pt"/>
      4. aop:aspect>
      1. public class AOPAdvice {
      2. public void before(JoinPoint jp){
      3. Object[] args = jp.getArgs();
      4. System.out.println("before"+args[0]);
      5. }
      6. public void after(JoinPoint jp){
      7. Object[] args = jp.getArgs();
      8. System.out.println("after"+args[0]);
      9. }
      10. public void afterReturing(Object ret){
      11. System.out.println("afterReturing..."+ret);
      12. }
      13. public void afterThrowing(Throwable t){
      14. System.out.println("afterThrowing..."+t.getMessage());
      15. }
      16. public Object around(ProceedingJoinPoint pjp){
      17. System.out.println("around before");
      18. //对原始方法的调用
      19. Object ret = null;
      20. try {
      21. ret = pjp.proceed();
      22. } catch (Throwable e) {
      23. System.out.println("around...exception..."+e.getMessage());
      24. }
      25. System.out.println("around after..."+ret);
      26. return ret;
      27. }
      28. }
      1. public class App {
      2. public static void main(String[] args) {
      3. ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
      4. UserService userService = (UserService) ctx.getBean("userService");
      5. //userService.save(666);
      6. //int tj = userService.update();
      7. //System.out.println("app......"+tj);
      8. userService.delete();
      9. }
      10. }
  • 相关阅读:
    Day10 尚硅谷JUC——线程间通信
    Unity 之 Material (材质)渲染3D对象的重要组件
    java面向对象(上)
    freesql自定义sql和参数查询
    MFC_系统对话框(CFileDialog、字符编码转化ANSI-UTF8-Unicode、Window记事本demo练习)
    C/C++学习笔记 CMake 与 Make有什么区别?
    arc 166 b
    AZO偶氮化合物测试标准法则
    Apache calcite Quickstart
    99%的时间里使用的14个git命令
  • 原文地址:https://blog.csdn.net/weixin_59624686/article/details/126900589