首页 > 代码库 > spring AOP 详解

spring AOP 详解

AOP(Aspect Oriented Programming):面向切面编程。
面向切面编程(也叫面向方面编程),是目前软件开发中的一个热点,也是Spring框架中的一个重要内容。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
主要用途:日志记录,性能统计,安全控制,权限管理,事务处理,异常处理,资源池管理。
各个通知:
A 前置通知(Before advice) :在某连接点(JoinPoint)之前执行的通知,但这个通知不能阻止连接点前的执行。xml中在<aop:aspect>里面使用<aop:before>元素进行声明;例如,TestAspect中的doBefore方法。注解中使用@Before声明;例如,TestAnnotationAspect中的doBefore方法。
B 后通知(After advice) :当某连接点退出的时候执行的通知(不论是正常返回还是异常退出)。xml中在<aop:aspect>里面使用<aop:after>元素进行声明。例如,TestAspect中的doAfter方法,所以AOPTest中调用BServiceImpl.barB抛出异常时,doAfter方法仍然执行。注解中使用@After声明。
C 返回后通知(After return advice) :在某连接点正常完成后执行的通知,不包括抛出异常的情况。xml中在<aop:aspect>里面使用<after-returning>元素进行声明。注解中使用@AfterReturning声明;
D 环绕通知(Around advice) :包围一个连接点的通知,类似Web中Servlet规范中的Filter的doFilter方法。可以在方法的调用前后完成自定义的行为,也可以选择不执行。xml中在<aop:aspect>里面使用<aop:around>元素进行声明。例如,TestAspect中的doAround方法。注解中使用@Around声明。
E 抛出异常后通知(After throwing advice) : 在方法抛出异常退出时执行的通知。xml中在<aop:aspect>里面使用<aop:after-throwing>元素进行声明。例如,TestAspect中的doThrowing方法。注解中使用@AfterThrowing声明。
通知执行顺序:前置通知→环绕通知连接点之前→连接点执行→环绕通知连接点之后→返回通知→后通知→(如果发生异常)异常通知→后通知


1、applicationContext.xml文件配置,以下带下划线的几处地方

<beans xmlns="http://www.springframework.org/schema/beans"  
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"  
    xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jdbc="http://www.springframework.org/schema/jdbc"  
    <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/context  
    http://www.springframework.org/schema/context/spring-context-3.0.xsd  
    http://www.springframework.org/schema/tx  
    http://www.springframework.org/schema/tx/spring-tx-3.0.xsd  
    http://www.springframework.org/schema/jdbc  
    http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd  
    http://www.springframework.org/schema/aop 
    http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">  

<aop:aspectj-autoproxy />
......
......
</beans>

2、创建AOP类

package cn.com.abel.springProject.aop;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

@Component  
@Aspect
public class TestAop {
	//环绕通知
	@Around("execution(* cn.com.abel.springProject.service.TestService.sayHello(..))")
	public void aroundExecute(ProceedingJoinPoint point) throws Throwable{
	    System.out.println("================Around start");
	    //参数:point.getArgs()[0]下标表示方法的第几个参数,从0开始。下同
	    point.proceed();  
	    System.out.println("================Around end");  
	}
	
	//前置通知
	@Before("execution(* cn.com.abel.springProject.service.TestService.sayHello(..))")  
	public void beforeExecute(JoinPoint point) throws Throwable{
		System.out.println("================Before");
		//参数:point.getArgs()[0]
	}
	
	//后置通知
	@AfterReturning("execution(* cn.com.abel.springProject.service.TestService.sayHello(..))")  
	public void afterReturningExecute(JoinPoint point) throws Throwable{
		System.out.println("================AfterReturning");
	}
	
	//抛出异常后通知
	@AfterThrowing("execution(* cn.com.abel.springProject.service.TestService.sayHello(..))")  
	public void afterThrowingExecute(JoinPoint point) throws Throwable{
		System.out.println("================AfterThrowing");
	}
	
	//最终通知
	@After("execution(* cn.com.abel.springProject.service.TestService.sayHello(..))")  
	public void afterExecute(JoinPoint point) throws Throwable{
		System.out.println("================After");
	}
}


3、目标方法

package cn.com.abel.springProject.service;

import org.springframework.stereotype.Service;

@Service
public class TestService {

	public String sayHello(Integer age, String name){
	     System.out.println("================hello word");

	}
}


TestService.sayHello方法,无异常情况下输出结果:

================Around start
================Before
================hello word
================AfterReturning
================Around end
================After


出现异常时的结果:

================Around start
================Before
================hello word
================AfterThrowing
================After


spring AOP 详解