Spring AOP 简单的整理

AOP全称是Aspect Oriented Programing,通常译为面向切面编程。利用AOP可以对面向对象编程做很好补充。


项目中遇到的实际运用到的切面编程是某系统日志模块,在原有的某些怎删改查功能已经完成的情况,需要添加对这些功能的操作日志监控共功能,这时候在原来的代码上再去一个一个添加操作记录的功能,显然会很繁琐,接下来就根据实际的功能记录下Spring AOP的运用

@Order(10)
@Aspect
@Component
public class AuditAspect {

	public AuditAspect() {
		// TODO Auto-generated constructor stub
	}

	@Pointcut("execution(public String cn.tiankuan.gcf.controller.*.add*(..))")
	public void addPointcut() {
	}

	@Pointcut("execution(public String cn.xx.gcf.controller.*.update*(..))")
	public void updatePointcut() {
	}

	@Pointcut("execution(public String cn.xx.gcf.controller.*.delete*(..))")
	public void deletePointcut() {
	}
	
	@Pointcut("execution(public String cn.xx.gcf.controller.*.*Pwd(..))")
	public void pwdPointcut() {
	}
	
	@Pointcut("execution(public void cn.xx.gcf.controller.*.*login(..))")
	public void testPointcut(){
	}
	
	@After("addPointcut() || updatePointcut() || deletePointcut() || pwdPointcut() || testPointcut()")
	public void addAadvice(JoinPoint joinPoint) {
		System.out.println("============ 切面 测试 方法执行"+joinPoint.getSignature().getName()+"-"
				+joinPoint.getSignature().getDeclaringTypeName()+"-"
				+joinPoint.getSignature().getModifiers()+"-"
				+joinPoint.getSignature().getDeclaringType()+"-");
		System.out.println();
		Object[] paramValues = joinPoint.getArgs();  
		String[] paramNames = ((CodeSignature) joinPoint.getSignature()).getParameterNames();  
		for(int i=0;i<paramNames.length;i++){  
		     System.out.println(paramNames[i]+","+paramValues[i]);  
		}

	}
	
	@Before("testPointcut()")
	public void aspectTest(JoinPoint joinPoint){ 
		System.out.println("============ 切面 前测试 方法执行"+joinPoint.getSignature().getName());
	}
}

关于aop的一些基础概念如下,转载于:http://blog.csdn.net/u013782203/article/details/51799427点击打开链接

  1. 通知、增强处理(Advice) 就是你想要的功能,也就是上说的安全、事物、日子等。你给先定义好,然后再想用的地方用一下。包含Aspect的一段处理代码
  2. 连接点(JoinPoint) 这个就更好解释了,就是spring允许你是通知(Advice)的地方,那可就真多了,基本每个方法的钱、后(两者都有也行),或抛出异常是时都可以是连接点,spring只支持方法连接点。其他如AspectJ还可以让你在构造器或属性注入时都行,不过那不是咱们关注的,只要记住,和方法有关的前前后后都是连接点。
  3. 切入点(Pointcut) 上面说的连接点的基础上,来定义切入点,你的一个类里,有15个方法,那就有十几个连接点了对吧,但是你并不想在所有方法附件都使用通知(使用叫织入,下面再说),你只是想让其中几个,在调用这几个方法之前、之后或者抛出异常时干点什么,那么就用切入点来定义这几个方法,让切点来筛选连接点,选中那几个你想要的方法。
  4. 切面(Aspect) 切面是通知和切入点的结合。现在发现了吧,没连接点什么事,链接点就是为了让你好理解切点搞出来的,明白这个概念就行了。通知说明了干什么和什么时候干(什么时候通过方法名中的befor,after,around等就能知道),二切入点说明了在哪干(指定到底是哪个方法),这就是一个完整的切面定义。
  5. 引入(introduction) 允许我们向现有的类添加新方法属性。这不就是把切面(也就是新方法属性:通知定义的)用到目标类中吗
  6. 目标(target) 引入中所提到的目标类,也就是要被通知的对象,也就是真正的业务逻辑,他可以在毫不知情的情况下,被咋们织入切面。二自己专注于业务本身的逻辑。
  7. 代理(proxy) 怎么实现整套AOP机制的,都是通过代理,这个一会儿给细说。
  8. 织入(weaving) 把切面应用到目标对象来创建新的代理对象的过程。有三种方式,spring采用的是运行时 

基础的注解:

@Aspect//声明切面,标记类 

@Pointcut("execution(* *.perform(..))"//定义切点,标记方法  

@Before("performance()")  //切点之前执行

@AfterReturning("performance()")  //切点之后执行

@AfterThrowing("performance()")  //切点抛出异常后执行


Spring AOP 的注解配置并不复杂:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context"
	xmlns:task="http://www.springframework.org/schema/task"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xsi:schemaLocation="http://www.springframework.org/schema/mvc 
	http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd 
	http://www.springframework.org/schema/beans 
	http://www.springframework.org/schema/beans/spring-beans-3.2.xsd 
	http://www.springframework.org/schema/context 
	http://www.springframework.org/schema/context/spring-context-3.2.xsd 
	http://www.springframework.org/schema/task 
	http://www.springframework.org/schema/task/spring-task-3.2.xsd 
	http://www.springframework.org/schema/aop 
	http://www.springframework.org/schema/aop/spring-aop-3.2.xsd">

springde xml配置文件中加入aop相关的命名空间

	<!-- 	切面配置 -->
	<aop:aspectj-autoproxy proxy-target-class="true" />  

 开启aop的注解配置,配置就基本完成了


下面整理一下基础的几个切面的使用方法:

@Aspect
@Component
public class AspectAction {
	
	@Pointcut("execution(public String myMaven.action.*.*(..))")
	public void testPointcut(){	   //myMaven.action
	}
	@Pointcut("execution(public String myMaven.action.*.*(..))")
	public void testPointcut01(){	  
	}
	
	@Before("testPointcut()")
	public void aspectTest01(JoinPoint joinPoint){
		System.out.println("============before 切面 方法执行");
		Object[] paramValues = joinPoint.getArgs();  
		String[] paramNames = ((CodeSignature) joinPoint.getSignature()).getParameterNames();  
		for(int i=0;i<paramNames.length;i++){  
		     System.out.println(paramNames[i]+","+paramValues[i]);  
		}
	}
	@AfterReturning(returning="rvt", pointcut="testPointcut01()")
	public void aspectTest02(JoinPoint joinPoint,Object rvt){
		System.out.println("============after 切面 方法执行");
		System.out.println("返回值:"+ rvt);
	}
}


上面两个切面分别是方法执行前方法有返回后织入:

方法执行请主要涉及到的是要获取切点方法的参数,joinPoint.getSignature()强转为CodeSignature类后,才可以拿到方法的参数名数组,通过循环可以拿到所有的参数

方法返回后的问题就是要获取该方法的返回值,例子如上,返回值就在第二个参数object  rvt中。



@Pointcut("execution(public String myMaven.action.AspectTestAction.login(..))")
	public void testPointcut02(){
	}


切入点excution表达式的语法

1、execution(): 表达式主体。

2、第一个*号:表示返回类型, *号表示所有的类型。

3、包名:表示需要拦截的包名,后面的两个句点表示当前包和当前包的所有子包,com.sample.service.impl包、子孙包下所有类的方法。

4、第二个*号:表示类名,*号表示所有的类。

5、*(..):最后这个星号表示方法名,*号表示所有的方法,后面括弧里面表示方法的参数,两个句点表示任何参数

具体的使用例子 http://sishuok.com/forum/posts/list/281.html   点击打开链接

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值