一、声明一个切面类
1、首先要将这个类放入容器中,基于注解,在类头信息加入@Component
2、将这个类声明成切面类,在头信息加入@Aspect注解
3、可以基于切面中的方法,比如前置通知,后置通知,返回通知,异常通知,以及环绕通知写自己的业务逻辑,定义切点"execution(* com.liyi.service.*.*(..))",即那些方法需要执行这些方法。如果想获取到方法的名字和参数,可以在方法中加入JoinPoint参数,可以获取到进入切面的方法细节。
3.1 前置通知:执行目标方法前拦截到的方法。没有特殊注意的地方,只需要一个连接点,JoinPoint,即可获取拦截目标方 法以及请求参数。
3.2 后置通知: 切面的后置通知,不管方法是否抛出异常,都会走这个方法。只需要一个连接点,JoinPoint,即可获取当 前结束的方法名称。
3.3 返回通知: 在方法正常执行通过之后执行的通知叫做返回通知。此时注意,不仅仅使用JoinPoint获取连接 点信息,同时要在返回通知注解里写入,resut="result"。在切面方法参数中加入Object result,用于接受返回通知 的返回结果。如果目标方法方法是void返回类型则返回NULL
3.4 异常通知: 在执行目标方法过程中,如果方法抛出异常则会走此方法。和返回通知很相似,在注解中 加入,throwing="ex",在切面方法中加入Exection ex用于接受异常信息
3.5 环绕通知:环绕通知需要携带ProceedingJoinPoint 这个类型的参数,环绕通知类似于动态代理的全过程 ProceedingJoinPoint类型的参数可以决定是否执行目标函数环绕通知必须有返回值。其实就是包含了所有通知的全 过程
四、最后别忘了在applicationContent.xml中声明aspect的代理对象,即初始化spring 容器的时候,spring自动对切点生成代理对象
<!-- 配置aspect 自动为匹配的类 产生代理对象 -->
<aop:aspectj-autoproxy>
Ⅱ 接下来 直接粘贴代码,很直观。
@Component
@Aspect
public class LoggingAspect {
/**
* 切面的前置方法 即方法执行前拦截到的方法 记录并输出
* 在目标方法执行之前的通知
* @param joinPoint
*/
@Before("execution(* com.liyi.service.*.*(..))")//第一个星号是否方法的返回值 第二个星是只service的所有子包 另一个是任意方法
public void beforeMethod(JoinPoint joinPoint){
System.out.println("======================方法开始======================");
Object object = joinPoint.getSignature();
String methodName = joinPoint.getSignature().getName();
List<Object> list = Arrays.asList(joinPoint.getArgs());
Date date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
String rightnow=sdf.format(date);
System.out.println(rightnow+"执行了【"+object+"方法开始执行......】");
System.out.println("******参数"+list+"******");
}
/**
* 切面的后置方法,不管抛不抛异常都会走此方法
* 在目标方法执行之后的通知
* @param joinPoint
*/
@After("execution(* com.liyi.service.*.*(..))")
public void afterMethod(JoinPoint joinPoint){
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+"方法结束......】");
}
/**
* 在方法正常执行通过之后执行的通知叫做返回通知
* 可以返回到方法的返回值 在注解后加入returning
* @param joinPoint
*/
@AfterReturning(value="execution(* com.liyi.service.*.*(..))",returning="result")
public void afterReturn(JoinPoint joinPoint,Object result ){
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+"方法正常执行结束......】"+"【返回结果:"+result+"】");
System.out.println("√√√√√√√√√√√√√√√√√√√√√√方法结束√√√√√√√√√√√√√√√√√√√√√√");
}
/**
* 在目标方法非正常执行完成 发生异常 抛出异常的时候会走此方法
* 获得异常可以用throwing
* @param joinPoint
* @param ex
*/
@AfterThrowing(value="execution(* com.liyi.service.*.*(..))",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");
}
/**
* 环绕通知需要携带ProceedingJoinPoint 这个类型的参数
* 环绕通知类似于动态代理的全过程 ProceedingJoinPoint类型的参数可以决定是否执行目标函数
* 环绕通知必须有返回值
* @param proceedingJoinPoint
* @return
*/
// @Around(value="execution(* com.liyi.service.*.*(..))")
// public Object aroundMethod(ProceedingJoinPoint proceedingJoinPoint){
// Object result=null;
// Object classMethod=proceedingJoinPoint.getSignature();
// Date date = new Date();
// SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
// String rightnow=sdf.format(date);
// try {
// //前置通知
// System.out.println(rightnow+"环绕通知执行了【"+classMethod+"方法开始执行......】");
// //执行目标方法
// result = proceedingJoinPoint.proceed();
// //返回通知
// System.out.println(rightnow+"环绕通知正常执行【"+classMethod+"方法完毕......】"+"【返回结果:】"+result);
// } catch (Throwable e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// //异常通知
// System.out.println(rightnow+"环绕通知非正常执行【"+classMethod+"方法完毕,抛出异常......】"+"【返回异常:】"+e);
// }
// //后置通知
// System.out.println(rightnow+"环绕通知执行【"+classMethod+"方法完毕】");
// return result;
// }
}
最后说明一点:所有通知类型都能获取到方法的相关参数,只有返回通知和环绕通能得到切面方法的返回值
分享到:
相关推荐
在AOP注解中一共分为五中类型的通知注解,接下来,我们通过实例,对这五种AOP注解进行讲解
一、AOP 概念 二、AOP 种类 三、Spring AOP 代理原理 四、Spring AOP 通知类型 五、Spring AOP Pointcut 六、Spring AOP 中的Advisor其实就是Aspect 七、AOP ProxyFactory 八、自动代理
这是一种常用的AOP通知类型,常用于日志记录、安全性检查等方面。 下面详细解释如何在Spring Boot中使用@Before注解,并提供一个完整的实例和代码来演示其用法。在实例中,我们将创建一个简单的用户认证功能,并在...
SpringAop xml方式配置通知
Spring.net通知类型,以及通知链Spring.net通知类型,以及通知链
主要给大家介绍了关于如何使用Spring AOP的通知类型及创建通知的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用Spring AOP具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
主要介绍了浅谈spring aop的五种通知类型,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
Spring spectJ AOP 前置通知 后置通知 返回通知 异常通知 环绕通知
Spring AOP四种创建通知(拦截器)类型
用spring AOP(包括几种常用的通知类型)做的小程序
Spring_AOP四种创建通知(拦截器)类型,介绍的比较详细,有实例
描述一下Spring AOP?...Spring中有哪些不同的通知类型(advice types)? Spring AOP 代理是什么? 引介(Introduction)是什么? 连接点(Joint Point)和切入点(Point Cut)是什么? 织入(Weaving)是什么?
Spring AOP支持不同类型的通知,如前置通知(Before)、后置通知(After)、返回后通知(After-returning)、抛出异常后通知(After-throwing)和环绕通知(Around)。这种机制使得开发者可以在运行时动态地应用这些...
如何定义通知类型枚举、切点接口、连接点接口、通知接口、配置器接口。 如何定义默认切点类、默认连接点类、默认通知类。 如何定义 CGLIB 织入器类、AOP 框架类、代理对象管理器类。 如何使用 AOP 框架来定义切点、...
Spring 4.0 AOP 面向切面测试程序,涉及通知类型包括前置通知\后置通知\返回通知\异常通知\环绕通知,项目采用Maven搭建!
这里写目录标题什么是AOPAOP中的核心概念切面通知切点引入目标对象代理对象...类型BeforeAfterReturningAfterThrowingAfter(Finally)Around实际应用通知中的参数JoinPointProceedingJoinPoint通知的排序AOP的应用全局...
6. 了解通知类型(五种) 7. 重点掌握aop底层的原理之动态代理机制的概述及差别 8. 重点掌握JDK代理技术之产生代理对象和代理对象执行逻辑分析 9. 重点掌握Cglib代理技术之产生代理对象和代理对象执行逻辑分析 10. ...
火龙果软件工程技术中心 在本系列的第一部分,...比起第一部分中介绍的那些通知类型,around形式的通知是一种更具侵入性也更强大的面向对象概念。本文将描述around通知的每个特性,以便您可以在自己的SpringAOP应用程
1.什么是Spring框架 2.Spring的特点 3.什么是IOC 4.基于xml的IOC 5.项目案例 6.基于注解的IOC ...15.AspectJ常见通知类型 16.AspectJ 的切入点表达式(掌握) 17.AspectJ的前置通知@Before .... .... ....