举例讲解Java的Spring框架中AOP程序设计方式的使用

 更新时间:2016年04月27日 16:34:00   作者:HotStrong  
这篇文章主要介绍了Java的Spring框架中AOP程序设计方式的使用讲解,文中举的AOP下抛出异常的例子非常实用,需要的朋友可以参考下

1、什么是AOP

AOP是Aspect Oriented Programming的缩写,意思是面向方面编程,AOP实际是GoF设计模式的延续。

2、关于Spring AOP的一些术语:
 A、切面(Aspect):在Spring AOP中,切面可以使用通用类或者在普通类中以@Aspect 注解(@AspectJ风格)来实现
B、连接点(Joinpoint):在Spring AOP中一个连接点代表一个方法的执行
C、通知(Advice):在切面的某个特定的连接点(Joinpoint)上执行的动作。通知有各种类型,其中包括"around"、"before”和"after"等通知。许多AOP框架,包括Spring,都是以拦截器做通知模型, 并维护一个以连接点为中心的拦截器链
D、切入点(Pointcut):定义出一个或一组方法,当执行这些方法时可产生通知,Spring缺省使用AspectJ切入点语法。

3、通知类型
A、前置通知(@Before):在某连接点(join point)之前执行的通知,但这个通知不能阻止连接点前的执行(除非它抛出一个异常)
B、返回后通知(@AfterReturning):在某连接点(join point)正常完成后执行的通知:例如,一个方法没有抛出任何异常,正常返回
C、抛出异常后通知(@AfterThrowing):方法抛出异常退出时执行的通知
D、后通知(@After):当某连接点退出的时候执行的通知(不论是正常返回还是异常退出)
E、环绕通知(@Around):包围一个连接点(join point)的通知,如方法调用。这是最强大的一种通知类型,环绕通知可以在方法调用前后完成自定义的行为,它也会选择是否继续执行连接点或直接返回它们自己的返回值或抛出异常来结束执行
 
4、@AspectJ风格的AOP配置

Spring AOP配置有两种风格:
A、XML风格 = 采用声明形式实现Spring AOP
B、AspectJ风格 = 采用注解形式实现Spring AOP

5、实例

切面类TestAspect

package com.spring.aop; 
/** 
 * 切面 
 */ 
public class TestAspect { 
 
  public void doAfter(JoinPoint jp) { 
    System.out.println("log Ending method: " 
        + jp.getTarget().getClass().getName() + "." 
        + jp.getSignature().getName()); 
  } 
 
  public Object doAround(ProceedingJoinPoint pjp) throws Throwable { 
    long time = System.currentTimeMillis(); 
    Object retVal = pjp.proceed(); 
    time = System.currentTimeMillis() - time; 
    System.out.println("process time: " + time + " ms"); 
    return retVal; 
  } 
 
  public void doBefore(JoinPoint jp) { 
    System.out.println("log Begining method: " 
        + jp.getTarget().getClass().getName() + "." 
        + jp.getSignature().getName()); 
  } 
 
  public void doThrowing(JoinPoint jp, Throwable ex) { 
    System.out.println("method " + jp.getTarget().getClass().getName() 
        + "." + jp.getSignature().getName() + " throw exception"); 
    System.out.println(ex.getMessage()); 
  } 
 
  private void sendEx(String ex) { 
    //TODO 发送短信或邮件提醒 
  } 
}  

package com.spring.service; 
/** 
 * 接口A 
 */ 
public interface AService { 
   
  public void fooA(String _msg); 
 
  public void barA(); 
} 
package com.spring.service; 
/** 
 *接口A的实现类 
 */ 
public class AServiceImpl implements AService { 
 
  public void barA() { 
    System.out.println("AServiceImpl.barA()"); 
  } 
 
  public void fooA(String _msg) { 
    System.out.println("AServiceImpl.fooA(msg:"+_msg+")"); 
  } 
} 
package com.spring.service; 
 
/** 
 *  Service类B 
 */ 
public class BServiceImpl { 
 
  public void barB(String _msg, int _type) { 
    System.out.println("BServiceImpl.barB(msg:"+_msg+" type:"+_type+")"); 
    if(_type == 1) 
      throw new IllegalArgumentException("测试异常"); 
  } 
 
  public void fooB() { 
    System.out.println("BServiceImpl.fooB()"); 
  } 
 
} 

ApplicationContext

<?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-2.0.xsd 
      http://www.springframework.org/schema/aop 
      http://www.springframework.org/schema/aop/spring-aop-2.5.xsd" 
  default-autowire="autodetect"> 
  <aop:config> 
    <aop:aspect id="TestAspect" ref="aspectBean"> 
      <!--配置com.spring.service包下所有类或接口的所有方法--> 
      <aop:pointcut id="businessService" 
        expression="execution(* com.spring.service.*.*(..))" /> 
      <aop:before pointcut-ref="businessService" method="doBefore"/> 
      <aop:after pointcut-ref="businessService" method="doAfter"/> 
      <aop:around pointcut-ref="businessService" method="doAround"/> 
      <aop:after-throwing pointcut-ref="businessService" method="doThrowing" throwing="ex"/> 
    </aop:aspect> 
  </aop:config> 
   
  <bean id="aspectBean" class="com.spring.aop.TestAspect" /> 
  <bean id="aService" class="com.spring.service.AServiceImpl"></bean> 
  <bean id="bService" class="com.spring.service.BServiceImpl"></bean> 
 
</beans> 

 测试类AOPTest

public class AOPTest extends AbstractDependencyInjectionSpringContextTests { 
   
  private AService aService; 
   
  private BServiceImpl bService; 
   
  protected String[] getConfigLocations() { 
    String[] configs = new String[] { "/applicationContext.xml"}; 
    return configs; 
  } 
   
   
  /** 
   * 测试正常调用 
   */ 
  public void testCall() 
  { 
    System.out.println("SpringTest JUnit test"); 
    aService.fooA("JUnit test fooA"); 
    aService.barA(); 
    bService.fooB(); 
    bService.barB("JUnit test barB",0); 
  } 
   
  /** 
   * 测试After-Throwing 
   */ 
  public void testThrow() 
  { 
    try { 
      bService.barB("JUnit call barB",1); 
    } catch (IllegalArgumentException e) { 
       
    } 
  } 
   
  public void setAService(AService service) { 
    aService = service; 
  } 
   
  public void setBService(BServiceImpl service) { 
    bService = service; 
  } 
} 

 
运行结果如下:

log Begining method: com.spring.service.AServiceImpl.fooA 
AServiceImpl.fooA(msg:JUnit test fooA) 
log Ending method: com.spring.service.AServiceImpl.fooA 
process time: 0 ms 
log Begining method: com.spring.service.AServiceImpl.barA 
AServiceImpl.barA() 
log Ending method: com.spring.service.AServiceImpl.barA 
process time: 0 ms 
log Begining method: com.spring.service.BServiceImpl.fooB 
BServiceImpl.fooB() 
log Ending method: com.spring.service.BServiceImpl.fooB 
process time: 0 ms 
log Begining method: com.spring.service.BServiceImpl.barB 
BServiceImpl.barB(msg:JUnit test barB type:0) 
log Ending method: com.spring.service.BServiceImpl.barB 
process time: 0 ms 
 
log Begining method: com.spring.service.BServiceImpl.barB 
BServiceImpl.barB(msg:JUnit call barB type:1) 
log Ending method: com.spring.service.BServiceImpl.barB 
method com.spring.service.BServiceImpl.barB throw exception 
测试异常 

相关文章

  • JDK源码之Vector与HashSet解析

    JDK源码之Vector与HashSet解析

    HashSet、HashMap、ArrayList、LinkedList、Vector这几个在Java编程中经常用到,他们之间有很多联系,有很多相通的地方,我们这次先了解一下Vector与HashSet
    2021-06-06
  • JAVA多线程知识汇总

    JAVA多线程知识汇总

    这篇文章主要介绍了JAVA多线程的相关资料,文中讲解非常细致,代码帮助大家更好的理解和学习,感兴趣的朋友可以了解下
    2020-07-07
  • SpringBoot项目集成xxljob实现全纪录

    SpringBoot项目集成xxljob实现全纪录

    XXL-JOB是一个分布式任务调度平台,本文主要介绍了SpringBoot项目集成xxljob实现全纪录,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-11-11
  • Java8排序stream.sorted()的使用

    Java8排序stream.sorted()的使用

    这篇文章主要介绍了Java8排序stream.sorted()的使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-03-03
  • Java应用启动停止重启Shell脚本模板server.sh

    Java应用启动停止重启Shell脚本模板server.sh

    这篇文章主要为大家介绍了Java应用启动、停止、重启Shell脚本模板server.sh,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-08-08
  • java中实现汉字按照拼音排序(示例代码)

    java中实现汉字按照拼音排序(示例代码)

    这篇文章主要是对java中将汉字按照拼音排序的实现代码进行了详细的分析介绍。需要的朋友可以过来参考下,希望对大家有所帮助
    2013-12-12
  • Java多线程:生产者与消费者案例

    Java多线程:生产者与消费者案例

    这篇文章主要介绍了Java并发编程中的生产者与消费者模型简述,多线程并发是Java编程中最终要的部分之一,需要的朋友可以参考下,希望能给你带来帮助
    2021-07-07
  • IDEA 去除 mybatis.xml 文件黄色警告的图文教程

    IDEA 去除 mybatis.xml 文件黄色警告的图文教程

    这篇文章主要介绍了IDEA 去除 mybatis.xml 文件黄色警告的方法,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-07-07
  • java中HashMap的七种遍历方式小结

    java中HashMap的七种遍历方式小结

    本文主要介绍了java中HashMap的七种遍历方式小结,包括迭代器,For Each,Lambda,Streams API等,具有一定的参考价值,感兴趣的可以了解一下
    2024-01-01
  • 浅谈Java中是否直接可以使用enum进行传输

    浅谈Java中是否直接可以使用enum进行传输

    这篇文章主要介绍了浅谈Java中是否直接可以使用enum进行传输,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-05-05

最新评论