Spring AOP学习
Spring AOP构建在动态代理的基础之上,因此仅支持方法级别的连接点,如果需要更细粒度的拦截可以使用Aspect
什么是Spring AOP
来自百度百科
在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
Spring AOP解决什么问题
日志、安全审计等在整个程序流程会多处使用,但是跟业务又没什么关系,像这类问题就可以用AOP来实现,将核心业务和非业务代码解耦
在Spring Boot实现AOP
Spring Boot中添加spring-boot-starter-aop的依赖;Sprig Boot中已经默认启用aop功能了,非Spring Boot的需要配置启用aop
实现的是一个到学校图书馆看书的场景,不管到图书馆里面看书还是自习,进出都需要刷学生卡,那么这部分业务就可以作为一个切面处理
libraryAspect.Java
package com.ccccye.springstudy.S20190727;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
/**
* Created by ccccye on 2019/7/27
* 图书馆-切面
*/
@Aspect
@Component
public class libraryAspect {
/**
* 可重用的切点
*/
@Pointcut("execution(* com.ccccye.springstudy.S20190727.LibraryController.*(..))")
public void libraryCut(){ }
/**
* 前置通知
*/
//@Before("execution(* com.ccccye.springstudy.S20190727.LibraryController.*(..))")
@Before("libraryCut()")
public void before(){
System.out.printf("滴,学生卡 进入图书馆\r\n");
}
/**
* 后置通知
*/
//@After("execution(* com.ccccye.springstudy.S20190727.LibraryController.*(..))")
@After("libraryCut()")
public void after(){
System.out.printf("滴,学生卡 离开图书馆\r\n");
}
/**
* 后置通知-异常之后
*/
@AfterThrowing("libraryCut()")
public void afterThrowing(){
System.out.printf("哎呀,在图书馆大声吵闹被赶出来了\r\n");
}
}
LibraryController.Java
package com.ccccye.springstudy.S20190727;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* Created by ccccye on 2019/7/27
* 图书馆接口
*/
@RestController
@RequestMapping("/library/")
public class LibraryController {
@RequestMapping(value = "read")
public String readBook() throws Exception{
// if (1==1){
// throw new Exception("大声吵闹");
// }
String msg = "周末看书ing\r\n";
System.out.printf(msg);
return msg;
}
}
相关知识点
- JAVA设计模式-代理模式
相关概念
- Aspect(切面),Aspect声明类似于JAVA中的类声明,在Aspect中包含着一些PointCut以及相应的Advice
- Joint point(连接点),表示在程序中明确定义的点,典型的包括方法调用,对类成员的访问以及异常处理程序块的执行等等,它自身还可以嵌套其它 joint point
- Pointcut(切点),表示一组 joint point,这些 joint point 或是通过逻辑关系组合起来,或是通过通配、正则表达式等方式集中起来,它定义了相应的 Advice 将要发生的地方
- Advice(通知),Advice 定义了在 Pointcut 里面定义的程序点具体要做的操作,它通过 before、after 和 around 来区别是在每个 joint point 之前、之后还是代替执行的代码
- Target(目标对象),织入 Advice 的目标对象
- Weaving(织入),将 Aspect 和其他对象连接起来, 并创建 Adviced object 的过程
Spring切面的5种类型通知
- Before(前置通知),在目标方法调用之前调用通知功能
- After(后置通知),在目标方法完成之后调用通知,此时不会关心方法输出的是什么
- After-Returning(返回通知),在目标方法成功执行之后调用通知
- After-Throwing(异常通知),在目标方法抛出异常后调用通知
- Around(环绕通知),通知包裹了被通知的方法,在被通知之前和通知之后执行自定义的行为
总结
通过学习Spring AOP,以后遇到公共的非核心业务,就会马上想到用AOP实现。
参考资料
- Spring实战(第4版)
- 细说Spring——AOP详解(AOP概览)