一、spring中aop的有关名词解释
其中weaving,也可以说是:将通知应用到连接点形成切入点的过程,是一个动词,然后这个携带通知的切入点会切入到每个需要增强的连接点;
二、spring中aop的演示(使用)步骤:
1、导包
2、准备目标对象(被代理对象)
3、准备(定义)通知类MyAdvice,并在该类里边定义一些通知方法;
1 package cn.itcast.d_springaop; 2 3 import org.aspectj.lang.ProceedingJoinPoint; 4 5 //通知类 6 public class MyAdvice { 7 8 //前置通知 9 // |-目标方法运行之前调用 10 //后置通知(如果出现异常不会调用) 11 // |-在目标方法运行之后调用 12 //环绕通知 13 // |-在目标方法之前和之后都调用 14 //异常拦截通知 15 // |-如果出现异常,就会调用 16 //后置通知(无论是否出现 异常都会调用) 17 // |-在目标方法运行之后调用 18 //---------------------------------------------------------------- 19 //前置通知 20 public void before(){ 21 System.out.println("这是前置通知!!"); 22 } 23 //后置通知 24 public void afterReturning(){ 25 System.out.println("这是后置通知(如果出现异常不会调用)!!"); 26 } 27 //环绕通知 28 public Object around(ProceedingJoinPoint pjp) throws Throwable { 29 System.out.println("这是环绕通知之前的部分!!"); 30 Object proceed = pjp.proceed();//调用目标方法 31 System.out.println("这是环绕通知之后的部分!!"); 32 return proceed; 33 } 34 //异常通知 35 public void afterException(){ 36 System.out.println("出事啦!出现异常了!!"); 37 } 38 //后置通知 39 public void after(){ 40 System.out.println("这是后置通知(出现异常也会调用)!!"); 41 } 42 }
4、配置将通知织入目标对象
(1)使用xml配置(在applicationContext.xml配置)
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 3 xmlns="http://www.springframework.org/schema/beans" 4 xmlns:context="http://www.springframework.org/schema/context" 5 xmlns:aop="http://www.springframework.org/schema/aop" 6 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd "> 7 8 <!-- 准备工作: 导入aop(约束)命名空间 --> 9 <!-- 1.配置目标对象 --> 10 <bean name="userService" class="cn.itcast.service.UserServiceImpl" ></bean> 11 <!-- 2.配置通知对象 --> 12 <bean name="myAdvice" class="cn.itcast.d_springaop.MyAdvice" ></bean> 13 <!-- 3.配置将通知织入目标对象 --> 14 <aop:config> 15 <!-- 配置切入点 以下是不断简化写法的过程: 16 public void cn.itcast.service.UserServiceImpl.save() 17 void cn.itcast.service.UserServiceImpl.save() 18 * cn.itcast.service.UserServiceImpl.save() 19 * cn.itcast.service.UserServiceImpl.*() 20 21 * cn.itcast.service.*ServiceImpl.*(..) 22 * cn.itcast.service..*ServiceImpl.*(..) 23 --> 24
<aop:pointcut expression="execution(* cn.itcast.service.*ServiceImpl.*(..))" id="pc"/> 25
<!--以下的结果是:让携带通知的切点,然后转入上一步,将携带通知的切点切入连接点(即织入连接点)(要增强的方法:* cn.itcast.service.*ServiceImpl.*(..))-->
<aop:aspect ref="myAdvice" > 26 <!-- 指定名为before方法作为前置通知 --> 27 <aop:before method="before" pointcut-ref="pc" /> 28 <!-- 后置 --> 29 <aop:after-returning method="afterReturning" pointcut-ref="pc" /> 30 <!-- 环绕通知 --> 31 <aop:around method="around" pointcut-ref="pc" /> 32 <!-- 异常拦截通知 --> 33 <aop:after-throwing method="afterException" pointcut-ref="pc"/> 34 <!-- 后置 --> 35 <aop:after method="after" pointcut-ref="pc"/> 36 </aop:aspect> 37 </aop:config> 38 </beans>
以下是测试类:
(2)使用注解配置(了解?)
就是将上述(1)中的xml配置(1)(2)(3)步骤换成注解,由于(1)(2)步骤的注解使用之前已经介绍过,这里就只说明一下把步骤(3)换为注解该怎么使用:
首先看配置文件中怎么写:
然后,来看通知类到底怎么用注解代替xml:
1 package cn.itcast.e_annotationaop; 2 3 import org.aspectj.lang.ProceedingJoinPoint; 4 import org.aspectj.lang.annotation.After; 5 import org.aspectj.lang.annotation.AfterReturning; 6 import org.aspectj.lang.annotation.AfterThrowing; 7 import org.aspectj.lang.annotation.Around; 8 import org.aspectj.lang.annotation.Aspect; 9 import org.aspectj.lang.annotation.Before; 10 import org.aspectj.lang.annotation.Pointcut; 11 12 //通知类 13 @Aspect 14 //表示该类是一个通知类 15 public class MyAdvice { 16 @Pointcut("execution(* cn.itcast.service.*ServiceImpl.*(..))")//将切点用注解代替,方便修改,然后再通知的注解里传入"MyAdvice.pc()"参数, 17 public void pc(){} 18 //前置通知 19 //指定该方法是前置通知,并制定切入点 20 @Before("MyAdvice.pc()") 21 public void before(){ 22 System.out.println("这是前置通知!!"); 23 } 24 //后置通知 25 @AfterReturning("execution(* cn.itcast.service.*ServiceImpl.*(..))") 26 public void afterReturning(){ 27 System.out.println("这是后置通知(如果出现异常不会调用)!!"); 28 } 29 //环绕通知 30 @Around("execution(* cn.itcast.service.*ServiceImpl.*(..))") 31 public Object around(ProceedingJoinPoint pjp) throws Throwable { 32 System.out.println("这是环绕通知之前的部分!!"); 33 Object proceed = pjp.proceed();//调用目标方法 34 System.out.println("这是环绕通知之后的部分!!"); 35 return proceed; 36 } 37 //异常通知 38 @AfterThrowing("execution(* cn.itcast.service.*ServiceImpl.*(..))") 39 public void afterException(){ 40 System.out.println("出事啦!出现异常了!!"); 41 } 42 //后置通知 43 @After("execution(* cn.itcast.service.*ServiceImpl.*(..))") 44 public void after(){ 45 System.out.println("这是后置通知(出现异常也会调用)!!"); 46 } 47 }
三、spring中aop的总结和整理(两张图片)
(1)动态代理体现了aop思想
(2)spring中aop的使用(xml配置及原理)