问题:什么是AOP?
答:AOP基本概念:Aspect-Oriented Programming,面向方面编程的简称,Aspect是一种新的模块化机制,用来描述分散在对象、类或方法中的横切关注点(crosscutting concern), 从关注点中分离出横切关注点是面向方面程序设计的核心所在。分离关注点使得解决特定领域问题的代码从业务逻辑中独立出来,业务逻辑的代码中不再含有针对特 定领域问题代码的调用,业务逻辑同特定领域问题的关系通过方面来封装、维护,这样原本分散在整个应用程序中的变动就可以很好地管理起来。
个人理解:所谓的AOP就是把我们的程序的执行看成是一个方块的面包,然后切成了一片一片的吐司--这些吐司就是我们一个一个的方法。然后在这些吐司片的前面,后面、甚至是里面来做一些特定条件下发生的特定事情,比如嵌入几个葡萄干、给前面加苹果酱、给后面加草莓酱这样的事情。。优势在于你可以在自己的AOP方法中规定一个加苹果酱的理由,满足这个理由的话就可以加苹果酱,而不用在每个方法中都特定的指出加苹果酱,加草莓酱什么的··个人理解···。
AOP的实现有很多的方式,我这边使用Spring中自带的aop来做一些业务逻辑的实现。
在Spring中实现aop的方式有两种,分别是通过xml配置和通过注解配置。下面来介绍这两种方式。
在介绍他们之前先看一下项目的结构:
上图中ServiceAspect是我们使用注解的方式来实现AOP的类,InteceptorXML是使用XML来实现AOP的类;TestAop是测试方法;TestServiceImpl;TestService是用来被AOP的动作;(需要明确的是,AOP的动作建议都发生在service层面。)application-context.xml是我的配置文件。
1.通过注解配置。
我注解AOP的代码如下:
package test.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.aspectj.lang.annotation.Pointcut; import org.springframework.stereotype.Component; import test.entity.User; @Component // 声明这是一个组件 @Aspect // 声明这是一个切面bean public class ServiceAspect {	// 配置切入点,该方法无方法体,主要是为了同类中其他方法使用此处配置的切入点 ----见(1)	@Pointcut("execution(* test.service..*.*(..))")	public void aspect() {	}	// 配置前置通知,使用在方法aspect()上注册的切入点,同时接受JoinPoint切入点对象,可以没有该参数 ----见(2)	@Before("aspect()&&args(id)")	public void before(JoinPoint joinPoint, long id) {	System.out.println(id + "------------------");	System.out.println("before-->" + joinPoint);	}	// 配置后置通知,使用在方法aspect()上注册的切入点----见(3)	@After("aspect()&&args(id)")	public void after(JoinPoint joinPoint, long id) {	System.out.println(id + "after----------------------");	System.out.println("after-->" + joinPoint);	}	// 配置环绕通知----见(4)	@Around("aspect()")	public Object around(JoinPoint joinPoint) {	long start = System.currentTimeMillis();	try {	Object o=((ProceedingJoinPoint) joinPoint).proceed();	User user = (User)o;	System.out.println("-----around======="+user.toString());	long end = System.currentTimeMillis();	System.out.println("around -->" + joinPoint + "\tUse time : "	+ (end - start) + " ms!");	return user;	} catch (Throwable e) {	long end = System.currentTimeMillis();	System.out.println("around __>" + joinPoint + "\tUse time : "	+ (end - start) + " ms with exception : " + e.getMessage());	return null;	}	}	// 配置后置返回通知,使用在方法aspect()上注册的切入点----见(5)	@AfterReturning(pointcut = "aspect()", returning = "returnVal")	public void afterReturning(JoinPoint joinPoint, Object returnVal) {	System.out.println("afterReturning executed, return result is "	+ returnVal);	}	// 配置抛出异常后通知,使用在方法aspect()上注册的切入点----见(6)	@AfterThrowing(pointcut = "aspect()", throwing = "ex")	public void afterThrow(JoinPoint joinPoint, Exception ex) {	System.out.println("afterThrow--> " + joinPoint + "\t"	+ ex.getMessage());	} }