已经配置好的demo下载:
请点击
教程开始:
1.首先一个最基本的springmvc框架;
相关的教程:https://blog.csdn.net/qq_23095607/article/details/100902345
相关的springmvc demo:https://download.csdn.net/download/qq_23095607/11752267
2.总体的结构为:
3.在这个基础上导入依赖:
<!--spring-aop-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>${spring.version}</version>
</dependency>
4.springContext.xml开启AOP功能
<aop:aspectj-autoproxy/>
注意:一定要检查一下你要扫描的包是不是包含了所有的注解,如下:
<!-- 搜索spring控件,扫描所有带有注解的包,别丢东西了 -->
<context:component-scan base-package="com."></context:component-scan>
<aop:aspectj-autoproxy/>
5.编写相关的切面,以及切面逻辑,这里就不一一讲了,可以自行百度,直接贴代码:
package com.aspect;
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.stereotype.Component;
/**
* @desc: 经纪人切面
* @author: CSH 参考:https://www.cnblogs.com/chuijingjing/p/9806651.html
**/
@Aspect
@Component
public class BrokerAspect {
/**
* 定义切入点,切入点为com.example.demo.aop.AopController中的所有函数 通过@Pointcut注解声明频繁使用的切点表达式
*/
@Pointcut("execution( * com.huaxi.AopController.*(..)))")
public void BrokerAspect() {
}
/**
* @description 在连接点执行之前执行的通知 一定要保证JoinPoint处在参数列表的第一位,否则抛异常
*/
@Before("BrokerAspect()")
public void doBeforeGame(JoinPoint joinPoint) {
System.out.println("------before advice start------");
Object target = joinPoint.getTarget().getClass().getName();
String name = joinPoint.getSignature().getName();
Object[] args = joinPoint.getArgs();// 2.传参
System.out.println("所用的类名为:" + target);
System.out.println("所用的方法名为:" + name);
System.out.print("传递的参数有:");
for (Object object : args) {
System.out.println(object);
}
System.out.println("------before advice end------");
}
/**
* @description 在连接点执行之后执行的通知(返回通知和异常通知的异常) 一定要保证JoinPoint处在参数列表的第一位,否则抛异常
*/
@After("BrokerAspect()")
public void doAfterGame(JoinPoint joinPoint) {
System.out.println("------after advice start------");
Object target = joinPoint.getTarget().getClass().getName();
String name = joinPoint.getSignature().getName();
Object[] args = joinPoint.getArgs();// 2.传参
System.out.println("所用的类名为:" + target);
System.out.println("所用的方法名为:" + name);
System.out.print("传递的参数有:");
for (Object object : args) {
System.out.println(object);
}
System.out.println("------after advice end------");
}
/**
* @description 在连接点执行之后执行的通知(返回通知) 一定要保证JoinPoint处在参数列表的第一位,否则抛异常
*/
@AfterReturning(returning = "rvt", pointcut = "BrokerAspect()")
public void doAfterReturningGame(JoinPoint joinPoint, Object rvt) {
System.out.println("------after-return advice start------");
Object target = joinPoint.getTarget().getClass().getName();
String name = joinPoint.getSignature().getName();
Object[] args = joinPoint.getArgs();// 2.传参
System.out.println("所用的类名为:" + target);
System.out.println("所用的方法名为:" + name);
System.out.print("传递的参数有:");
for (Object object : args) {
System.out.println(object);
}
System.out.println("返回值为:" + rvt);
System.out.println("------after-return advice end------");
}
/**
* @description 在连接点执行之后执行的通知(异常通知) 一定要保证JoinPoint处在参数列表的第一位,否则抛异常
*/
@AfterThrowing(throwing = "ex", pointcut = "BrokerAspect()")
public void doAfterThrowingGame(JoinPoint joinPoint, Throwable ex) {
System.out.println("------AfterThrowing advice start------");
Object target = joinPoint.getTarget().getClass().getName();
String name = joinPoint.getSignature().getName();
Object[] args = joinPoint.getArgs();// 2.传参
System.out.println("所用的类名为:" + target);
System.out.println("所用的方法名为:" + name);
System.out.print("传递的参数有:");
for (Object object : args) {
System.out.println(object);
}
System.out.println("抛出的异常为::" + ex);
System.out.println("------AfterThrowing advice end------");
}
//---------------------------------------------------------------------------------------
//-----------------由于@around功能跟强大,影响到了页面的逻辑,本人已经屏蔽,有需要的可以放开测试-----------------------------------------
//-----------------------------------------------------------------------------------------
/*
* @description近似于Before增强处理和AfterReturing增强处理的总结 可以修改参数,自动调用方法等强大的功能
* 第一个形参必须是ProceedJoinPoint类型(至少含有一个形参 环绕通知需要返回返回值,否则真正调用者将拿不到返回值,只能得到一个null。
* 环绕通知有控制目标方法是否执行、有控制是否返回值、有改变返回值,改变参数的能力。
*/
/* @Around("BrokerAspect()")
public Object processTx(ProceedingJoinPoint joinPoint)throws Throwable{
System.out.println("------Around advice start------");
Object target = joinPoint.getTarget().getClass().getName();
String name = joinPoint.getSignature().getName();
Object[] args = joinPoint.getArgs();// 2.传参
System.out.println("所用的类名为:" + target);
System.out.println("所用的方法名为:" + name);
System.out.print("传递的参数有:");
for (Object object : args) {
System.out.println(object);
}
// 获取目标方法原始的调用参数
if (args != null && args.length >= 1) {
// 修改目标方法的第一个参数
args[0] = "【经过了around advice 不需要请在后台注销整个@around】" + args[0];
System.out.println(args[0]);
}
// 以改变后的参数去执行目标方法,并保存目标方法执行后的返回值
//rvt为返回值,可以自定义就行返回。
Object rvt = joinPoint.proceed(args);
// 如果rvt的类型是Integer,将rvt改为它的平方
if (rvt != null && rvt instanceof Integer)
rvt = (Integer) rvt * (Integer) rvt;
System.out.println("------Around advice end------");
return rvt;
}*/
}