我们将向你展示如何将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. (1)线程的同步机制 (2)网络编程的常识 (3)基于tcp协议的编程模型

    1.线程的同步机制(重点)1.1 基本概念 当多个线程同时访问同一种共享资源时可能会造成数据的覆盖和不一致等问题,此时就需要对线程之间进行协调和通信,该方式就叫线程的同步机制. 如: 2003年左右 ...

  2. PAT 1001 A+B 解题报告

    PAT 1001 A+B 代码链接:传送门 题目链接:传送门 题目简述: 给定两个值a,b: 范围-1000000 <= a, b <= 1000000: 按指定格式输出a+b的结果,例: ...

  3. Crond定时任务

    crond简介 crond是linux下用来周期性的执行某种任务或等待处理某些事件的一个守护进程,与windows下的计划任务类似,当安装完成操作系统后,默认会安装此服务工具,并且会自动启动crond ...

  4. 跟我一起阅读Java源代码之HashMap(二)

    上一节中实现的SimpleHashMap,没有解决冲突的问题,这一节我们继续深入 由于table的大小是有限的,而key的集合范围是无限大的,所以寄希望于hashcode散落,肯定会出现多个key散落 ...

  5. css背景精华所在+前端页面开发流程

    background属性 background属性是css中应用比较多,且比较重要的一个属性,它是负责给盒子设置背景图片和背景颜色的,background是一个复合属性,它可以分解成如下几个设置项: ...

  6. nginx配置解析之客户端真实IP的传递

    前后端分离之后,采用nginx作为静态服务器,并通过反向代理的方式实现接口跨域的方式,在降低开发成本的同时也带来了诸多问题,例如客户端真实IP的获取. 在一些特殊场景下,比如风控和支付流程,往往需要获 ...

  7. AbstractApplicationContext 笔记

    一.这个类的属性 public abstract class AbstractApplicationContext extends DefaultResourceLoader implements C ...

  8. ali验证码推送接口调用

    /** * 发送接口 * @param $info 发送信息的某些参数 * @return bool */ public function send($info) { $config = target ...

  9. HDU5343:MZL's Circle Zhou(SAM,记忆化搜索DP)

    Description Input Output Sample Input Sample Output Solution 题意:给你两个串,分别从两个里面各选出一个子串拼到一起,问能构成多少个本质不同 ...

  10. 使用 BEGINCONTENT() 和 ENDCONTENT() 设定 YII 的 LAYOUTS

    Yii 的 views/layouts 是用来放置 layouts 的目录,在默认的情况下会有 main.php 和 column1.php 和 column2.php. main.php 内容定义了 ...