Spring 注解形式AOP
AOP 面向切面编程,通过预编译的方式,在运行期通过动态代理实现一种技术,AOP可实现业务与切面的逻辑分离,降低耦合度
一、注解形式的AOP
Aspect:切面
Joinpoint:连接点,要拦截的方法
Pointcut:切点,连接点的集合
Advice:通知,在连接点前后,或异常情况来做的事情。 前置通知,后置通知,返回通知,异常通知,环绕通知
Target:目标对象:代理的目标对象
Weave:织入,切面应用到目标对象,并创建Proxy的过程
1、导包:spring-aop spring-aspect aopalliance weaver
2、引入头信息:
xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation=“http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd"
3、基于注解方式的切面声明
<!-- 开启以注解形式切面的驱动 --> <aop:aspectj-autoproxy/>
4、切面定义,创建一个类,上面加入@Aspect
1 @Aspect 2 public class PermAspect { 3 /** 4 * 第一个* 返回值类型 5 * 第二个* 所有类 6 * 第三个* 所有方法 7 * 第一个.. 包及其子包 8 * 第二个.. 所有参数 9 */ 10 @Pointcut("execution(* com.tx.spring..*.*(..))") 11 public void anyMethod(){ 12 13 } 14 }
5、前置通知
1 /** 2 * 前置通知 3 * anyMethod() 前置通知的切点 4 * args中的参数名,要与方法名中的参数名一致 5 */ 6 @Before(value="anyMethod()&&args(user)") 7 public void preAdvice(User user){ 8 System.out.println(user); 9 user.setUsername("张三"); 10 System.out.println("执行前置通知"); 11 System.out.println("---------------------"); 12 }
6、后置通知
1 /** 2 * 后置通知 3 * anyMethod() 前置通知的切点 4 * args中的参数名,要与方法名中的参数名一致 5 */ 6 @After(value="anyMethod()&&args(user)") 7 public void afterAdvice(User user){ 8 System.out.println("---------------------"); 9 System.out.println("执行后置通知"); 10 }
7、返回通知
/** * 返回通知,可以对业务方法的返回值进行统一加工 */ @AfterReturning(value="anyMethod()",returning="user") public void returnAdvice(User user){ System.out.println("------------"); user.setUsername("李四"); System.out.println("执行返回通知"); }
8、例外通知
/** * 例外通知 * @param ex 抛出的异常 */ @AfterThrowing(pointcut="anyMethod()",throwing="ex") public void exceptionAdvice(Exception ex){ System.out.println("执行例外通知"); ex.printStackTrace(); }
9、环绕通知
/** * 环绕通知 * @param jp 指定的连接点(要拦截的方法) */ @Around("anyMethod()") public Object aroundAdvice(ProceedingJoinPoint jp){ Object[] argsArr = jp.getArgs(); System.out.println("环绕通知前-----参数是:"+argsArr[0]); Object obj = null; try { obj = jp.proceed();//执行要拦截的方法 } catch (Throwable e) { e.printStackTrace(); } System.out.println("环绕通知后-----"); return obj; }