博客内容

 本篇文章可以学到springboot如何使用AOP的前置通知和后置通知如何实现以及对AOP的前置通知和后置通知的了解

如何理解AOP

  AOP是一个面向切面的编程,就是将一段代码插进另一段代码里运行,就拿记录日志来说,我们有个业务是登录,我们要记录登录日志(例如 IP地址,登录用户,城市),如果不使用AOP的话

1
2
3
4
5
///就比如说这是一个登录的方法
public void login(String user,String pass){
System.out.println("登录成功"); //登录成功
log.info("192.168.0.01,"+user+",河南,安阳")// 添加日志
}

如果使用AOP的话,我们可以将log.info(“xxxxx”);写到aop里,就不需要在这里面写了

AOP也是拿来解耦的,如果一个业务和另外一个业务需要执行一个相同的方法,比如说
假如我们有一个书城,当我们执行购买图书的时候,我们需要等购买完后查询订单信息,还有就是我们点详情的时候也要看订单的信息
不用AOP的时候,我们要在这两个方法里添加一个查询订单的方法(操作)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/**
* 不使用AOP
**/
public void buy(){
System.out.println("购买一本书");
System.out.println(selInfo());
}

public void order(){
System.out.println(selInfo());
}

public String selInfo(){
return "这是查看的信息"
}

如果我们使用AOP的话,可以将这个查询信息的方法切入到这两个方法里面,这两个调用后,就可以通过切面,执行这个查询信息的方法
在使用AOP的情况下,只写一遍代码就行(两个方法只执行一个方法,而且是同一个(切面方法里面的selinfo())),而不使用的话,我们需要在这两个操作中分别写入一个相同的操作(两个方法分别执行自己方法块里面的相同方法,就是分别执行上面的selinfo())

怎么样理解 前置通知和后置通知

拿一个下象棋的例子来说,你是红方,你要先走棋,等你开始走的时候,你会说 我开始走了啊,然后在下你棋,等你下完了,你会在说一句我下好了

前置通知和后置通知实践

在方法执行的时候,会先执行这个方法
比如说我们有个控制器

1
2
3
4
5
6
7
8
@RestController
public class test {
@RequestMapping("/aop")
public String ss(){
System.out.println("我下了一步棋");
return "ss";
}
}

下面是那个控制器的切面,分别是前置和后置通知

1
2
3
4
5
6
7
8
9
10
11
12
13
@Component
@Aspect
class Aop {
@Before("execution(public * com.example.aop.controller.test.*())")
public void dobef(){
System.out.println("该我下棋了,我要开始下了");
}

@After("execution(public * com.example.aop.controller.test.*())")
public void aft(){
System.out.println("我下好了,该你了");
}
}

在看看运行访问后的输出(大半夜了,还有点瞌睡,上传个图可麻烦,直接复制粘贴过来吧)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
  .   ____          _            __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.3.0.RELEASE)

2020-06-23 00:09:48.291 INFO 2692 --- [ main] com.example.aop.AopApplication : Starting AopApplication on DESKTOP-NO6I8UL with PID 2692 (E:\ideaProject\aop\target\classes started by 86177 in E:\ideaProject\aop)
2020-06-23 00:09:48.293 INFO 2692 --- [ main] com.example.aop.AopApplication : No active profile set, falling back to default profiles: default
2020-06-23 00:09:48.978 INFO 2692 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8989 (http)
2020-06-23 00:09:48.983 INFO 2692 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2020-06-23 00:09:48.984 INFO 2692 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.35]
2020-06-23 00:09:49.030 INFO 2692 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2020-06-23 00:09:49.030 INFO 2692 --- [ main] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 706 ms
2020-06-23 00:09:49.150 INFO 2692 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor'
2020-06-23 00:09:49.224 WARN 2692 --- [ main] ion$DefaultTemplateResolverConfiguration : Cannot find template location: classpath:/templates/ (please add some templates or check your Thymeleaf configuration)
2020-06-23 00:09:49.276 INFO 2692 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8989 (http) with context path ''
2020-06-23 00:09:49.284 INFO 2692 --- [ main] com.example.aop.AopApplication : Started AopApplication in 1.213 seconds (JVM running for 1.65)
2020-06-23 00:09:51.640 INFO 2692 --- [nio-8989-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet'
2020-06-23 00:09:51.640 INFO 2692 --- [nio-8989-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
2020-06-23 00:09:51.644 INFO 2692 --- [nio-8989-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 4 ms
该我下棋了,我要开始下了
我下了一步棋
我下好了,该你了

我们可以看到上面的输出
先输出了该我下棋了,我要开始下了,接着在输出我们那个控制器里面的我下了一步棋,最后才是我下好了,该你了

开始执行方法 —> 前置通知 —> 执行方法里的内容 —> 后置通知

Springboot可以这样做,spring(MVC)也可以这样做,这个方法并不是springboot专有的。(Springboot和Spring并不是互不干扰(没有关系)的框架)

—–以上就是我对AOP前置通知和后置通知的理解,如有错误,欢迎评论指正 End

更新于

请我喝[茶]~( ̄▽ ̄)~*

Fanxing 微信支付

微信支付

Fanxing 支付宝

支付宝

Fanxing 贝宝

贝宝