Spring框架:全功能栈的应用程序框架——SpringAOP

一、SpringAOP介绍

  • AOP(Aspect Oriented Programming):面向切面编程。
  • 在不修改源代码的基础上,增加新的功能。

二、SpringAOP的 SchemaBase方式实现

1、流程

  1. 导入SpringAOP的jar包。
  2. 在src下创建advice包,并创建前置通知和后置通知类。
    前置通知:实现MethodBeforeAdvice接口
    后置通知:实现AfterReturning 接口
  3. 在applicationcontext.xml文件中配置资源,并声明组装规则。
  4. 从Spring容器中获取代理对象,完成功能开发。

2、概念

  1. 真实对象:要进行功能扩展的对象
  2. 代理对象:完成功能扩展的对象
  3. 切点:要进行功能扩展的方法
  4. 切面:前置/后置通知+切点
  5. 前置通知方法:切点之前执行的方法
  6. 后置通知方法:切点之后执行的方法
  7. 织入:前置/后置通知+切点,形成切面的过程

3、环绕通知

  1. 特点:
    将扩展代码和调用原有切点方法的代码声明在一起,简化扩展流程。也就说环绕通知中包含了前置通知和后置通知。

  2. 使用流程:

    1. 创建一个普通java类,实现环绕通知的接口(MethodInterceptor)。

    2. 在applicationcontext.xml文件中配置环绕通知的bean。

    3. 在组装规则中,使用环绕通知的组装。

4、异常通知

使用:

  1. 创建一个普通java类,实现异常接口(ThrowsAdvice)。
  2. 在applicationcontext.xml文件中配置异常通知的bean。
  3. 在applicationcontext.xml文件中配置组装规则。

注意:建议将异常通知的配置配置在组装规则的最上面。

三、SpringAOP的SchemaBase方法的参数

1、前置通知

  1. Method method:切点的方法对象

  2. Object[] objects:代理方法接收的实参的数组

  3. Object o:真实对象

2、后置通知

  1. Object o:真实方法的返回值

  2. Method method:切点的方法对象

  3. Object[] objects:代理方法接收的实参的数组

  4. Object o:真实对象

3、环绕通知

  • MethodInvocation:可以通过get方法获取以上通知的所有参数。

4、异常通知

  • Exception ex:获取异常信息

四、SpringAOP的AspectJ方式实现

1、概念:

在一个类中,实现声明所有的通知方法,并在配置文件中的切面配置中,指明哪些方法是前置,哪些是后置即可。

2、使用:

  1. 创建web项目,并导入jar包。
  2. 在src下创建MVC包结构。
  3. 在src下创建并配置applicationcontext.xml文件。
    1. 切点的bean
    2. 扩展类的bean
    3. 配置切面
  4. 获取Spring容器中的扩展对象,完成功能操作。

五、AspectJ和SchemaBase方式比较

1、相同点

  • 都能在不修改源码的情况下,实现功能的扩展。

2、不同点

  1. SchemaBased方式基于接口来区别前置和后置和环绕和异常通知的,而AspectJ方式是在配置文件中使用标签来区分
  2. AspectJ方式切点只在Aop:aspect标签下有效。SchemaBased方式的切点在全局有效。SchemaBased的切点的通用性比AspectJ方式要好。
  3. 扩展时涉及参数的流程
    1. AspectJ
      ①切点方法中声明形参完成数据处理
      ②修改通知方法声明形参接收对应的实参
      ③修改配置文件中的切点声明,切点中的方法上声明对应的参数类型。同时还要声明参数的形参名
      ④在通知的配置上声明参数名
      1. Schema
        ①在切点方法上声明形参完成功能处理
        ②在配置文件中修改切点的路径为带有参数的切点
        ③直接在通知方法中的形参中的Object[]中获取参数使用即可

总结:不涉及到参数问题,使用AspectJ方式。涉及到参数,使用SchemaBased方式。

六、SpringAOP的切点声明格式

  1. 切点是某包某类的无参数的方法

    示例:execution(* com.abc.service.impl.Student.test())
  2. 切点是某包某类带有参数的方法

    示例:execution(* com.abc.service.impl.Student.test(String,int))
  3. 切点是某包某类的某个同名的所有方法

    示例:..  表示任意个数任意类型的参数----execution(* com.abc.service.impl.Student.test(..))
  4. 切点是某包下的某类的所有方法

    示例:*表示任意的类名,方法名,包名----execution(* com.abc.service.impl.Student.*(..))
  5. 切点是某包下的所有类的所有方法

    示例:* 表示任意的类名,方法名,包名----execution(* com.abc.service.impl.*.*(..))
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值