一、Spring的AOP的开发(AspectJ的注解的方式)
①、创建web项目,引入jar包
AspectJ核心包:com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar
②、编写目标类并配置交给Spring管理
public class OrderDao { public void save() { System.out.println("保存订单..."); } public void find() { System.out.println("查询订单..."); int i=1/0; } public void update() { System.out.println("修改订单..."); } public String delete() { System.out.println("删除订单..."); return "delete"; } }
<bean id="order" class="com.xxx.spring.dao.OrderDao"/>
③、编写切面类并配置交给Spring管理
public class AspectAnno { /** * 前置通知 获取切入点信息 */ public void before(JoinPoint joinPoint) { System.out.println("前置增强======" + joinPoint); } }
<bean id="aspectAnno" class="com.xxx.spring.dao.AspectAnno"/>
④、使用注解的AOP对象目标类进行增强
Ⅰ、在配置文件中打开注解的AOP开发
<aop:aspectj-autoproxy/>
Ⅱ、在切面类和其内部方法上注解
@Aspect public class AspectAnno { /** * 前置通知 获取切入点信息 * 指定增强的方法 */ @Before(value = "execution(* com.xxx.spring.dao.OrderDao.save(..))") public void before(JoinPoint joinPoint) { System.out.println("前置增强======" + joinPoint); } }
⑤、编写测试类
@SpringJUnitConfig(locations = "classpath:bean.xml") public class SpringDemo { @Autowired private OrderDao orderDao; @Test public void demo2() { orderDao.save(); orderDao.update(); orderDao.delete(); orderDao.find(); } }
二、Spring的注解的AOP的通知类型
①、@Before :前置通知
@Before(value = "execution(* com.xxx.spring.dao.OrderDao.save(..))") public void before(JoinPoint joinPoint) { System.out.println("前置通知 获取切入点信息======" + joinPoint); }
②、@AfterReturning:后置通知
@AfterReturning(value = "execution(* com.xxx.spring.dao.OrderDao.delete(..))",returning = "result") public void writeLog(Object result) { System.out.println("后置通知 获取切入点返回值======" + result); }
③、@Around:环绕通知
@Around(value = "execution(* com.xxx.spring.dao.OrderDao.update(..))") public Object checkPerformance(ProceedingJoinPoint joinPoint) throws Throwable { System.out.println("环绕通知 前 ======"); // 获取切入点 Object obj = joinPoint.proceed(); System.out.println("环绕通知 后======"); return obj; }
④、@AfterThrowing:异常抛出通知
@AfterThrowing(value = "execution(* com.xxx.spring.dao.OrderDao.find(..))",throwing = "ex") public void afterThrowing(Throwable ex) { System.out.println("异常抛出通知 获取异常信息======" + ex.getMessage()); }
⑤、@After:最终通知
@After(value = "execution(* com.xxx.spring.dao.OrderDao.find(..))") public void after() { System.out.println("最终通知======"); }
以上的代码每个方法上都需要写value表达式(每个通知都配置了切入点的表达式),如果有多个通知上配置同一个切入点的话,我们就需要修改多次,解决方案:Spring的切入点的配置
三、Spring的切入点的配置
@Aspect public class AspectAnno { @Before(value = "pointcut_save()") public void before(JoinPoint joinPoint) { System.out.println("前置通知 获取切入点信息======" + joinPoint); } @AfterReturning(value = "pointcut_delete()",returning = "result") public void writeLog(Object result) { System.out.println("后置通知 获取切入点返回值======" + result); } @Around(value = "pointcut_update()") public Object checkPerformance(ProceedingJoinPoint joinPoint) throws Throwable { System.out.println("环绕通知 前 ======"); // 获取切入点 Object obj = joinPoint.proceed(); System.out.println("环绕通知 后======"); return obj; } @AfterThrowing(value = "pointcut_find()",throwing = "ex") public void afterThrowing(Throwable ex) { System.out.println("异常抛出通知 获取异常信息======" + ex.getMessage()); } @After(value = "pointcut_find()") public void after() { System.out.println("最终通知======"); } //切入点注解 @Pointcut(value = "execution(* com.xxx.spring.dao.OrderDao.find(..))") private void pointcut_find() {} @Pointcut(value = "execution(* com.xxx.spring.dao.OrderDao.save(..))") private void pointcut_save() {} @Pointcut(value = "execution(* com.xxx.spring.dao.OrderDao.update(..))") private void pointcut_update() {} @Pointcut(value = "execution(* com.xxx.spring.dao.OrderDao.delete(..))") private void pointcut_delete() {} }