在使用面向切面编程时,我们可以在一个地方定义通用的共鞥,但是可以通过声明的方式定义这个功能要以何种方式在何处应用,而无需修改受影响的类。横切关注点可以被模块化为特殊的类,这些类被称为切面。这样的优点是:每个关注点都集中在一个地方,而不是分散到多处的代码中;其次,服务模块更简洁,它们只包含主要关注点的代买,而次要关注点的代码被转移到切面中。

AOP是Aspect Oriented Programming的简称,被译为面向切面的编程。

AOP允许你把遍布应用各处的功能分离出来形成可重用的组件。

通知(Advice)

  在AOP中,切面的工作被称为通知。通知定义了切面是什么以及何时使用。

  Spring切面可以应用5中类型的通知:

    前置通知(Before):在目标方法被调用之前调用通知

    后置通知(After):在目标方法完成之后调用通知,此时不会关心方法的输出是什么

    返回通知(After-returning):在目标方法成功执行之后调用通知

    异常通知(After-throwing):在目标方法跑出异常后调用通知

    环绕通知(Around):通知包裹了被通知的方法,在被通知的方法调用之前和调用之后执行自定义的行为

连接点(Joinpoint)

  程序执行的某个特定位置;一个类或一段程序代码拥有一些具有边界性质的特定,这些代码中的特定点就称为连接点。Spring仅支持方法的连接点,即仅能在方法调用前、方法调用后、方法抛出异常时以及方法调用前后这些程序执行点织入增强。连接点由两个信息确定:第一是用方法表示的程序执行点;第二是用相对点表示的方位。

切点(Pointcut)

  切点的定义会匹配通知所要织入的一个或多个连接点。通常用明确的类和方法名称或是利用正则表达式定义所匹配的类和方法名称来指定这些切点。

<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
>
<bean id="minstrel" class="com.spronginaction.aop.Minstrel">
</bean> <aop:config>
<aop:aspect ref="minstrel">
<aop:pointcut id="embark" expression="execution(* *.embarkOnQuest()">
<aop:before pointcut-ref="emark" method="singBeforeQuest"/> //声明前置通知
<aop:after pointcut-ref="emark" method='singAfterQuest" /> //声明后置通知
</aop:aspect>
</aop:config> </beans>

横切关注点(cross-cutting concern):散布于应用中多处的功能被称为横切关注点。通常来说,这些横切关注点从概念上是与应用的业务逻辑相分离的

切面(Aspect)

  切面是通知和切点的结合。

引入(Introduction)

  引入允许我们向现有的类添加新方法或属性。

织入(Weaving)

  织入是把切面应用到目标对象并创建新的代理对象的过程。切面在指定的连接点被织入到目标对象中。

  在目标对象的生命周期里有多个点可以进行织入:

    编译器:切面在目标类编译时被织入。这种方式需要特殊的编译器。AspectJ的织入编译器就是以这种方式织入切面的

    类加载器:切面在目标类加载到JVM时被织入。这种方式需要特殊的类加载器,它可以在目标类被引入应用之前增强该目标类的字节码。Aspect5的加载时织入(load-time weaving, LTW)就支持以这种方式织入切面

    运行期:切面在应用运行的某个时刻被织入。一般情况下,在织入切面时,AOP容易会以目标对象动态地创建一个代理对象。Spring AOP就是以这种方式织入切面的

在Spring AOP中,要使用AspectJ的切点表达式语言来定义切点。而且Spring仅支持AspecctJ切点指示器的一个子集。

AspectJ指示器      描述

arg()      限制连接点匹配参数为指定类型的执行方法

@args()     限制连接点匹配参数由指定注解标注的执行方法

execute()     用于匹配时连接点的执行方法

this()         限制连接点匹配AOP代理的bean引用为指定类型的类

target        限制连接点匹配目标对象为指定类型的类

@target()      限制连接点匹配特定的执行对象,这些对象对应的类要具有指定类型的注解

within()       限制连接点匹配指定的类型

@within()      限制连接点匹配指定注解所标注的类型

@annotation  限定匹配带有指定注解的连接点

execution(* package.class.method(..)) *表示了不关心返回值的类型  ..表明了切点要选择任意的method()方法

e.g:

  execution(* concert.Performance.perform(..)) && within(concert.*)    当concert包下的任意类的方法被调用时,执行perform方法

  execution(* concert.Performance.perform(..)) and bean('beanId')       到id为beanId的bean被调用时,执行perform方法

定义切面

注解          通知

@After                   通知方法会在目标方法返回或抛出异常后调用

@AfterReturning     通知方法会在目标方法返回后调用

@AfterThrowing      通知方法会在目标方法抛出异常后调用

@Around       通知方法会将目标方法封装起来

@Before      通知方法会在目标方法调用之前执行

1.@AspectJ注解表明该类不仅仅是一个POJO,还是一个切面。该类中的方法都是可以使用注解来定义切面的具体行为

2.使用@Ponitcut在切面的一个空方法上设置一个切点表达式。这样可以在通知时将该方法当做参数以避免相同并过长的切点表达式

3.使用@EnableAspectJAutoProxy在JavaConfig中进行注解,启用自动代理功能;也可在xm中添加<aop:aspectj-autoproxy />;无论是JavaConfig还是XML,AspectJ自动代理都会为使用@Aspect注解的bean创建一个代理,这个代理会围绕着所有该切面的切点所匹配的bean。

创建环绕通知---使用注解来创建切面

@Aspect
public class Audience{ @PointCut("execution(** Class.method(..))")
public void performance(){} @Around("performance()")
public void watchPerformance(ProceedingJoinPoint jp){
try{
System.out.println("Silencing cell phons");
System.out.println("Taking seats");
jp.proceed();
System.out.println("CLAP CLAP CLAP");
}catch(Throwable e){
System.out.println("Demanding a refund")
}
}
}

在Spring中,切面只是实现了它们所包装bean相同接口的代理类。当引入接口的方法被调用时,代理会把此调用委托给实现了新接口的某个其他对象。实际上,一个bean的实现被拆分到了多个类中。

@DeclareParent注解由三部分组成:

  value属性指定了哪些类型的bean要引入该接口。

  defaultImpl属性指定了为引入功能提供实现的类

  @DeclareParents注解所标注的静态属性指明了要引入了接口

Spring的自动代理机制将会获取到它的声明,当Spring发现一个bean使用了@Aspect注解时,Spring就会创建一个代理,然后将调用委托给被代理的bean或被引入的实现,这取决于调用的方法属于被代理的bean还是属于被引入的接口。

如果需要声明切面,但又不能为通知类添加注解的时候,此时只能转向XML配置了

在Spring的aop命名空间中,提供了多个元素用来在XML中声明切面:

AOP配置元素            用途

<aop:advisor>        定义AOP通知器

<aop:after>          定义AOP后置通知(不管被通知的方法是否执行成功)

<aop:after-returning>     定义AOP返回通知

<aop:after-throwing>      定义AOP异常通知

<aop:around>         定义AOP环绕通知

<aop:aspect>          定义一个切面

<aop:aspectj-autoproxy>    启用@AspectJ注解驱动的切面

<aop:before>          定义一个AOP前置通知

<aop:config>           顶层的AOP配置元素

<aop:declare-parents>    以透明的方式为通知的对象引入额外的接口

<aop:pointcut>        定义一个切点

<aop:config>
<aop:aspect ref="audience"> <aop:before pointcut="execution(** package.class.method(..))" method="silenceCellPhones" /> <aop:before pointcut="execution(** package.class.method(..))" method="takeSeats" /> <aop:after-returning pointcut="execution(** package.class.method(..))" method="applause" /> <aop:after-throwing pointcut="execution(** package.class.method(..))" method="demandRefund" /> </aop:aspect>
</aop:config>
<aop:config>
<aop:aspect ref="audience"> <aop:pointcut id="performance" expression="execution(** package.class.method(..))" /> <aop:before pointcut-ref="performance" method="silenceCellPhones" /> <aop:before pointcut-ref="performance" method="takeSeats" /> <aop:after-returning pointcut-ref="performance" method="applause" /> <aop:after-throwing pointcut-ref="performance" method="demandRefund"/ > </aop:aspect>
</aop:config>
<aop:config>

    <aop:aspect ref="audience">

        <aop:pointcut id="performance" expression="execution(** package.class.method(..))">

        <aop:around pointcut-ref="performance" method="watchPerformance"/>

    </aop:aspect>

</aop:config>
<aop:config>
<aop:aspect ref="trackCounter">
<aop:pointcut id="trackPlayed" expression="execution(* package.class.method(paramType)) and argss(paramName)" /> <aop:before pointcut-ref="trackPlayed" method="countTrack" />
</aop:aspect>
</aop:config>
<aop:aspect>
<aop:declare-parents type-matching="package.class+" implement-interface="package.class" default-impl="package.class" />
</aop:aspect>

 

Spring面向切面编程的更多相关文章

  1. 快速高效掌握企业级项目中的Spring面向切面编程应用,外带讲面试技巧

    Spring面向切面编程(AOP)是企业级应用的基石,可以这样说,如果大家要升级到高级程序员,这部分的知识必不可少. 这里我们将结合一些具体的案例来讲述这部分的知识,并且还将给出AOP部分的一些常见面 ...

  2. Spring 面向切面编程(AOP)

    Spring 系列教程 Spring 框架介绍 Spring 框架模块 Spring开发环境搭建(Eclipse) 创建一个简单的Spring应用 Spring 控制反转容器(Inversion of ...

  3. Spring面向切面编程(AOP)

    1 spring容器中bean特性 Spring容器的javabean对象默认是单例的. 通过在xml文件中,配置可以使用某些对象为多列. Spring容器中的javabean对象默认是立即加载(立即 ...

  4. 再学习之Spring(面向切面编程)

    一.概念 1.理论 把横切关注点和业务逻辑相分离是面向切面编程所要解决的问题.如果要重用通用功能的话,最常见的面向对象技术是继承(inheritance)或 组成(delegation).但是,如果在 ...

  5. 详解Spring面向切面编程(AOP)三种实现

    一.什么是AOP AOP(Aspect Oriented Programming),即面向切面编程,可以说是OOP(Object Oriented Programming,面向对象编程)的补充和完善. ...

  6. Spring——面向切面编程(AOP)详解

    声明:本博客仅仅是一个初学者的学习记录.心得总结,其中肯定有许多错误,不具有参考价值,欢迎大佬指正,谢谢!想和我交流.一起学习.一起进步的朋友可以加我微信Liu__66666666 这是简单学习一遍之 ...

  7. Spring面向切面编程(AOP,Aspect Oriented Programming)

    AOP为Aspect Oriented Programming的缩写,意为:面向切面编程(也叫面向方面),可以通过预编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态统一添加功能的一种技术. ...

  8. spring面向切面编程示例(xml配置形式vs@注解形式)

    一.xml配置形式 1.在Spring配置文件中增加面向切面配置当调用com.activemq.service.impl.ConsumerServiceImpl接口实现类的任意方法时执行切面类中的方法 ...

  9. JAVA Spring 面向切面编程 基本案例(AOP)

    < 1 > 配置文件 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns=&q ...

随机推荐

  1. JQuery Tree插件

    转载这个,这个非常的全,有时间可以去学习学习:http://ztreeapi.iteye.com/ http://ztreeapi.iteye.com/blog/2028608

  2. java面试之谈

    半个多月的找工作时间,不是在去面试路上,就是在面试中,经历了大概有近10家的面试,虽然很多家都是一回了无音讯,对自己收获还是有的,至少让自己认识到了自身基础不牢固和技术知识面的狭隘.之前从事的工作主要 ...

  3. Zookeeper浏览器工具和Eclipse插件

    公司很多产品会使用zookeeper,比如Meta消息中间件,在测试的过程中,我们经常需要查询zookeeper里面的信息来精确定位问题.目前项目中有开发团队自己写的浏览器node-zk-browse ...

  4. JAVA OCR图片识别

    今天闲来无聊,尝试了一下OCR识别,尝试了以下三种方案: 1.直接使用业界使用最广泛的Tesseract-OCR. Tesseract项目最初由惠普实验室支持,1996年被移植到Windows上,19 ...

  5. ffmpeg+libmp3lame库源码安装教程(CentOS)

    lame--libmp3lame的安装包,支持MP3编码:yasm--NASM的重写,用于编译ffmpeg. 1.下载 ffmpeg下载链接:http://ffmpeg.org/download.ht ...

  6. QAbstractItemView区分单双击

    系统不可能知道你这一次单击鼠标是为了双击指令,所以在你第一次按下鼠标时,系统会发出一个WM_XBUTTONDOWN(也就是clicked), 当你第二次单击鼠标时,系统先发送WM_XBUTTONDOW ...

  7. Python之简单的用户登录和注册

    # -*- coding: utf-8 -*- # @Time : 2018/7/26 20:16 # @Author : Adam # @File : exam2.py # @Project: ke ...

  8. Spring整合Hystrix

    1.添加maven依赖 <dependency> <groupId>com.netflix.hystrix</groupId> <artifactId> ...

  9. std::string find 的返回值

    std::string  的方法 find,返回值类型是std::string::size_type, 对应的是查找对象在字符串中的位置(从0开始), 如果未查找到,该返回值是一个很大的数据(4294 ...

  10. POJ 2373 Dividing the Path(DP + 单调队列)

    POJ 2373 Dividing the Path 描述 农夫约翰的牛发现,在他的田里沿着山脊生长的三叶草是特别好的.为了给三叶草浇水,农夫约翰在山脊上安装了喷水器. 为了使安装更容易,每个喷头必须 ...