五种通知
使用AspectJ注解声明切面
1)需要在spring IoC容器中将AspectJ切面声明为bean实例。
当Spring IOC容器初始化AspectJ切面后,spring IOC容器会为
AspectJ切面匹配的bean创建代理
2)在AspectJ注解中,切面是一个带有@Aspect注解的java类
3)通知是标识某种注解的简单Java方法
5中类型的通知注解
@Before前置通知,在方法执行之前执行
@After后置通知,在方法执行之后执行
@AfterRunning返回通知,在方法返回结果后执行
@AfterThrowing异常通知,在方法抛出异常之后
@Around环绕通知,围绕方法执行
4)使用@Order标识切面优先级,值越小优先级越高
依赖的jar包
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>${org.spring.version}</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.7.4</version> </dependency> <dependency> <groupId>aopalliance</groupId> <artifactId>aopalliance</artifactId> <version>1.0</version> </dependency>
LoggingAspect.java
package com.hous.math; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import javax.management.RuntimeErrorException; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.AfterThrowing; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.springframework.stereotype.Component; import com.mchange.v1.util.ArrayUtils; /** * 1.吧该类放到容器中 2.声明为一个切面 * 3.@Order切面优先级,值越小优先级越高 */ @Order(2) @Aspect @Component public class LoggingAspect { /** * 声明前置通知,在方法执行之前执行 * @param joinPoint */ @Before("execution(* com.hous.math.*.*(..))") public void beforeMethod(JoinPoint joinPoint) { String methodName = joinPoint.getSignature().getName(); List<Object> args = Arrays.asList(joinPoint.getArgs()); System.out.println("the method " + methodName + " begin with " + args); } /** * 后置通知,在目标方法执行后执行的通知(无论其是否发生异常) * 后置通知不能访问目标方法执行的结果 * @param joinPoint */ @After("execution(* com.hous.math.*.*(..))") public void afterMethod(JoinPoint joinPoint) { String methodName = joinPoint.getSignature().getName(); List<Object> args = Arrays.asList(joinPoint.getArgs()); System.out.println("the method " + methodName + " end with " + args); } /** * 在方法正常执行结束执行的通知 * 可以访问到方法的返回值 * @param joinPoint * @param result */ @AfterReturning(value="execution(* com.hous.math.*.*(..))", returning="result") public void afterReturning(JoinPoint joinPoint, Object result) { String methodName = joinPoint.getSignature().getName(); System.out.println("the method " + methodName + " end with result " + result); } /** * 在目标方法发生异常执行的代码 * 可以访问到异常对象,可以规定在某些特定异常执行 * @param joinPoint * @param e */ @AfterThrowing(value="execution(* com.hous.math.*.*(..))", throwing="e") public void afterThrowing(JoinPoint joinPoint, ArithmeticException e) { String methodName = joinPoint.getSignature().getName(); System.out.println("the method " + methodName + " occurs exception " + e); } /** * @param pjd * @return */ @Around("execution(* com.hous.math.*.*(..))") public Object aroundMethod(ProceedingJoinPoint pjd) { Object result = null; String methodName = pjd.getSignature().getName(); try { //前置通知 System.out.println("the methods " + methodName + " begins with" + Arrays.asList(pjd.getArgs())); //执行目标方法 result = pjd.proceed(); //后置通知 System.out.println("the methods " + methodName + " ends with result " + result); } catch (Throwable e) { //异常通知 System.out.println("the methods " + methodName + " occurs exception" + e); throw new RuntimeException(e); } //后置通知 System.out.println("the methods " + methodName + " ends"); return result; } }
xml配置
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:util="http://www.springframework.org/schema/util" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd"> <context:component-scan base-package="com.hous.math"> </context:component-scan> <!-- 为@Aspect标记,自动为匹配的类生成代理对象 --> <aop:aspectj-autoproxy></aop:aspectj-autoproxy> </beans>
重用切入点表达式
定义一个方法,声明切入点表达式。该方法不需要添加其他代码
在不同包下的引用需要加上包路径com.hous.LoggingAspect.declareJoinPointExpression()就这样
package com.hous.math; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import javax.management.RuntimeErrorException; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.AfterThrowing; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; import com.mchange.v1.util.ArrayUtils; /** * 1.吧该类放到容器中 2.声明为一个切面 * @Order切面优先级,值越小优先级越高 */ @Order(2) @Aspect @Component public class LoggingAspect { /** * 定义一个方法,声明切入点表达式。该方法不需要添加其他代码 */ @Pointcut("execution(* com.hous.math.*.*(..))") public void declareJoinPointExpression() {} /** * 声明前置通知,在方法执行之前执行 * @param joinPoint */ @Before("declareJoinPointExpression()") public void beforeMethod(JoinPoint joinPoint) { String methodName = joinPoint.getSignature().getName(); List<Object> args = Arrays.asList(joinPoint.getArgs()); System.out.println("the method " + methodName + " begin with " + args); } /** * 后置通知,在目标方法执行后执行的通知(无论其是否发生异常) * 后置通知不能访问目标方法执行的结果 * @param joinPoint */ @After("declareJoinPointExpression()") public void afterMethod(JoinPoint joinPoint) { String methodName = joinPoint.getSignature().getName(); List<Object> args = Arrays.asList(joinPoint.getArgs()); System.out.println("the method " + methodName + " end with " + args); } /** * 在方法正常执行结束执行的通知 * 可以访问到方法的返回值 * @param joinPoint * @param result */ @AfterReturning(value="declareJoinPointExpression()", returning="result") public void afterReturning(JoinPoint joinPoint, Object result) { String methodName = joinPoint.getSignature().getName(); System.out.println("the method " + methodName + " end with result " + result); } /** * 在目标方法发生异常执行的代码 * 可以访问到异常对象,可以规定在某些特定异常执行 * @param joinPoint * @param e */ @AfterThrowing(value="declareJoinPointExpression()", throwing="e") public void afterThrowing(JoinPoint joinPoint, ArithmeticException e) { String methodName = joinPoint.getSignature().getName(); System.out.println("the method " + methodName + " occurs exception " + e); } /** * @param pjd * @return */ @Around("declareJoinPointExpression()") public Object aroundMethod(ProceedingJoinPoint pjd) { Object result = null; String methodName = pjd.getSignature().getName(); try { //前置通知 System.out.println("the methods " + methodName + " begins with" + Arrays.asList(pjd.getArgs())); //执行目标方法 result = pjd.proceed(); //后置通知 System.out.println("the methods " + methodName + " ends with result " + result); } catch (Throwable e) { //异常通知 System.out.println("the methods " + methodName + " occurs exception" + e); throw new RuntimeException(e); } //后置通知 System.out.println("the methods " + methodName + " ends"); return result; } }使用配置文件方式配置AOP
相关推荐
Spring AOP五种通知方式代码实例详解 Spring AOP是一种非常强大的面向切面编程技术,它可以将横切关注点从业务逻辑中分离出来,从而提高系统的灵活性和可维护性。在Spring AOP中,有五种通知方式:前置通知、后置...
本示例“Around_AOP_Spring.zip_aop”主要讲解了Spring AOP中的环绕通知(Around Advice),这是AOP五种通知类型中最强大的一种。 1. **什么是AOP** - AOP的核心思想是将程序中的横切关注点(如日志、安全检查、...
3. **环绕通知(Around Advice)**:这是Spring AOP五种通知类型中最强大的一种。环绕通知可以在方法执行前后执行自定义逻辑,并且可以选择是否执行原始方法。它通过`@Around`注解来定义,并且需要实现`...
本篇文章将详细讲解五种主要的AOP通知注解及其应用。 1. 前置通知(@Before):在目标方法执行之前运行。例如,可以用于进行参数校验或开启事务。使用`@Before`注解的方法会在目标方法调用前被执行,其格式为`@Before...
在Spring AOP中,有三种主要的通知类型:前置通知、后置通知和环绕通知。下面将详细解释这三种通知,并通过简单的代码示例进行演示。 **1. 前置通知(Before Advice)** 前置通知在目标方法被调用之前执行,但无法...
### Spring AOP 四种创建通知(拦截器)类型详解 Spring AOP(Aspect Oriented Programming,面向切面编程)是Spring框架中的一个重要模块,它提供了在应用代码中添加横切关注点的能力,如日志记录、事务管理、权限...
AOP通知是指在特定连接点(Join Point)执行的动作,Spring支持五种不同的通知类型: 1. **前置通知(Before Advice)**: 在目标方法执行之前运行。 2. **后置通知(After Advice)**: 在目标方法执行之后运行,...
标题提到的"Spring 使用AspectJ 实现 AOP之前置通知小例子",指的是利用AspectJ在Spring中实现AOP的一种特定类型的通知——前置通知(Before advice)。前置通知在目标方法执行之前运行,但不会阻止方法的执行。这种...
Spring AOP 是一种面向切面编程的技术,它允许我们在不修改源代码的情况下,对应用程序的特定部分(如方法调用)进行增强。在 Spring 中,AOP 的实现主要依赖于代理模式,有两种代理方式:JDK 动态代理和 CGLIB 动态...
环绕通知是Spring AOP五种通知类型中最强大的一种。与前置通知(before)、后置通知(after)、返回通知(after-returning)和异常通知(after-throwing)不同,环绕通知可以包围一个方法的整个生命周期,包括调用...
Spring支持五种类型的通知:前置通知、后置通知、返回通知、异常通知和环绕通知。例如,创建一个前置通知: ```xml <aop:before method="beforeMethod" pointcut-ref="serviceMethods"/> ``` `method`属性指定了在...
引入通知是Spring AOP的一种特殊类型的通知,它可以在目标对象上添加新的接口或方法,而无需修改原始类的源代码。这种特性非常实用,尤其是在处理遗留系统或者第三方库时,可以避免对原有代码的侵入性修改。 Spring...
Spring AOP(面向切面编程)是Spring框架的重要组成部分,它提供了一种模块化和声明式的方式来处理系统中的交叉关注点,如日志、事务管理等。在Java应用中,AOP通过代理模式实现了切面编程,使得我们可以将业务逻辑...
- `beforeMethod`, `afterReturningMethod`, `afterThrowingMethod` 和 `aroundMethod`是切面类中定义的通知方法,分别对应四种不同的通知类型。 **三、通知类型** 1. **前置通知(Before Advice)**:在目标方法...
AOP(Aspect Oriented Programming,面向切面编程)是Spring框架中的一个重要概念,它提供了一种将关注点(如日志、事务管理等)与核心业务逻辑分离的方式,从而实现代码的模块化和可重用性。AOP通过定义切面...
在给出的XML配置中,`<aop:config>`元素开启AOP支持,而`<aop:aspect>`元素用于定义切面,其内部通过`<aop:pointcut>`定义切点,并通过`<aop:before>`和`<aop:after>`指定通知。 为了使用这些配置,我们需要在代码...
面向切面编程(AOP)是一种编程范式,旨在将横切关注点(如日志、安全等)与业务逻辑分离,从而提高模块化。AOP通过预定义的“切面”对横切关注点进行模块化,从而可以在不修改业务逻辑代码的情况下增加新功能。动态...
在Spring框架中,AOP(面向切面编程)是一种强大的工具,它允许我们在不修改代码的情况下,通过代理机制实现对程序行为的横切关注点,如日志、事务管理等。这里的“标签加载通知”指的是在Spring AOP中,如何通过...
1. **通知(Advice)**:通知定义了切面在何时执行,Spring支持Before、After-returning、After-throwing、Around和Introduction五种类型的Advice。 2. **连接点(Joinpoint)**:连接点是应用通知的时机,如方法调用、...