一:什么是AOP
AOP面向切面编程,是一种方法论,是对传统OOP编程的补充。每一个事物逻辑位于一个位置,代码不分散,便于维护和升级,业务模块更加简洁,只包括核心业务代码。
二:AOP的实现
- AspectJ注解
<!--配置自动扫描的包--><context:component-scan base-package="com.spring.aop.impl"></context:component-scan><!--使AspjectJ注解起作用:自动为匹配的类生成代理对象--><aop:aspectj-autoproxy></aop:aspectj-autoproxy>
通知标签 | 通知说明 |
---|---|
@Before | 在目标方法开始之前执行 |
@After | 在目标方法执行后(无论发生异常),执行的通知 |
@AfterReturning | 返回通知,再方法正常结束执行的代码,有返回值 |
@AfterThrowing | 异常通知,在目标方法出现异常会执行的代码,可以访问到异常的对象,且可以指定在出现特定异常时在执行通知代码 |
@Around | 环绕通知,需要携带ProceedingJoinPoint类型的参数,ProceedingJoinPoint是否执行目标方法,且环绕通知必须有返回值,返回值即目标方法的返回值 |
//切面的优先级,级越小,优先级最高。
@Order(2)
//把这个类声明一个切面
@Aspect
//需要把该类放到ioc容器中(@Component)
@Component
public class Aspect {//定义一个方法,用于声明切入点表达式,一般地,该方法不需要添加其他代码//使用@Pointcut来引入切片表达式
// @Pointcut("execution(public int com.spring.aop.impl.*.*(..))")
// public void declareJointPointExpression(){
//
// }
//声明该方法是一个前置通知:在目标方法开始之前执行
//使用切点表达式,实现切点复用。
//如果在其他类
//@Before("全类名.declareJointPointExpression()")
//@Before("declareJointPointExpression()")
@Before("execution(public int com.spring.aop.impl.AtithmeticCalculator.*(int,int))")public void beforeMethod(JoinPoint joinPoint){//joinPoint可以访问链接细节,如方法名字和参数值。//得到方法名字String methodName=joinPoint.getSignature().getName();//得到参数List<Object> args= Arrays.asList(joinPoint.getArgs());//add other code}//后置通知:在目标方法执行后(无论发生异常),执行的通知//在后置通知中还不能访问目标方法执行的结果@After("execution(public int com.spring.aop.impl.*.*(int,int))")public void afterMethod(JoinPoint joinPoint){String methodName=joinPoint.getSignature().getName();System.out.println("The Method "+methodName+" ends");}//返回通知,再方法正常结束执行的代码,有返回值@AfterReturning(value = "execution(public int com.spring.aop.impl.*.*(int,int))",returning ="result")public void afterReturuing(JoinPoint joinPoint,Object result){String methodName=joinPoint.getSignature().getName();//获取结果System.out.println("The Method "+methodName+" ends with"+result);}//异常通知//在目标方法出现异常会执行的代码,可以访问到异常的对象,且可以指定在出现特定异常时在执行通知代码@AfterThrowing(value = "execution(public int com.spring.aop.impl.*.*(int,int))",throwing = "ex")public void afterThrowing(JoinPoint joinPoint,Exception ex){String methodName=joinPoint.getSignature().getName();//获取异常System.out.println("The Method "+methodName+"occurs exception"+ex);}//坏绕通知需要携带ProceedingJoinPoint类型的参数//ProceedingJoinPoint是否执行目标方法,且环绕通知必须有返回值,返回值即目标方法的返回值@Around("execution(public int com.spring.aop.impl.*.*(..))")public Object aroundMethod(ProceedingJoinPoint pjd){Object result=null;String methodName = pjd.getSignature().getName();System.out.println("aroundMethod");//执行目标方法try {//前置通知System.out.println("进入前置通知");System.out.println("The method"+methodName + "begin with" + Arrays.asList(pjd.getArgs()));//执行目标方法result=pjd.proceed();//后置通知System.out.println("进入后置通知");System.out.println("The method end with"+result);} catch (Throwable throwable) {//异常通知System.out.println("进入异常通知");System.out.println("The method occurs exception"+throwable);}//后置通知System.out.println("The method "+methodName + " ends");return result;}
}
- xml注解
<?xml version="1.0" encoding="UTF-8"?>
<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.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"><!--配置bean--><bean id="artihmeticCalculator" class="com.spring.aop.impl.AtithmeticCalculatorImpl"></bean><!--配置切面的bean--><bean id="LoggingAspect" class="com.spring.aop.impl.LoggingAspect"></bean><bean id="vlidationAspect" class="com.spring.aop.impl.VlidationAspect"></bean><!-- 配置AOP--><aop:config><aop:pointcut id="poincut" expression="execution(public int com.spring.aop.impl.*.*(..))"/><aop:aspect ref="loggingAspect" order="2"><aop:before method="beforeMethod" pointcut-ref="poincut"></aop:before><aop:after method="afterMethod" pointcut-ref="poincut"></aop:after><aop:after-throwing method="afterThrowing" pointcut-ref="poincut" throwing="e"></aop:after-throwing><aop:after-returning method="afterReturuing" pointcut-ref="poincut" returning="result"></aop:after-returning><aop:around method="aroundMethod" pointcut-ref="poincut" /></aop:aspect></aop:config>
</beans>