Spring(五)---面向切面的编程(1)

(一)什么是AOP?
AOP(Aspect Oriented Programming),即面向切面编程,可以说是OOP(Object Oriented Programming,面向对象编程)的补充和完善。OOP引入封装、继承、多态等概念来建立一种对象层次结构,用于模拟公共行为的一个集合。不过OOP允许开发者定义纵向的关系,但并不适合定义横向的关系,例如日志功能。日志代码往往横向地散布在所有对象层次中,而与它对应的对象的核心功能毫无关系对于其他类型的代码,如安全性、异常处理和透明的持续性也都是如此,这种散布在各处的无关的代码被称为横切(cross cutting),在OOP设计中,它导致了大量代码的重复,而不利于各个模块的重用。

AOP技术恰恰相反,它利用一种称为”横切”的技术,剖解开封装的对象内部,并将那些影响了多个类的公共行为封装到一个可重用模块,并将其命名为”Aspect”,即切面。所谓”切面”,简单说就是那些与业务无关,却为业务模块所共同调用的逻辑或责任封装起来,便于减少系统的重复代码,降低模块之间的耦合度,并有利于未来的可操作性和可维护性。

使用”横切”技术,AOP把软件系统分为两个部分:核心关注点和横切关注点。业务处理的主要流程是核心关注点,与之关系不大的部分是横切关注点。横切关注点的一个特点是,他们经常发生在核心关注点的多处,而各处基本相似,比如权限认证、日志、事物。AOP的作用在于分离系统中的各种关注点,将核心关注点和横切关注点分离开来。
这里写图片描述
(二)AOP的核心概念

  • 横切关注点:跨越应用程序多个模块的功能;
  • 切面(Aspect):被模块化的横切关注点(即将功能相同的横切关注点封装到同一个模块下);切面是通知和切点的结合,通知和切点共同定义了切面的全部内容—它要完成的目标,在何时和何处完成其功能.
    下图说明下横切关注点和切面
    这里写图片描述
  • 通知(Advice):描述了切面要完成的工作(如:想要在目标方法中插入日志或验证参数,具体是指切面的某个具体方法),通知还解决了何时执行这个工作的问题(它应该在某个方法被调用之前?之后?之前和之后都调用?还是只在方法抛出异常时被调用?例:插入日志是在目标方法之前还是之后?)
    -Spring 切面可以应用五种类型的通知:
    (1) 前置通知(Before):在目标方法被调用之前调用通知功能;
    (2)后置通知(After):在目标方法完成之后调用通知,此时不会关心方法的输出是什么;
    (3)返回通知(After-returning):在目标方法抛出异常后调用通知;
    (4)异常通知(After-throwing):在目标方法抛出异常后调用通知;
    (5)环绕通知(Around):通知包裹了被通知的方法,在被通知的方法,在被通知方法调用之前和调用之后执行自定义的行为
    例:
//前置通知
        System.out.println("Before the method "+methodName+" begin with "+ Arrays.asList(joinPoint.getArgs()));
        //调用目标方法
        Integer result = null;
        try {
             result = (Integer) joinPoint.proceed();
            //返回通知
            System.out.println("After the method "+methodName+ "end with" + result);
        } catch (Throwable e) {
            //异常通知
            System.out.println("After the method "+methodName+ "occur with" + e );
            throw new RuntimeException();
        }
        //后置通知
        System.out.println("After the method "+methodName+ " end");
        return result;
    }
  • 连接点(Join point):连接点是在应用程序执行过程中能够插入切面的一个点.这个点可以是调用方法时,抛出异常时,甚至修改一个字段时.切面代码可以利用这些点插入到应用的正常流程中,并添加新的行为;
  • 目标(Target):被通知的对象;
  • 代理(Proxy):向目标对象应用通知之后创建的对象;
  • 切点:如果说通知定义了切面的”什么”和”何时”的话,那么切点就定义了”何处”.切点的定义会匹配通知所要织入的一个或多个连接点.我们通常使用明确的类和方法名称,或是利用正则表达式定义所匹配的类和方法名称来指定这些切点.
    切点,连接点和通知的关系
    这里写图片描述
  • 引入(introduction): 将切面应用到目标对象并导致代理对象创建的过程;
  • 织入(weave): 是把切面应用到目标对象并创建新的代理对象的过程.在目标对象的声明周期中有多个连接点可以进行织入.
    -编译期:切面在目标类编译时被织入.这种方式需要特殊的编译器.
    -类加载期:切面在目标类加载到JVM时被织入.
    -运行期:切面在某个运行时刻被织入.一般情况下,在织入切面时,AOP容器会为目标对象动态地创建一个代理对象。Spring AOP就是以这种方式织入切面的.
    (三)Spring对AOP的支持
    (1) Spring提供了4种类型的AOP支持:
  • 基于代理的经典Spring AOP;(配置过于复杂,弃用)
  • 纯POJO切面;(借助Spring的aop命名空间,我们可以将纯POJO转换为切面,实际上,这些POJO只是提供了满足切点条件时所要调用的方法,但是这种技术需要XML配置)
  • @AspectJ注解驱动的切面(Spring借鉴了AspectJ的切面,以提供了注解驱动的AOP.本质上,它依然是Spring基于代理的AOP,这种AOP风格的好处在于能够不使用XML来完成功能);
  • 注入式AspectJ切面(适用于Spring各个版本,若AOP需求超过了简单的方法调用[如构造器或属性拦截],那么需要考虑使用AspectJ来实现切面);
    注:前三种都是在Spring AOP实现的变体,Spring AOP构建在动态代理之上,因此,Spring对AOP的支持局限于方法拦截;
    (2)Spring的通知是Java编写的
    Spring所创建的通知都是用标准的Java类编写的.而且,定义通知所应用的切点通常会使用注解或在Spring配置文件里采用XML来编写.
    (3)Spring在运行时通知对象
    通过在代理类中包裹切面,Spring在运行期把切面织入到Spring管理的bean中.如下图所示,代理类封装了目标类,并拦截被通知方法(即目标对象的方法)的调用,再把调用转发给真正的目标bean.当代理拦截到方法调用时,在调用目标bean方法之前,会执行切面逻辑.
    这里写图片描述
    (4)Spring只支持方法级别的连接点
    (四)如何编写基于@AspectJ注解驱动的切面
    Ⅰ定义切面

  • 要在Spring中声明AspectJ切面,只需要在IOC容器中将切面声明为Bean的实例.当在Spring IOC容器中初始化AspectJ切面之后,SpringIOC容器就会为那些与AspectJ切面相匹配的Bean创建实例.(由于SpringAOP是基于Java的动态代理的模式,所以切面只会匹配到接口(interefce),然后会创建一个实现该接口的代理类,代理类的实现包裹了目标对象(即切点表达式所匹配的接口的实现类))


                
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值