spring - AOP - AspectJ标签 - 基于注解 or 基于配置文件
发布日期:2021-06-30 16:59:53 浏览次数:2 分类:技术文章

本文共 11810 字,大约阅读时间需要 39 分钟。

文章目录

概念

在这里插入图片描述

在这里插入图片描述

术语

在这里插入图片描述

在这里插入图片描述

AspectJ

在这里插入图片描述

在这里插入图片描述

Jar包

  • 实现AspectJ代理

    aopalliance-1.0.jar
    aspectjweaver-1.6.8.jar
    spring-aop-4.0.0.RELEASE.jar
    spring-aspects-4.0.0.RELEASE.jar(没用到)

  • 实现spring创建类

    spring-context-4.0.0.RELEASE.jar
    spring-beans-4.0.0.RELEASE.jar
    spring-core-4.0.0.RELEASE.jar
    commons-logging-1.1.1.jar
    spring-expression-4.0.0.RELEASE.jar

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在配置文件中加入 aop 的命名空间

  • <!-- 设置要扫描的包 -->
    <context:component-scan base-package="vedio.aop"> </context:component-scan>
  • 使AspectJ注解起作用:自动为匹配的类生成代理对象
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>

基于注解的方式

  • 把这个类声明为一个切面:需要把该类放入到IOC容器中,再声明为一个切面

    @Aspect
    @Component - 切面首先是一个 IOC 中的bean

  • 声明该方法时一个前置通知:在目标方法开始之前执行

    @Before("executiong(public int 类全名.方法名(参数类型))")
    在这里插入图片描述
    @Before("execution(public int vedio.proxy.Calculator.*(int , int ) )")
    所有(int, int )参数的方法

代码

package vedio.aop;import org.springframework.stereotype.Component;import vedio.proxy.Calculator;@Component("calculator")public class CalculatorImp_aop implements Calculator{
@Override public int add(int a, int b) {
return a+b; } @Override public int sub(int a, int b) {
return a-b; } @Override public int mul(int a, int b) {
return a*b; } @Override public int div(int a, int b) {
return a/b; }}
package vedio.aop;import java.util.Arrays;import org.aspectj.lang.JoinPoint;import org.aspectj.lang.annotation.After;import org.aspectj.lang.annotation.AfterReturning;import org.aspectj.lang.annotation.AfterThrowing;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Before;import org.springframework.stereotype.Component;@Aspect@Componentpublic class LoginingAspect {
/** * 在方法执行之前执行的一段代码 */ @Before("execution(public int vedio.proxy.Calculator.*(..) )") public void beforMethod( JoinPoint joinPoint ) {
//获取方法名 String methodName = joinPoint.getSignature().getName(); //获取参数 Object[] args = joinPoint.getArgs(); System.out.println("The method "+ methodName+Arrays.toString(args) + " begin"); } //后置通知:在目标方法执行后(无论是否发生异常),执行的通知 //注意:这里不能获得结果,结果在返回其他通知里面 /** * 无论被代理方法是否执行,之后一定执行! */ @After("execution(public int vedio.proxy.Calculator.*(..) )") public void afterMethod(JoinPoint joinPoint) {
String methodName = joinPoint.getSignature().getName(); Object[] args = joinPoint.getArgs(); System.out.println("The method "+ methodName+Arrays.toString(args) +" is end"); } /** * 在方法正常结束时,执行的代码 * 返回通知时可以访问到方法的返回值的! */ @AfterReturning(value = "execution(public int vedio.proxy.Calculator.*(..) )" , returning = "result") public void afterReturningMethod(JoinPoint jointPoint , Object result) {
String methodName = jointPoint.getSignature().getName(); Object[] args = jointPoint.getArgs(); System.out.println("The result of "+methodName+Arrays.toString(args)+" is " + result); } /** * 在目标方法出现异常时会执行的代码 * 可以访问到异常对象 * 且可以执行在出现特定异常时在执行通知代码 */ @AfterThrowing(value = "execution(public int vedio.proxy.Calculator.*(..) )" , throwing = "ex") public void afterThrowingMethod(JoinPoint joinPoint , Exception ex) {
String methodName = joinPoint.getSignature().getName(); System.out.println("The method "+methodName+" occurs excetion:"+ex); } // /**// * 环绕通知需要携带 ProceedingJoinPoint 类型的参数,// * 环绕通知类似于动态代理的全过程: // * ProcedingJoinPoint 类型的参数可以决定是否执行目标的方法// */// @Around(value = "execution(public int vedio.proxy.Calculator.*(..) )")// public Object aroundMthod(ProceedingJoinPoint pjd) {
// Object result = null ;// String methodName = pjd.getSignature().getName();// Object[] args = pjd.getArgs();// // //前置通知// System.out.println("The method "+ methodName+Arrays.toString(args) + " begin");// // try {
// //执行目标方法// result = pjd.proceed(args);// //后置通知// System.out.println("The method "+ methodName+Arrays.toString(args) +" is end");// //返回通知// System.out.println("The result of "+methodName+Arrays.toString(args)+" is " + result);// } catch (Throwable e) {
// //后置通知// System.out.println("The method "+ methodName+Arrays.toString(args) +" is end");// //异常通知// System.out.println("The method "+methodName+" occurs excetion:"+e);// }finally {
// }// // return result; // }}
@Test	public void test01() {
ClassPathXmlApplicationContext pac = new ClassPathXmlApplicationContext("vedio/beans-aop.xml"); Calculator c = pac.getBean("calculator" , Calculator.class); int a = 4 ; int b = 2 ; int result =0 ; result = c.add(a, b) ; result = c.sub(a, b); //异常 result = c.div(a, 0); }

在这里插入图片描述

优先级

@Order(优先级)

值越小,优先级越高

/**	 * 在方法执行之前执行的一段代码	 */	@Order(2)	@Before("execution(public int vedio.proxy.Calculator.*(..) )")	public void beforMethod( JoinPoint joinPoint ) {
//获取方法名 String methodName = joinPoint.getSignature().getName(); //获取参数 Object[] args = joinPoint.getArgs(); System.out.println("The method "+ methodName+Arrays.toString(args) + " begin"); }
@Aspect@Componentpublic class ValidatingAspect {
@Order(1) @Before("execution(public int vedio.proxy.Calculator.*(..))") public void validatingArgs(JoinPoint joinPoint) {
String methodName = joinPoint.getSignature().getName(); Object[] args = joinPoint.getArgs(); //在执行之前 //判断args是否符合条件.... System.out.println(Arrays.toString(args)+" pass the validation of method "+ methodName); }}

在这里插入图片描述

重用切点表达式

/* * 定义一个方法,用于声明切入点表达式, * 使用 @Pointcut 来声明切入点表达式 * 后面的其他执行通知直接使用方法名来引用当前的切入点表达式。 */@Pointcut("execution(public int vedio.proxy.Calculator.*(..) )")
package vedio.aop;import java.util.Arrays;import org.aspectj.lang.JoinPoint;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Before;import org.springframework.core.annotation.Order;import org.springframework.stereotype.Component;@Aspect@Componentpublic class ValidatingAspect {
@Order(1) @Before("vedio.aop.LoginingAspect.declareJoinPointExpression() ") public void validatingArgs(JoinPoint joinPoint) {
String methodName = joinPoint.getSignature().getName(); Object[] args = joinPoint.getArgs(); //在执行之前 //判断args是否符合条件.... System.out.println(Arrays.toString(args)+" pass the validation of method "+ methodName); }}
package vedio.aop;import java.util.Arrays;import org.aspectj.lang.JoinPoint;import org.aspectj.lang.annotation.After;import org.aspectj.lang.annotation.AfterReturning;import org.aspectj.lang.annotation.AfterThrowing;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;@Aspect@Componentpublic class LoginingAspect {
/* * 定义一个方法,用于声明切入点表达式, * 使用 @Pointcut 来声明切入点表达式 * 后面的其他执行通知直接使用方法名来引用当前的切入点表达式。 */ @Pointcut("execution(public int vedio.proxy.Calculator.*(..) )") public void declareJoinPointExpression() {
//一般的,该方法中不再需要添加其他代码。 } /** * 在方法执行之前执行的一段代码 */ @Order(2) @Before("declareJoinPointExpression() ") public void beforMethod( JoinPoint joinPoint ) {
//获取方法名 String methodName = joinPoint.getSignature().getName(); //获取参数 Object[] args = joinPoint.getArgs(); System.out.println("The method "+ methodName+Arrays.toString(args) + " begin"); } //后置通知:在目标方法执行后(无论是否发生异常),执行的通知 //注意:这里不能获得结果,结果在返回其他通知里面 /** * 无论被代理方法是否执行,之后一定执行! */ @After("declareJoinPointExpression() ") public void afterMethod(JoinPoint joinPoint) {
String methodName = joinPoint.getSignature().getName(); Object[] args = joinPoint.getArgs(); System.out.println("The method "+ methodName+Arrays.toString(args) +" is end"); } /** * 在方法正常结束时,执行的代码 * 返回通知时可以访问到方法的返回值的! */ @AfterReturning(value ="declareJoinPointExpression() ", returning = "result") public void afterReturningMethod(JoinPoint jointPoint , Object result) {
String methodName = jointPoint.getSignature().getName(); Object[] args = jointPoint.getArgs(); System.out.println("The result of "+methodName+Arrays.toString(args)+" is " + result); } /** * 在目标方法出现异常时会执行的代码 * 可以访问到异常对象 * 且可以执行在出现特定异常时在执行通知代码 */ @AfterThrowing( value = "declareJoinPointExpression() " , throwing = "ex") public void afterThrowingMethod(JoinPoint joinPoint , Exception ex) {
String methodName = joinPoint.getSignature().getName(); System.out.println("The method "+methodName+" occurs excetion:"+ex); } // /**// * 环绕通知需要携带 ProceedingJoinPoint 类型的参数,// * 环绕通知类似于动态代理的全过程: // * ProcedingJoinPoint 类型的参数可以决定是否执行目标的方法// */// @Around(value = "execution(public int vedio.proxy.Calculator.*(..) )")// public Object aroundMthod(ProceedingJoinPoint pjd) {
// Object result = null ;// String methodName = pjd.getSignature().getName();// Object[] args = pjd.getArgs();// // //前置通知// System.out.println("The method "+ methodName+Arrays.toString(args) + " begin");// // try {
// //执行目标方法// result = pjd.proceed(args);// //后置通知// System.out.println("The method "+ methodName+Arrays.toString(args) +" is end");// //返回通知// System.out.println("The result of "+methodName+Arrays.toString(args)+" is " + result);// } catch (Throwable e) {
// //后置通知// System.out.println("The method "+ methodName+Arrays.toString(args) +" is end");// //异常通知// System.out.println("The method "+methodName+" occurs excetion:"+e);// }finally {
// }// // return result; // }}

文章目录

基于配置文件的方式

package vedio.aop;import java.util.Arrays;import org.aspectj.lang.JoinPoint;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Before;import org.springframework.core.annotation.Order;import org.springframework.stereotype.Component;public class ValidatingAspect_xml {
public void validatingArgs(JoinPoint joinPoint) {
String methodName = joinPoint.getSignature().getName(); Object[] args = joinPoint.getArgs(); //在执行之前 //判断args是否符合条件.... System.out.println(Arrays.toString(args)+" pass the validation of method "+ methodName); }}
package vedio.aop;import java.util.Arrays;import org.aspectj.lang.JoinPoint;import org.aspectj.lang.annotation.After;import org.aspectj.lang.annotation.AfterReturning;import org.aspectj.lang.annotation.AfterThrowing;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;public class LoginingAspect_xml {
public void beforMethod( JoinPoint joinPoint ) {
//获取方法名 String methodName = joinPoint.getSignature().getName(); //获取参数 Object[] args = joinPoint.getArgs(); System.out.println("The method "+ methodName+Arrays.toString(args) + " begin"); } public void afterMethod(JoinPoint joinPoint) {
String methodName = joinPoint.getSignature().getName(); Object[] args = joinPoint.getArgs(); System.out.println("The method "+ methodName+Arrays.toString(args) +" is end"); } public void afterReturningMethod(JoinPoint jointPoint , Object result) {
String methodName = jointPoint.getSignature().getName(); Object[] args = jointPoint.getArgs(); System.out.println("The result of "+methodName+Arrays.toString(args)+" is " + result); } public void afterThrowingMethod(JoinPoint joinPoint , Exception ex) {
String methodName = joinPoint.getSignature().getName(); System.out.println("The method "+methodName+" occurs excetion:"+ex); }}
package video;import org.junit.Test;import org.springframework.context.support.ClassPathXmlApplicationContext;import vedio.proxy.Calculator;public class Test_AOP_xml {
@Test public void test01() {
ClassPathXmlApplicationContext pac = new ClassPathXmlApplicationContext("vedio/beans-aop-xml.xml"); Calculator c = pac.getBean("calculator" , Calculator.class); int a = 4 ; int b = 2 ; int result ; result = c.add(a, b) ; result = c.sub(a, b); result = c.div(a, 0); }}

在这里插入图片描述

转载地址:https://lawsssscat.blog.csdn.net/article/details/103551447 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:Java培优班 - 第三十一天 - Maven
下一篇:maven项目更新报“Cannot nest 'xx/src/main/resources' inside 'xx/src ……”

发表评论

最新留言

关注你微信了!
[***.104.42.241]2024年04月30日 04时31分23秒