springAOP基本概念和配置

原文地址:http://blog.csdn.net/csh624366188/article/details/7651702

先我们来看一下官方文档所给我们的关于AOP的一些概念性词语的解释:

切面(Aspect):一个关注点的模块化,这个关注点可能会横切多个对象。事务管理是J2EE应用中一个关于横切关注点的很好的例子。在Spring AOP中,切面可以使用基于模式)或者基于Aspect注解方式来实现。通俗点说就是我们加入的切面类(比如log类),可以这么理解。

连接点(Joinpoint):在程序执行过程中某个特定的点,比如某方法调用的时候或者处理异常的时候。在Spring AOP中,一个连接点总是表示一个方法的执行。通俗的说就是加入切点的那个点

通知(Advice):在切面的某个特定的连接点上执行的动作。其中包括了“around”、“before”和“after”等不同类型的通知(通知的类型将在后面部分进行讨论)。许多AOP框架(包括Spring)都是以拦截器做通知模型,并维护一个以连接点为中心的拦截器链。

切入点(Pointcut):匹配连接点的断言。通知和一个切入点表达式关联,并在满足这个切入点的连接点上运行(例如,当执行某个特定名称的方法时)。切入点表达式如何和连接点匹配是AOP的核心:Spring缺省使用AspectJ切入点语法。

引入(Introduction):用来给一个类型声明额外的方法或属性(也被称为连接类型声明(inter-type declaration))。Spring允许引入新的接口(以及一个对应的实现)到任何被代理的对象。例如,你可以使用引入来使一个bean实现IsModified接口,以便简化缓存机制。

目标对象(Target Object): 被一个或者多个切面所通知的对象。也被称做被通知(advised)对象。 既然Spring AOP是通过运行时代理实现的,这个对象永远是一个被代理(proxied)对象。

AOP代理(AOP Proxy):AOP框架创建的对象,用来实现切面契约(例如通知方法执行等等)。在Spring中,AOP代理可以是JDK动态代理或者CGLIB代理。

织入(Weaving):把切面连接到其它的应用程序类型或者对象上,并创建一个被通知的对象。这些可以在编译时(例如使用AspectJ编译器),类加载时和运行时完成。Spring和其他纯Java AOP框架一样,在运行时完成织入。

通知类型:

前置通知(Before advice):在某连接点之前执行的通知,但这个通知不能阻止连接点之前的执行流程(除非它抛出一个异常)。

后置通知(After returning advice):在某连接点正常完成后执行的通知:例如,一个方法没有抛出任何异常,正常返回。

异常通知(After throwing advice):在方法抛出异常退出时执行的通知。

最终通知(After (finally) advice):当某连接点退出的时候执行的通知(不论是正常返回还是异常退出)。

环绕通知(Around Advice):包围一个连接点的通知,如方法调用。这是最强大的一种通知类型。环绕通知可以在方法调用前后完成自定义的行为。它也会选择是否继续执行连接点或直接返回它自己的返回值或抛出异常来结束执行。

环绕通知是最常用的通知类型。和AspectJ一样,Spring提供所有类型的通知,我们推荐你使用尽可能简单的通知类型来实现需要的功能。例如,如果你只是需要一个方法的返回值来更新缓存,最好使用后置通知而不是环绕通知,尽管环绕通知也能完成同样的事情。用最合适的通知类型可以使得编程模型变得简单,并且能够避免很多潜在的错误。比如,你不需要在JoinPoint上调用用于环绕通知的proceed()方法,就不会有调用的问题。

spring AOP的实现

在spring2.5中,常用的AOP实现方式有两种。第一种是基于xml配置文件方式的实现,第二种是基于注解方式的实现。接下来,以具体的示例来讲解这两种方式的使用。下面我们要用到的实例是一个注册,就有用户名和密码,我们利用AOP来实现在用户注册的时候实现在保存数据之前和之后或者是抛出异常时,在这些情况下都给他加上日志。在这里我们只讲解AOP,所以我只把关键代码贴出来,不相干的就不贴了。

首先我们来看一下业务逻辑service层:

[java] view plaincopyprint?

  1. /**
  2. * RegisterService的实现类
  3. * @author 曹胜欢 */
  4. public class RegisterServiceImpl implements RegisterService {
  5. private  RegisterDao registerDao;
  6. public RegisterServiceImpl() {}
  7. /** 带参数的构造方法 */
  8. public RegisterServiceImpl(RegisterDao  registerDao){
  9. this.registerDao =registerDao;
  10. }
  11. public void save(String loginname, String password) {
  12. registerDao.save(loginname, password);
  13. throw new RuntimeException("故意抛出一个异常。。。。");
  14. }
  15. /** set方法 */
  16. public void setRegisterDao(RegisterDao registerDao) {
  17. this.registerDao = registerDao;
  18. }}

对于业务系统来说,RegisterServiceImpl类就是目标实现类,它的业务方法,如save()方法的前后或代码会出现异常的地方都是AOP的连接点。

下面是日志服务类的代码:

[java] view plaincopyprint?

  1. /**
  2. * 日志切面类
  3. * @author 曹胜欢
  4. */
  5. public class LogAspect {
  6. //任何通知方法都可以将第一个参数定义为 org.aspectj.lang.JoinPoint类型
  7. public void before(JoinPoint call) {
  8. //获取目标对象对应的类名
  9. String className = call.getTarget().getClass().getName();
  10. //获取目标对象上正在执行的方法名
  11. String methodName = call.getSignature().getName();
  12. System.out.println("前置通知:" + className + "类的" + methodName + "方法开始了");
  13. }
  14. public void afterReturn() {
  15. System.out.println("后置通知:方法正常结束了");
  16. }
  17. public void after(){
  18. System.out.println("最终通知:不管方法有没有正常执行完成,一定会返回的");
  19. }
  20. public void afterThrowing() {
  21. System.out.println("异常抛出后通知:方法执行时出异常了");
  22. }
  23. //用来做环绕通知的方法可以第一个参数定义为org.aspectj.lang.ProceedingJoinPoint类型
  24. public Object doAround(ProceedingJoinPoint call) throws Throwable {
  25. Object result = null;
  26. this.before(call);//相当于前置通知
  27. try {
  28. result = call.proceed();
  29. this.afterReturn(); //相当于后置通知
  30. } catch (Throwable e) {
  31. this.afterThrowing();  //相当于异常抛出后通知
  32. throw e;
  33. }finally{
  34. this.after();  //相当于最终通知
  35. }
  36. return result;
  37. }
  38. }

这个类属于业务服务类,如果用AOP的术语来说,它就是一个切面类,它定义了许多通知。Before()、afterReturn()、after()和afterThrowing()这些方法都是通知。

下面我们就来看具体配置,首先来看一下:

<1>.基于xml配置文件的AOP实现:这种方式在实现AOP时,有4个步骤。

[html] view plaincopyprint?

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:aop="http://www.springframework.org/schema/aop"
  5. xsi:schemaLocation="
  6. http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
  7. http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd>
  8. <bean id="registerDaoImpl" class="com.zxf.dao.RegisterDaoImpl"/>
  9. <bean id="registerService" class="com.zxf.service.RegisterServiceImpl">
  10. <property name=" registerDaoImpl " ref=" RegisterDaoImpl "/>
  11. </bean>
  12. <!-- 日志切面类 -->
  13. <bean id="logAspectBean" class="com.zxf.aspect.LogAspect"/>
  14. <!-- 第1步: AOP的配置 -->
  15. <aop:config>
  16. <!-- 第2步:配置一个切面 -->
  17. <aop:aspect id="logAspect" ref="logAspectBean">
  18. <!-- 第3步:定义切入点,指定切入点表达式 -->
  19. <aop:pointcut id="allMethod"
  20. expression="execution(* com.zxf.service.*.*(..))"/>
  21. <!-- 第4步:应用前置通知 -->
  22. <aop:before method="before" pointcut-ref="allMethod" />
  23. <!-- 第4步:应用后置通知 -->
  24. <aop:after-returning method="afterReturn" pointcut-ref="allMethod"/>
  25. <!-- 第4步:应用最终通知 -->
  26. <aop:after method="after" pointcut-ref="allMethod"/>
  27. <!-- 第4步:应用抛出异常后通知 -->
  28. <aop:after-throwing method="afterThrowing" pointcut-ref="allMethod"/>
  29. <!-- 第4步:应用环绕通知 -->
  30. <!--
  31. <aop:around method="doAround" pointcut-ref="allMethod" />
  32. -->
  33. </aop:aspect>
  34. </aop:config>
  35. </beans>

上述配置针对切入点应用了前置、后置、最终,以及抛出异常后通知。这样在测试执行RegisterServiceImpl类的save()方法时,控制台会有如下结果输出:

前置通知:com.zxf.service.RegisterServiceImpl类的save方法开始了。

针对MySQL的RegisterDao实现中的save()方法。

后置通知:方法正常结束了。

最终通知:不管方法有没有正常执行完成,一定会返回的。

下面我们在来看一下第二种配置方式:

<2>基于注解的AOP的实现

首先创建一个用来作为切面的类LogAnnotationAspect,同时把这个类配置在spring的配置文件中。

在spring2.0以后引入了JDK5.0的注解Annotation的支持,提供了对AspectJ基于注解的切面的支持,从而 更进一步地简化AOP的配置。具体的步骤有两步。

Spring的配置文件是如下的配置:

[html] view plaincopyprint?

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:aop="http://www.springframework.org/schema/aop"
  5. xsi:schemaLocation="
  6. http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
  7. http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd>
  8. <bean id="registerDao" class="com.zxf.dao.RegisterDaoImpl"/>
  9. <bean id="registerService" class="com.zxf.service.RegisterServiceImpl">
  10. <property name="registerDao" ref="registerDao"/>
  11. </bean>
  12. <!-- 把切面类交由Spring容器来管理 -->
  13. <bean id="logAspectBean" class="com.zxf.aspect.LogAnnotationAspect"/>
  14. <!-- 启用spring对AspectJ注解的支持 -->
  15. <aop:aspectj-autoproxy/>
  16. </beans>

这是那个切面的类LogAnnotationAspect

[java] view plaincopyprint?

    1. /**
    2. * 日志切面类
    3. */
    4. @Aspect  //定义切面类
    5. public class LogAnnotationAspect {
    6. @SuppressWarnings("unused")
    7. //定义切入点,提供一个方法,这个方法的名字就是改切入点的id
    8. @Pointcut("execution(* com.zxf.service.*.*(..))")
    9. private void allMethod(){}
    10. //针对指定的切入点表达式选择的切入点应用前置通知
    11. @Before("execution(* com. zxf.service.*.*(..))")
    12. public void before(JoinPoint call) {
    13. String className = call.getTarget().getClass().getName();
    14. String methodName = call.getSignature().getName();
    15. System.out.println("【注解-前置通知】:" + className + "类的"
    16. + methodName + "方法开始了");
    17. }
    18. //访问命名切入点来应用后置通知
    19. @AfterReturning("allMethod()")
    20. public void afterReturn() {
    21. System.out.println("【注解-后置通知】:方法正常结束了");
    22. }
    23. //应用最终通知
    24. @After("allMethod()")
    25. public void after(){
    26. System.out.println("【注解-最终通知】:不管方法有没有正常执行完成,"
    27. + "一定会返回的");
    28. }
    29. //应用异常抛出后通知
    30. @AfterThrowing("allMethod()")
    31. public void afterThrowing() {
    32. System.out.println("【注解-异常抛出后通知】:方法执行时出异常了");
    33. }
    34. //应用周围通知
    35. //@Around("allMethod()")
    36. public Object doAround(ProceedingJoinPoint call) throws Throwable{
    37. Object result = null;
    38. this.before(call);//相当于前置通知
    39. try {
    40. result = call.proceed();
    41. this.afterReturn(); //相当于后置通知
    42. } catch (Throwable e) {
    43. this.afterThrowing();  //相当于异常抛出后通知
    44. throw e;
    45. }finally{
    46. this.after();  //相当于最终通知
    47. }
    48. return result;
    49. }
    50. }
时间: 2024-08-08 04:53:15

springAOP基本概念和配置的相关文章

Oracle GoldenGate学习之--基本概念和配置

Oracle GoldenGate学习之--基本概念和配置(1) 一  GoldenGate简介 Oracle Golden Gate软件是一种基于日志的结构化数据复制备份软件,它通过解析源 数据库在线日志或归档日志获得数据的增量变化,再将这些变化应用到目标数据库,从而实现源数据库与目标数据库同步.Oracle Golden Gate可以在异构的IT基础结构(包括几乎 所有常用操作系统平台和数据库平台)之间实现大量数据亚秒一级的实时复制,从而在可以 在应急系统.在线报表.实时数据仓库供应.交易跟

Oracle GoldenGate学习之--基本概念和配置(2)

Oracle GoldenGate学习之--基本概念和配置(2) 一.Oracle OGG下载: http://www.oracle.com/technetwork/cn/middleware/goldengate/downloads/index.html 二:OGG安装(RedHat EL6) (未完待续)

还原数据自动管理的概念和配置

一.oracle是通过还原表空间来实现还原数据的自动管理的,oracle9i以后才引入还原数据段的自动管理.oracle为每个实例分配一个还原表空间,该表空间要有足够的空间以应对该实例的工作负荷,之后oracle服务器将自动维护和管理还原表空间中的还原数据. 要实习oracle的自动管理还原数据必须在初始化参数文件中配置undo_management,undo_tablespace两个参数而且还必须创建至少一个还原表空间. undo_management:设置管理方式是auto或者manual

spring之aop概念和配置

面向切面的一些概念: 简单说: 连接点就一些方法,在这些方法基础上需要额外的一些业务需求处理. 切入点就是方法所代表的功能点组合起来的功能需求. 通知就是那些额外的操作. 织入就是使用代理实现整个切入的过程. 引入就是已有功能代码不变的基础上,添加新属性和方法. spring使用aop首先xml添加命名空间实例; 并且要在xml 配置中添加<aop:aspectj-autoproxy/>标签,当然对象交给spring管理也要配置bean 环绕通知可以替换上面通知效果: 最终通知在例外通知前执行

JAVAEE——spring01:介绍、搭建、概念、配置详解、属性注入和应用到项目

一.spring介绍 1.三层架构中spring位置 2.spring一站式框架 正是因为spring框架性质是属于容器性质的. 容器中装什么对象就有什么功能.所以可以一站式. 不仅不排斥其他框架,还能帮其他框架管理对象. aop支持.ioc思想.spring jdbc.aop 事务.junit 测试支持 二.spring搭建 1.导包 日志包:com.springsource.org.apache.commons.logging-1.1.1.jar 可选:com.springsource.or

第九回 Microsoft.Practices.Unity.Interception实现基于数据集的缓存(针对六,七,八讲的具体概念和配置的解说)

返回目录 概念 Microsoft.Practices.Unity.Interception是一个拦截器,它隶属于Microsoft.Practices.Unity组成之中,主要完成AOP的功能,而实现AOP方法拦截(页向切面)的基础就是IoC,我们需要配置相关接口或者类型的IoC方式,然后在生产对象时,使用Unity的方法进行动态生产对象,这时,你的Interception拦截器也会起作用! 相关技术 IoC: 控制反转(Inversion of Control,英文缩写为IoC)是一个重要的

SpringCloud系列九:SpringCloudConfig 基础配置(SpringCloudConfig 的基本概念、配置 SpringCloudConfig 服务端、抓取配置文件信息、客户端使用 SpringCloudConfig 进行配置、单仓库目录匹配、应用仓库自动选择、仓库匹配模式)

1.概念:SpringCloudConfig 基础配置 2.具体内容 通过名词就可以发现,SpringCloudConfig 核心作用一定就在于进行配置文件的管理上.也就是说为了更好的进行所有微服务的配置项的管理,在 SpringCloud 设计架构里面就考虑到了针对于所有的核心配置文件(application.yml)进行的一项统一管理的工具. 2.1.SpringCloudConfig 的基本概念 现在可以思考一个问题:在一个实际的项目开发过程之中,有可能会出现有上百个微服务(创建微服务的标

VRRP的基本概念以及配置

O1/VRRP基本概念和工作原理-VRRP基本概念- 随着Internet的发展,人们对网络的可靠性的要求越来越高.对于局域网用户来说,能够时刻与外部网络保持联系是非常重要的.通常情况下,内部网络中的所有主机都设置一条相同的缺省路由,指向出口网关(即图1中的路由器RouterA),实现主机与外部网络的通信.当出口网关发生故障时,主机与外部网络的通信就会中断.配置多个出口网关是提高系统可靠性的常见方法,但局域网内的主机设备通常不支持动态路由协议,如何在多个出口网关之间进行选路是个问题. IETF(

nginx模型概念和配置文件结构

一. nginx模型概念: Nginx会按需同时运行多个进程: 一个主进程(master)和几个工作进程(worker),配置了缓存时还会有缓存加载器进程(cache loader)和缓存管理器进程(cache manager)等. 所有进程均是仅含有一个线程,并主要通过“共享内存”的机制实现进程间通信. 主进程以root用户身份运行,而worker.cache loader和cache manager均应以非特权用户身份(user配置项)运行. 主进程主要完成如下工作: 1. 读取并验正配置信