何为Aop
Aop中文翻译过来是切面编程,说通俗点就是在运行两段代码之间强行插入一段其他的程序。它也是Spring框架里的一个核心功能。详细介绍可以参考这位大佬的博客,写的十分详细。本篇就不再过多介绍
springboot关于aop的配置
本配置采用的maven来统一管理jar包。
首先是引入关键的依赖,引入相应的jar包之后,才可以使用aop的注解
附上代码
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
aop的用法
aop是spring框架的几大核心功能之一,之前我们在使用ssm整合框架的时候,虽然aop已经有自己的注解,但我们大部分还是用的xml配置。springboot提倡使用注解,所以我这次主要还是讲的aop的基本注解用法。
声明一个类,我们可以把这个类理解为配置类,并添上@Aspect
和@Component
注解。若没有出现这个注解,很可能是因为maven中的依赖没有起作用,尝试着在网好的地方刷新一下试试?
声明完类之后,我们要往里面添加东西了。首先是声明切点
@Pointcut注解的作用是声明一个切点。其基本语法为 :
@Pointcut(value = "execution(切点地址)")//注意:双引号要保留
public void 切点代名{}
其中,切点地址是有一定格式规范的,详细情况可以参考spring官方文档,地址为spring官方文档
在导航栏里选中该项,然后向下滑动大概3,4秒左右就能找到
我下面就介绍一些比较常用的写法
项目结构图为:
AopTest类
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* @author 无_言
* aop第一个测试类
* */
@Controller
@RequestMapping("aopTest")
public class AopTest {
@RequestMapping("/start1")
public String start1(){
System.out.println("start1方法");
return "hello";
}
@RequestMapping("/start2")
public String start2(){
System.out.println("start2方法");
return "hello";
}
}
AopTest2类
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* @author 无_言
* aop第二个测试类
* */
@Controller
@RequestMapping("/aopTest2")
public class AopTest2 {
@RequestMapping("/start4")
public String start4(){
System.out.println("start4方法");
return "hello";
}
@RequestMapping("/disstart4")
public String disstart4(String str){
System.out.println("disstart4方法");
return "hello";
}
@RequestMapping("/disstart5")
public String disstart5(){
System.out.println("disstart5方法");
return "hello";
}
}
切点声明:
@Pointcut(value = "execution(* my.test.aoptest.controller..*.*(..))")
public void pointCutAll(){}
@Pointcut(value = "execution(* my.test.aoptest.controller.AopTest.*(..))")
public void pointCut1(){}
@Pointcut(value = "execution(* my.test.aoptest.controller.AopTest.start1())")
public void pointCut2(){}
@Pointcut(value = "execution(* my.test.aoptest.controller.AopTest.start2())")
public void pointCut3(){}
@Pointcut(value = "execution(* my.test.aoptest.controller.AopTest2.dis*(..))")
public void pointCut4(){}
@Pointcut(value = "execution(* my.test.aoptest.controller.AopTest2.dis*(String))")
public void pointCut5(){}
附上图:
首先,括号里的第一个星号代表权限(下同),除了号以外,就是private,public ,protected,default四个基本权限。代表访问该包中拥有这些权限的属性。例如把号换成public则程序就只会扫描权限为public的方法,换成private同理,*号表通配符,意思为所有权限的方法都可以访问。
1. 表示controller包下的所有类的所有权限和类型的方法
2. 表示controller包下名为AopTest的类下的所有类型和权限的方法
3. 表示controller包下名为AopTest的类下的名为star1的方法
4. 表示controller包下名为AopTest的类下的名为star2的方法
5. 表示controller包下名为AopTest2的类下的所有名称以“dis”开头的方法
6. 表示controller包下名为AopTest2的类下的所有名称以“dis”开头的参数类型为String的方法
再声明完切点之后,接下来就是声明切面方法了。这里着重介绍三个注解@Before,@After和@Around
附上代码:
@Before("pointCut2()")
public void testAop2(){
System.out.println("这是程序执行前的函数");
}
@After("pointCut3()")
public void testAop1(){
System.out.println("这是程序执行之后的函数");
}
@Around("pointCut4()")
public Object testAop6(ProceedingJoinPoint pro)throws Throwable{
System.out.println("程序执行之前的函数");
Object proccees=pro.proceed();//切点方法执行
System.out.println("程序执行结束后的函数");
return proccees;
}
这三个注解的格式都是@注解名(”切点地址”)
(注:1.双引号保留2.如果在上文声明了切点,则可直接使用切点代名)
其中,@Before和@After见名知义,分别指代方法开始运行之前和运行结束之后所要执行的程序。程序运行结果如下:
@Before
@After
相对于前面两个注解,@Around
要稍微复杂一些,不过可以把@Around
理解为@Before
和@After
的整合
- 相当于@Before,执行切点方法开始运行前的程序
- 执行切点处的方法
- 相当于@After,执行切点方法运行结束之后的程序
运行效果图: