1、什么是AOP
AOP即面向切面编程,在我的理解中,它就跟java中的代理一样的道理,都是用于不改变原有代码逻辑的情况下,对功能进行加强,比如在SpringBoot项目中,对某个功能进行权限分析,日志管理等前置后置或者环绕之类的一系列操作。
2、应用
目标:利用AOP完成SpringBoot项目中,当Service层的方法被调用后,打印被执行的函数以及该方法被调用的次数。
思路:
一、设置好切面类,包括,切入点,以及一些前置通知,后置通知等等
二、在切面类中的后置通知中,应该能够获取当前正在执行的方法,然后找个数据结构,比如Map,Map的健应该存储方法名,值应该存储该方法被执行的次数,然后在后置通知中打印即可
代码如下以下为切面类代码:
package com.example.springboottest.aop;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
@Aspect
@Component
public class AopC {
public Map<String, Integer> map = new HashMap<>();
@Pointcut("execution(* com.example.springboottest.Service.*.*(..))")
public void pointCut() {
}
@Before("pointCut()")
public void doBefore(JoinPoint joinPoint) {
Object[] args = joinPoint.getArgs();
String methodName = joinPoint.getSignature().getName();
System.out.println(methodName + "方法执行前...");
if (map.get(methodName) == null) {
map.put(methodName, 1);
} else {
map.put(methodName, map.get(methodName) + 1);
}
}
@After("pointCut()")
public void doAfter(JoinPoint joinPoint){
String methodName = joinPoint.getSignature().getName();
System.out.println(methodName+"方法执行后...");
System.out.println(methodName+"执行次数为:"+map.get(methodName));
}
}
需要注意的是,@Aspect需要加,否则Spring容器并不能够识别该类为切面类
@RestController
public class LoginContoller {
@Autowired
private UserSerivce userSerivce;
@RequestMapping("login")
public String login(String username,String password){
List<User> list=userSerivce.list();
if(list!=null){
list.forEach(System.out::println);
}
return "";
}
@GetMapping("login2")
public String login2(@Param("username") String username, @Param("password")String password){
User user=userSerivce.findUerByname(username,password);
System.out.println(user);
return "";
}
}
Controller层定义了两个方法,分别调用了两个Service层的两个不同方法,然后分别通过url去调用这两个个不同的Service层方法,下面是对结果的测试
上面没结果的原因是,上面Controller层这个方法是有参数的,访问url并没有 写参数,导致没参数没查出来,所以返回了个null