博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
开涛spring3(6.4) - AOP 之 6.4 基于@AspectJ的AOP
阅读量:6525 次
发布时间:2019-06-24

本文共 4887 字,大约阅读时间需要 16 分钟。

 Spring除了支持Schema方式配置AOP,还支持注解方式:使用@AspectJ风格的切面声明。

6.4.1  启用对@AspectJ的支持

       Spring默认不支持@AspectJ风格的切面声明,为了支持需要使用如下配置:

这样Spring就能发现@AspectJ风格的切面并且将切面应用到目标对象。

6.4.2  声明切面

       @AspectJ风格的声明切面非常简单,使用@Aspect注解进行声明:

@Aspect()      Public class Aspect{      ……      }

然后将该切面在配置文件中声明为Bean后,Spring就能自动识别并进行AOP方面的配置:

该切面就是一个POJO,可以在该切面中进行切入点及通知定义,接着往下看吧。

 

6.4.3  声明切入点

       @AspectJ风格的命名切入点使用org.aspectj.lang.annotation包下的@Pointcut+方法(方法必须是返回void类型)实现。

@Pointcut(value="切入点表达式", argNames = "参数名列表")  public void pointcutName(……) {}

 

value指定切入点表达式;

       argNames指定命名切入点方法参数列表参数名字,可以有多个用“,”分隔,这些参数将传递给通知方法同名的参数,同时比如切入点表达式“args(param)”将匹配参数类型为命名切入点方法同名参数指定的参数类型。

       pointcutName切入点名字,可以使用该名字进行引用该切入点表达式。

@Pointcut(value="execution(* cn.javass..*.sayAdvisorBefore(..)) && args(param)", argNames = "param")      public void beforePointcut(String param) {}

定义了一个切入点,名字为“beforePointcut”,该切入点将匹配目标方法的第一个参数类型为通知方法实现中参数名为“param”的参数类型。

 

6.4.4  声明通知

       @AspectJ风格的声明通知也支持5种通知类型:

 

一、前置通知:使用org.aspectj.lang.annotation 包下的@Before注解声明;

@Before(value = "切入点表达式或命名切入点", argNames = "参数列表参数名")

 value指定切入点表达式或命名切入点;

       argNames与Schema方式配置中的同义。

 

接下来示例一下吧:

1、定义接口和实现,在此我们就使用Schema风格时的定义;

package lqy.springh6_4;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Before;import org.aspectj.lang.annotation.Pointcut;2、定义切面:@Aspect  public class HelloWorldAspect2 {         3、定义切入点:    @Pointcut(value="execution(* lqy.springh6_2..*.sayBefore(..)) && args(param)", argNames = "param")      public void beforePointcut(String param) {}          4、定义通知:    @Before(value = "beforePointcut(param)", argNames = "param")      public void beforeAdvice(String param) {          System.out.println("HelloWorldAspect2:" + param);      }     }

xml配置文件中进行如下配置:

测试

package lqy.springh6_4;import lqy.springh6_2.IHelloWorldService;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;public class test2 {    /**     * @param args     */    public static void main(String[] args) {        ApplicationContext ctx =  new ClassPathXmlApplicationContext("lqy/springh6_4/springh6_4.xml");           IHelloWorldService helloworldService = ctx.getBean("helloWorldService", IHelloWorldService.class);          helloworldService.sayBefore("before");      }}

 

切面、切入点、通知全部使用注解完成:

       1)使用@Aspect将POJO声明为切面;

       2)使用@Pointcut进行命名切入点声明,同时指定目标方法第一个参数类型必须是java.lang.String,对于其他匹配的方法但参数类型 不一致的将也是不匹配的,通过argNames = "param"指定了将把该匹配的目标方法参数传递给通知同名的参数上;

       3)使用@Before进行前置通知声明,其中value用于定义切入点表达式或引用命名切入点;

       4)配置文件需要使用<aop:aspectj-autoproxy/>来开启注解风格的@AspectJ支持;

       5)需要将切面注册为Bean,如“aspect”Bean;

       6)测试代码完全一样。

 

 

二、后置返回通知:使用org.aspectj.lang.annotation 包下的@AfterReturning注解声明;

@AfterReturning(      value="切入点表达式或命名切入点",      pointcut="切入点表达式或命名切入点",      argNames="参数列表参数名",      returning="返回值对应参数名")

       value指定切入点表达式或命名切入点;

       pointcut同样是指定切入点表达式或命名切入点,如果指定了将覆盖value属性指定的,pointcut具有高优先级;

       argNames与Schema方式配置中的同义;

       returning与Schema方式配置中的同义。

 

@AfterReturning(      value="execution(* cn.javass..*.sayBefore(..))",      pointcut="execution(* cn.javass..*.sayAfterReturning(..))",      argNames="retVal", returning="retVal")  public void afterReturningAdvice(Object retVal) {      System.out.println("===========after returning advice retVal:" + retVal);  }

其中测试代码与Schema方式几乎一样,在此就不演示了

 

三、后置异常通知:使用org.aspectj.lang.annotation 包下的@AfterThrowing注解声明

@AfterThrowing (      value="切入点表达式或命名切入点",      pointcut="切入点表达式或命名切入点",      argNames="参数列表参数名",      throwing="异常对应参数名")

       value指定切入点表达式或命名切入点;

       pointcut同样是指定切入点表达式或命名切入点,如果指定了将覆盖value属性指定的,pointcut具有高优先级;

       argNames与Schema方式配置中的同义;

       throwing与Schema方式配置中的同义。

 

@AfterThrowing(      value="execution(* cn.javass..*.sayAfterThrowing(..))",      argNames="exception", throwing="exception")  public void afterThrowingAdvice(Exception exception) {      System.out.println("===========after throwing advice exception:" + exception);  }

其中测试代码与Schema方式几乎一样,在此就不演示了

 

四、后置最终通知:使用org.aspectj.lang.annotation 包下的@After注解声明;

@After (  value="切入点表达式或命名切入点",  argNames="参数列表参数名")

value指定切入点表达式或命名切入点;

       argNames与Schema方式配置中的同义;

 

@After(value="execution(* cn.javass..*.sayAfterFinally(..))")      public void afterFinallyAdvice() {          System.out.println("===========after finally advice");      }

其中测试代码与Schema方式几乎一样,在此就不演示了

 

 

五、环绕通知:使用org.aspectj.lang.annotation 包下的@Around注解声明;

@Around (      value="切入点表达式或命名切入点",      argNames="参数列表参数名")

     value指定切入点表达式或命名切入点;

       argNames与Schema方式配置中的同义;

 

@Around(value="execution(* cn.javass..*.sayAround(..))")  public Object aroundAdvice(ProceedingJoinPoint pjp) throws Throwable {      System.out.println("===========around before advice");      Object retVal = pjp.proceed(new Object[] {"replace"});      System.out.println("===========around after advice");      return retVal;  }

其中测试代码与Schema方式几乎一样,在此就不演示了,如果需要请参考AopTest.java中的annotationAroundAdviceTest测试方法。

6.4.5  引入

省略

 

转载地址:http://scjbo.baihongyu.com/

你可能感兴趣的文章
国际货币基金组织赞扬香港金融规管制度
查看>>
欧时:米其林2019美食排行 全法75家餐馆新上榜
查看>>
中国房企加速并购重组
查看>>
新版IPhone设计毫无创新可言,只靠系统苹果还能撑多久
查看>>
8点1氪|苹果第一财季营收843亿美元;VIPKID拟融资4-5亿美元;工信部称5G终端将于年中推出...
查看>>
一个炫酷大屏展示页的打造过程
查看>>
HenCoder UI 部分 2-2 全新定义 View 的尺寸
查看>>
如何优雅地使用 KVO
查看>>
一个前端工程师的基本修养
查看>>
Spring Boot 揭秘与实战 自己实现一个简单的自动配置模块
查看>>
找对象的过程中,我竟然理解了什么是机器学习!
查看>>
[译] 只有 20 行的 JavaScript 模板引擎
查看>>
30 天精通 RxJS(15): Observable Operators - distinct, distinctUntilChanged
查看>>
WebSocket系列之基础知识入门篇
查看>>
纳税服务系统十【信息发布管理、Ueditor、异步信息交互】
查看>>
怎么优雅使用 react 获取数据
查看>>
如何大幅度提高 Mac 开发效率
查看>>
[译] 模块化 Swift 中的状态
查看>>
记录一次v4包中SwipeRefreshLayout的“坑爹”事件
查看>>
[开源]一个完整的黄页小程序
查看>>