Spring AOP
AOP面向切面是spring的一项强大功能,通过代理模式方式实现 ,主要的应用需求是实现在单个或多个方法执行之前或之后执行某些特定的操作,应用场景是日志记录、安全控制、事务管理、异常处理等。
在本例中,主要讲解的是如何用注解的方式实现面向切面AOP。spring的面向切面编程有五种通知类型,分别是前置通知、后置通知、环绕通知、返回通知、异常通知,这些通知就是针对切入点方法之前或之后或异常时运行的方法。
前置通知:切入点方法执行之前运行
后置通知:切入点方法执行之后运行
环绕通知:前置通知执行前以及后置通知执行后都会运行
返回通知:环绕通知执行之后运行
异常通知:切入点方法出现异常时运行
第一步:配置spring的bean和aop实现方法
<bean name="userService" class="com.entor.spring.aop.UserServiceImpl"></bean> <bean name="secureHandler" class="com.entor.spring.aop.SecureHandler"></bean> <!-- 自动扫描,注解方法实现AOP --> <aop:aspectj-autoproxy/>
第二步:定义需要切入的类及方法
public interface UserService { public String saveUser(String name,int id); public String saveExt(); }
public class UserServiceImpl implements UserService{ //切入点方法 public String saveUser(String name,int id) { // TODO Auto-generated method stub System.out.println("切入点方法:-----执行UserServiceImpl类saveUser方法 ------返回:"+name+id); return name + id; } //异常通知的测试方法 public String saveExt() { // TODO Auto-generated method stub System.out.println("-----UserServiceImpl saveExt异常通知测试 ------"); int t = 5 / 0; return "SUCCESS"; } }
第三步:定义面向切面的方法
//注解方式配置AOP,声明这是一个面向切面的类 @Aspect public class SecureHandler { //allMethod方法不会被执行 /*@Pointcut注解作用是声明需要切入方法的定义 在这里是切入aop包下的所有子包中的所有类以save开头的方法*/ @Pointcut("execution(* com.entor.spring.aop.*.save*(..))") public void allMethod(){ System.out.println("allMethod"); } @Before("allMethod()") public void checkSecure(JoinPoint jp){ System.out.println("前置通知:----------切入点方法名:"+jp.getSignature().getName()+"------------"); } @After("allMethod()") public void after(JoinPoint jp){ //System.out.println(jp.getClass()); Object[] arg0 = jp.getArgs(); System.out.println("后置通知:"); System.out.println("\t获取类名:"+jp.getTarget().getClass().getName()); System.out.println("\t获取方法名:"+jp.getSignature().getName()); System.out.print("\t获取参数值:"); for(int i=0;i<arg0.length;i++) System.out.print(arg0[i].toString()); System.out.println("----注解配置的Logger-----"); } /** * 方法正常结束后执行的代码 * 返回通知是可以访问到方法的返回值的 */ @AfterReturning(value="allMethod()", returning="result") public void afterReturning(JoinPoint joinPoint, Object result) { String methodName = joinPoint.getSignature().getName(); System.out.println("返回通知:The method " + methodName + " return with " + result); } @Around("allMethod()") public Object around(ProceedingJoinPoint jp) throws Throwable{ Object[] arg0 = jp.getArgs(); String targetName = jp.getTarget().getClass().getName(); String methodName = jp.getSignature().getName(); System.out.println("环绕通知,前置通知及切入点执行之前:"); System.out.println("\t获取类名:"+targetName); System.out.println("\t获取方法名:"+methodName); //这里可以控制切入点方法的执行 Object result = jp.proceed(); System.out.println("环绕通知,切入点及后置通知执行之后:"); for(int i=0;i<arg0.length;i++) System.out.println("\t入参"+(i+1)+":"+arg0[i].toString()); System.out.println("\t返回值:"+result.toString()); return result; } @AfterThrowing(value="allMethod()",throwing="ex") public void afterThrowing(JoinPoint joinPoint,Exception ex ){ Object object = joinPoint.getSignature(); Date date = new Date(); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); String rightnow=sdf.format(date); System.out.println("异常通知:"+rightnow+"执行了【"+object+"方法发生异常......】"+"【异常报告:"+ex+"】"); System.out.println("xxxxxxxxxxxxxxxxxx方法发生异常结束xxxxxxxxxxxxxxxxxx"); } }
各注解的作用:
@Aspect :声明这是一个面向切面的类
@Pointcut:声明需要切入方法的定义,告诉程序我们需要切入哪些方法
@Before: 声明前置通知
@After: 声明后置通知
@AfterReturning 声明返回通知
@Around 声明环绕通知
@AfterThrowing: 声明异常通知
前置、后置、返回、异常通知方法可以接收一个org.aspectj.lang.JoinPoint类对象,在方法中可以调用这个类对象的相应方法获取切入点方法的信息,环绕通知会有一点不同,接收的是一个org.aspectj.lang.ProceedingJoinPoint类对象。
getTarget().getClass().getName() :获取切入点方法所在类的类名
getSignature().getName(): 获取切入点方法的方法名
getArgs(): 获取切入点方法的入参数组
环绕通知接收的ProceedingJoinPoint对象不同之处在于它可以调用proceed()方法来控制切入点方法执行与否,调用proceed()切入点方法就会被执行,反之那么切入点方法什么都不会做。
/** * 面向切面AOP的练习,使用了注解方式和xml配置文件方式 * @author max * */ public class AopTest { public static void main(String[] args) { BeanFactory bean = new ClassPathXmlApplicationContext("applicationContext*.xml"); UserService userService = (UserService)bean.getBean("userService"); //savaUser是切入点方法 System.out.println("--------------------执行saveUser方法-----------------------"); userService.saveUser("面向切面",100); System.out.println("\n\n\n--------------------执行saveExt方法-----------------------"); userService.saveExt(); } }
测试类中执行saveUser()和saveExt()两个方法,saveUser()会正常结束,saveExt()会抛出异常,我们可以对比一下两种情况的不同。
--------------------执行saveUser方法----------------------- 环绕通知,前置通知及切入点执行之前: 获取类名:com.entor.spring.aop.UserServiceImpl 获取方法名:saveUser 前置通知:----------切入点方法名:saveUser------------ 切入点方法:-----执行UserServiceImpl类saveUser方法 ------返回:面向切面100 后置通知: 获取类名:com.entor.spring.aop.UserServiceImpl 获取方法名:saveUser 获取参数值:面向切面100----注解配置的Logger----- 环绕通知,切入点及后置通知执行之后: 入参1:面向切面 入参2:100 返回值:面向切面100 返回通知:The method saveUser return with 面向切面100
--------------------执行saveExt方法----------------------- 环绕通知,前置通知及切入点执行之前: 获取类名:com.entor.spring.aop.UserServiceImpl 获取方法名:saveExt 前置通知:----------切入点方法名:saveExt------------ 切入点方法:-----UserServiceImpl saveExt异常通知测试 ------ 后置通知: 获取类名:com.entor.spring.aop.UserServiceImpl 获取方法名:saveExt 获取参数值:----注解配置的Logger----- 异常通知:2016-12-12 03:49:55执行了【String com.entor.spring.aop.UserService.saveExt()方法发生异常......】【异常报告:java.lang.ArithmeticException: / by zero】 xxxxxxxxxxxxxxxxxx方法发生异常结束xxxxxxxxxxxxxxxxxx
对比执行结果可以得出通知的执行顺序
方法运行正常的情况的执行顺序:
1.环绕通知
2.前置通知
3.切入点方法执行
4.后置通知
5.环绕通知
6.返回通知
方法运行出现异常的情况的执行顺序 :
1.环绕通知
2.前置通知
3.切入点方法执行
4.后置通知
5.异常通知
注:环绕通知、返回通知不执行
相关推荐
面向切面编程(Aspect-Oriented Programming,AOP)是Spring框架的核心特性之一,它提供了一种优雅的方式来处理系统的横切关注点,如日志、事务管理、性能监控和权限控制等。在Spring中,AOP主要通过代理模式实现,...
Spring AOP(面向切面编程)是Spring框架的重要组成部分,它允许我们在不修改源代码的情况下对应用程序的行为进行统一管理和控制。在本实例中,我们将深入探讨如何使用AspectJ技术和XML配置来实现AOP。 首先,了解...
这个“spring-aop面向切面系统日志案例”是一个实践教程,旨在教你如何利用Spring AOP实现系统的日志记录。 首先,理解Spring AOP的基本概念至关重要。AOP是一种编程范式,它允许程序员定义“切面”,这些切面可以...
Spring4AOP 面向切面编程实例之方法拦截实例 一下利用Spring4的最后一个版本Spring4.3.9,实现简单的方法拦截实例。 Eclipse 建立java工程,导入必要的jar包,工程目录如下:
本项目是提供给java新手...本项目演示了java的 AOP 面向切面 的开发。 本项目演示了 前置切面,环绕切面, 后置异常切面 的开发。 本项目的技术栈是 Maven+Spring 如果您是技术高手,请不要购买,这个资源不适合您。
在Spring框架中,AOP(面向切面编程)是一种强大的设计模式,它允许开发者将关注点从核心业务逻辑中分离出来,比如日志记录、事务管理、权限控制等。本实例将深入探讨如何在Spring 4.0版本中实现AOP。 首先,AOP的...
在Spring框架中,动态代理和AOP(面向切面编程)是两个重要的概念,它们极大地增强了代码的可维护性和灵活性。下面将详细讲解这两个概念及其实际应用。 动态代理,是Spring提供的一种机制,允许我们在不修改原对象...
在"微服务之SpringBoot2—降低开发复杂度之面向切面AOP.zip"的案例中,每个部分都将详细展示如何实现上述五种通知类型。通过实践这些案例,开发者可以深入理解AOP在Spring Boot中的应用,从而在实际项目中更加高效地...
在Spring框架中,面向切面编程(Aspect Oriented Programming,简称AOP)是一种强大的设计模式,它允许我们定义横切关注点,如日志、事务管理、权限检查等,然后将这些关注点与核心业务逻辑解耦。这篇教程将详细讲解...
Spring AOP(面向切面编程)是Spring框架的重要组成部分,它提供了一种强大的方式来实现横切关注点,如日志、事务管理、安全性等,从而解耦应用程序的核心业务逻辑。在Spring AOP中,关注点被模块化为独立的“切面”...
Spring AOP(Aspect Oriented Programming,面向切面编程)是Spring框架的一个重要组成部分,它提供了一种在不修改原有代码的情况下,通过代理方式添加额外功能的技术。这种技术使得我们可以实现如日志记录、事务...
通过利用Spring的AOP(面向切面编程)特性,特别是@AspectJ注解的支持,我们可以创建灵活、可重用的业务逻辑切面,从而在不修改现有代码的情况下,对应用程序的行为进行增强。 ### Spring自定义切面的核心概念 ###...
AOP(Aspect Oriented Programming,面向切面编程)是一种编程范式,旨在通过将系统中的关注点(concerns)分离出来,提高代码的可维护性和可重用性。在Java开发中,AOP通常用于日志记录、事务管理、性能监控等横切...
Spring 1.x版本虽然已经较为古老,但理解其AOP(面向切面编程)的使用对于学习Spring框架的整体架构和设计理念至关重要。AOP是Spring解决横切关注点问题的重要手段,如日志记录、事务管理等。 首先,让我们来了解...
Spring AOP(面向切面编程)是Spring框架的重要组成部分,它提供了一种模块化和声明式的方式来实现横切关注点,如日志、事务管理、性能监控等。本入门案例将帮助你理解并掌握Spring AOP的基本概念和使用方法。 在...
Spring框架是Java开发中不可或缺的一部分,它通过提供两种核心特性——控制反转(IoC)和面向切面编程(AOP)来简化应用的构建。理解并掌握这两种技术对于任何Java开发者来说都至关重要。 **控制反转(IoC)**,也...
Spring AOP(面向切面编程)是Spring框架的重要组成部分,它提供了一种模块化和声明式的方式来处理系统中的交叉关注点问题,如日志、事务管理、安全性等。本示例将简要介绍如何在Spring应用中实现AOP,通过实际的...
Spring AOP是Spring框架的一个重要特性,它实现了面向切面编程,允许开发者定义“切面”,即关注点的模块化,比如日志记录、性能监控、安全控制等。切面通过通知(advises)来增强其他对象的行为。Spring支持多种...
Spring AOP(Aspect Oriented Programming,面向切面编程)是Spring框架的重要组成部分,它提供了一种在不修改源代码的情况下,对程序进行功能增强的技术。这个"spring aop jar 包"包含了实现这一功能所需的类和接口,...
面向切面编程(AOP,Aspect Oriented Programming)是一种编程范式,旨在将关注点分离,使得业务逻辑和系统服务(如日志、事务管理、权限控制等)能够解耦。这种编程方式允许程序员定义“切面”,这些切面封装了特定...