我们将向你展示如何将AspectJ注解集成到Spring AOP框架。在这个Spring AOP+ AspectJ 示例中,让您轻松实现拦截方法。

常见AspectJ的注解:
  1. @Before – 方法执行前运行
  2. @After – 运行在方法返回结果后
  3. @AfterReturning – 运行在方法返回一个结果后,在拦截器返回结果。
  4. @AfterThrowing – 运行方法在抛出异常后,
  5. @Around – 围绕方法执行运行,结合以上这三个通知。
 

1. 目录结构

看到这个例子的目录结构。
 

2. Spring Beans

普通 bean 中有几个方法,后来通过 AspectJ 注解拦截。
package com.yiibai.customer.bo;

public interface CustomerBo {

    void addCustomer();

    String addCustomerReturnValue();

    void addCustomerThrowException() throws Exception;

    void addCustomerAround(String name);
} package com.yiibai.customer.bo.impl; import com.yiibai.customer.bo.CustomerBo; public class CustomerBoImpl implements CustomerBo { public void addCustomer(){
System.out.println("addCustomer() is running ");
} public String addCustomerReturnValue(){
System.out.println("addCustomerReturnValue() is running ");
return "abc";
} public void addCustomerThrowException() throws Exception {
System.out.println("addCustomerThrowException() is running ");
throw new Exception("Generic Error");
} public void addCustomerAround(String name){
System.out.println("addCustomerAround() is running, args : " + name);
}
}

4. 启用AspectJ

在 Spring 配置文件,把“<aop:aspectj-autoproxy />”,并定义Aspect(拦截)和普通的bean。

File : applicationContext.xml

<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-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd "> <aop:aspectj-autoproxy /> <bean id="customerBo" class="com.yiibai.customer.bo.impl.CustomerBoImpl" /> <!-- Aspect -->
<bean id="logAspect" class="com.yiibai.aspect.LoggingAspect" /> </beans>

4. AspectJ @Before

在下面例子中,logBefore()方法将在 customerBo接口的 addCustomer()方法的执行之前被执行。
AspectJ的“切入点”是用来声明哪种方法将被拦截,应该参考Spring AOP切入点指南,支持切入点表达式的完整列表。

File : LoggingAspect.java

package com.yiibai.aspect;

import org.aspectj.lang.JoinYiibai;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before; @Aspect
public class LoggingAspect { @Before("execution(* com.yiibai.customer.bo.CustomerBo.addCustomer(..))")
public void logBefore(JoinYiibai joinYiibai) { System.out.println("logBefore() is running!");
System.out.println("hijacked : " + joinYiibai.getSignature().getName());
System.out.println("******");
} }

运行

CustomerBo customer = (CustomerBo) appContext.getBean("customerBo");
customer.addCustomer();

输出结果

logBefore() is running!
hijacked : addCustomer
******
addCustomer() is running

5. AspectJ @After

在下面例子中,logAfter()方法将在 customerBo 接口的 addCustomer()方法的执行之后执行。

File : LoggingAspect.java

package com.yiibai.aspect;

import org.aspectj.lang.JoinYiibai;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.After; @Aspect
public class LoggingAspect { @After("execution(* com.yiibai.customer.bo.CustomerBo.addCustomer(..))")
public void logAfter(JoinYiibai joinYiibai) { System.out.println("logAfter() is running!");
System.out.println("hijacked : " + joinYiibai.getSignature().getName());
System.out.println("******"); } }

运行它

CustomerBo customer = (CustomerBo) appContext.getBean("customerBo");
customer.addCustomer();

输出结果

addCustomer() is running
logAfter() is running!
hijacked : addCustomer
******

6. AspectJ @AfterReturning

在下面例子中,logAfterReturning()方法将在 customerBo 接口的addCustomerReturnValue()方法执行之后执行。此外,还可以截取返回的值使用“returning”属性。

要截取返回的值,对“returning”属性(结果)的值必须用相同的方法参数(结果)。

File : LoggingAspect.java

package com.yiibai.aspect;

import org.aspectj.lang.JoinYiibai;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.AfterReturning; @Aspect
public class LoggingAspect { @AfterReturning(
pointcut = "execution(* com.yiibai.customer.bo.CustomerBo.addCustomerReturnValue(..))",
returning= "result")
public void logAfterReturning(JoinYiibai joinYiibai, Object result) { System.out.println("logAfterReturning() is running!");
System.out.println("hijacked : " + joinYiibai.getSignature().getName());
System.out.println("Method returned value is : " + result);
System.out.println("******");
}
}

运行它

CustomerBo customer = (CustomerBo) appContext.getBean("customerBo");
customer.addCustomerReturnValue();

输出结果

addCustomerReturnValue() is running
logAfterReturning() is running!
hijacked : addCustomerReturnValue
Method returned value is : abc
******

7. AspectJ @AfterReturning

在下面的例子中,如果 customerBo 接口的addCustomerThrowException()方法抛出异常logAfterThrowing()方法将被执行。

File : LoggingAspect.java

package com.yiibai.aspect;

import org.aspectj.lang.JoinYiibai;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.AfterThrowing; @Aspect
public class LoggingAspect { @AfterThrowing(
pointcut = "execution(* com.yiibai.customer.bo.CustomerBo.addCustomerThrowException(..))",
throwing= "error")
public void logAfterThrowing(JoinYiibai joinYiibai, Throwable error) { System.out.println("logAfterThrowing() is running!");
System.out.println("hijacked : " + joinYiibai.getSignature().getName());
System.out.println("Exception : " + error);
System.out.println("******"); }
}

运行它

CustomerBo customer = (CustomerBo) appContext.getBean("customerBo");
customer.addCustomerThrowException();

输出结果

addCustomerThrowException() is running
logAfterThrowing() is running!
hijacked : addCustomerThrowException
Exception : java.lang.Exception: Generic Error
******
Exception in thread "main" java.lang.Exception: Generic Error
//...

8. AspectJ @Around

在下面例子中,logAround()方法将在customerBo接口的addCustomerAround()方法执行之前执行, 必须定义“joinYiibai.proceed();” 控制何时拦截器返回控制到原来的addCustomerAround()方法。

File : LoggingAspect.java

package com.yiibai.aspect;

import org.aspectj.lang.ProceedingJoinYiibai;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Around; @Aspect
public class LoggingAspect { @Around("execution(* com.yiibai.customer.bo.CustomerBo.addCustomerAround(..))")
public void logAround(ProceedingJoinYiibai joinYiibai) throws Throwable { System.out.println("logAround() is running!");
System.out.println("hijacked method : " + joinYiibai.getSignature().getName());
System.out.println("hijacked arguments : " + Arrays.toString(joinYiibai.getArgs())); System.out.println("Around before is running!");
joinYiibai.proceed(); //continue on the intercepted method
System.out.println("Around after is running!"); System.out.println("******"); } }

运行它

CustomerBo customer = (CustomerBo) appContext.getBean("customerBo");
customer.addCustomerAround("yiibai");

输出结果

logAround() is running!
hijacked method : addCustomerAround
hijacked arguments : [yiibai]
Around before is running!
addCustomerAround() is running, args : yiibai
Around after is running!
******

总结

它总是建议采用最少 AspectJ 注解。这是关于Spring AspectJ 的一篇相当长的文章。进一步的解释和例子,请访问下面的参考链接。
下载源代码 – http://pan.baidu.com/s/1boo4f9P

Spring学习(十八)----- Spring AOP+AspectJ注解实例的更多相关文章

  1. spring学习 十八 spring的声明事物

    1.编程式事务: 1.1 由程序员编程事务控制代码.commit与rollback都需要程序员决定在哪里调用,例如jdbc中conn.setAutoCimmit(false),conn.commit( ...

  2. Spring学习十四----------Spring AOP实例

    © 版权声明:本文为博主原创文章,转载请注明出处 实例 1.项目结构 2.pom.xml <project xmlns="http://maven.apache.org/POM/4.0 ...

  3. Spring学习(八)AOP详解

    文章更新时间:2020/04/06 一.一个例子 在上面的例子中,包租婆的核心业务就是签合同,收房租,那么这就够了,灰色框起来的部分都是重复且边缘的事,交给中介商就好了,这就是 AOP 的一个思想:让 ...

  4. Spring学习(十六)----- Spring AOP实例(Pointcut(切点),Advisor)

    在上一个Spring AOP通知的例子,一个类的整个方法被自动拦截.但在大多数情况下,可能只需要一种方式来拦截一个或两个方法,这就是为什么引入'切入点'的原因.它允许你通过它的方法名来拦截方法.另外, ...

  5. Spring学习(十五)----- Spring AOP通知实例 – Advice

    Spring AOP(面向方面编程)框架,用于在模块化方面的横切关注点.简单得说,它只是一个拦截器拦截一些过程,例如,当一个方法执行,Spring AOP 可以劫持一个执行的方法,在方法执行之前或之后 ...

  6. Spring学习十五----------Spring AOP API的Pointcut、advice及 ProxyFactoryBean相关内容

    © 版权声明:本文为博主原创文章,转载请注明出处 实例: 1.项目结构 2.pom.xml <project xmlns="http://maven.apache.org/POM/4. ...

  7. Spring学习(十九)----- Spring的五种事务配置详解

    前段时间对Spring的事务配置做了比较深入的研究,在此之间对Spring的事务配置虽说也配置过,但是一直没有一个清楚的认识.通过这次的学习发觉Spring的事务配置只要把思路理清,还是比较好掌握的. ...

  8. spring学习 十六 spring加载属性文件

    第一步:创建一个properties文件,以数据库链接作为实例db.properties jdbc.url=jdbc:mysql://192.168.153.128:3306/mybaties?cha ...

  9. spring学习 十五 spring的自动注入

    一  :在 Spring 配置文件中对象名和 ref=”id” ,id 名相同使用自动注入,可以不配置<property/>,对应的注解@Autowired的作用 二: 两种配置办法 (1 ...

随机推荐

  1. 【实战项目】【FLEX】#900 实现拖控件功能

    一.功能说明:拖控件的功能(类似FLEX,VS 里面的拖控件). 提示:大家对事件的注册和派发的说法可能不一样.因为在FLEX中和在Java中,叫法有的区别.但是本质是一样的. 注册事件  == 设置 ...

  2. PHP设计模式系列 - 单例

    单例模式 通过提供自身共享实例的访问,单例设计模式用于限制特定对象只能被创建一次. 使用场景 例如数据库实例,一般都会走单例模式. 单例模式可以减少类的实例化 代码:来源InitPHP框架,先检测类有 ...

  3. 解决hibernate双向关系造成的一方重复执行SQl,或者死循环的问题

    系统采用struts-json hibernate3. 在对关联表配置manytoone onetomany双向关联的时候,在执行一方的时候,会发现打印出来的SQL语句多执行了一次或者多次.经过调试, ...

  4. js检测密码强度

    <script> function AuthPasswd(string) {     if(string.length >=6) {         if(/[a-zA-Z]+/.t ...

  5. 一劳永逸部署项目:通过tomcat加载环境变量

    一劳永逸部署项目:通过tomcat加载环境变量 转载自:https://blog.csdn.net/u010414666/article/details/46499953 一.说明 项目中经常会用到x ...

  6. BZOJ4180:字符串计数(SAM,二分,矩阵乘法)

    Description SD有一名神犇叫做Oxer,他觉得字符串的题目都太水了,于是便出了一道题来虐蒟蒻yts1999. 他给出了一个字符串T,字符串T中有且仅有4种字符 'A', 'B', 'C', ...

  7. 【洛谷】【二分答案+贪心】P1316 丢瓶盖

    [题目描述:] 陶陶是个贪玩的孩子,他在地上丢了A个瓶盖,为了简化问题,我们可以当作这A个瓶盖丢在一条直线上,现在他想从这些瓶盖里找出B个,使得距离最近的2个距离最大,他想知道,最大可以到多少呢? [ ...

  8. HBase学习之路 (十一)HBase的协过滤器

    协处理器—Coprocessor 1. 起源 Hbase 作为列族数据库最经常被人诟病的特性包括:无法轻易建立“二级索引”,难以执 行求和.计数.排序等操作.比如,在旧版本的(<0.92)Hba ...

  9. 解决nodejs运行程序卡死之后,程序后台运行的问题

    查看node进程 ps aux | grep node 查出的结果如下 root 1660 0.0 1.5 885024 15892 tty1 Sl+ Mar11 0:00 node server.j ...

  10. python range函数与numpy arange函数,xrange与range的区别

    转自:https://www.cnblogs.com/ymjyqsx/p/6426764.html 1.range()返回的是range object,而np.arange()返回的是numpy.nd ...