Spring-AOP配置(XML)

目录

AOP基本配置

AspectJ

AOP配置

切入点表达式

切入点表达式的组成

切入点表达式-关键字

切入点表达式-通配符

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

切入点配置经验

五种通知类型配置

通知类型

实例演示

通知顺序

通知获取参数数据

通知获取返回值数据

通知获取异常数据


  • AOP基本配置

  • AspectJ

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

  • 名称:aop:config
  • 类型:标签
  • 归属:beans标签
  • 作用:设置AOP
  • 格式:
  • <beans>
  • <aop:config>.....</aop:config>
  • <aop:config>.....</aop:config>
  • < beans>
  • 说明:一个beans标签中可以配置多个aop:config标签
  • 名称: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: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.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对象,封装原始方法中可能出现的异常信息
  • 实例演示

  • 前置通知
  • 后置通知
  • 返回后通知
  • 抛出异常后通知
  • 环绕通知
  • public class AOPAdvice {
        public void before(){
            System.out.println("before");
        }
        public void after(){
            System.out.println("after");
        }
        public void afterReturing(){
            System.out.println("afterReturing");
        }
        public void afterThrowing(){
            System.out.println("afterThrowing");
        }
        public void around(ProceedingJoinPoint pjp) throws Throwable {
            System.out.println("around before");
            //对原始方法的调用
            pjp.proceed();
            System.out.println("around after");
        }
    }
  • <!--6.配置切面(切入点与通知的关系)-->
            <aop:aspect ref="myAdvice">
                <!--7.配置具体的切入点对应通知中的哪个操作方法-->
                <!--<aop:before method="before" pointcut-ref="pt"/>-->
                <!--<aop:after method="after" pointcut-ref="pt"/>-->
                <!--<aop:after-returning method="afterReturing" pointcut-ref="pt"/>-->
                <!--<aop:after-throwing method="afterThrowing" pointcut-ref="pt"/>-->
                <aop:around method="around" pointcut-ref="pt"/>
            </aop:aspect>
  • 通知顺序

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

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

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

  • 注意:
  • before时,程序还没有运行,肯定拦截不了
  • after-returning时,因为能正常返回,也拦截不到
  • after还是那问题,可能能,可能不能,所以不能
  • 实例:
  • after-throwing
  • around
  • public class UserServiceImpl implements UserService {
        public void save(int i){
            //0.将共性功能抽取出来
            //System.out.println("共性功能");
            System.out.println("user service running..."+i);
            //int i=1/0;
        }
    
        @Override
        public int update() {
            System.out.println("user service update running...");
            return 100;
        }
    
        @Override
        public void delete() {
            System.out.println("user service delete running...");
            int i = 1/0;
        }
    }
  • <aop:aspect ref="myAdvice">
                <!--7.配置具体的切入点对应通知中的哪个操作方法-->
                <!--<aop:before method="before" pointcut-ref="pt"/>-->
                <!--<aop:after method="after" pointcut-ref="pt"/>-->
                <!--<aop:after-returning method="afterReturing" pointcut-ref="pt" returning="ret"/>-->
                <aop:after-throwing method="afterThrowing" pointcut-ref="pt" throwing="t"/>
                <aop:around method="around" pointcut-ref="pt"/>
            </aop:aspect>
  • public class AOPAdvice {
        public void before(JoinPoint jp){
            Object[] args = jp.getArgs();
            System.out.println("before"+args[0]);
        }
        public void after(JoinPoint jp){
            Object[] args = jp.getArgs();
            System.out.println("after"+args[0]);
        }
        public void afterReturing(Object ret){
            System.out.println("afterReturing..."+ret);
        }
        public void afterThrowing(Throwable t){
            System.out.println("afterThrowing..."+t.getMessage());
        }
        public Object around(ProceedingJoinPoint pjp){
            System.out.println("around before");
            //对原始方法的调用
            Object ret = null;
            try {
                ret = pjp.proceed();
            } catch (Throwable e) {
                System.out.println("around...exception..."+e.getMessage());
            }
            System.out.println("around after..."+ret);
            return ret;
        }
    }
  • public class App {
        public static void main(String[] args) {
            ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
            UserService userService = (UserService) ctx.getBean("userService");
            //userService.save(666);
            //int tj = userService.update();
            //System.out.println("app......"+tj);
            userService.delete();
        }
    }
  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

兔子队列

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

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

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

打赏作者

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

抵扣说明:

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

余额充值