1.是什么?
AOP是面向切面编程,就是将项目中重复的代码块抽离出来,在一个地方统一实现。比如:日志、事务、权限认证等功能。
AOP的5种通知:
- @Before:前置通知,在切点之前执行;
- @After:后置通知,在切点之后执行,不管是否发生异常都会执行;
- @AfterRuturning:返回通知,在切点之后执行,只有正常返回时才会执行;
- @AfterThrowing:异常通知,发生异常才会执行;
- @Around:环绕通知,在切点之前以及之后执行;
2.为什么?
提高了代码复用率,简化开发。
3.怎么做?
接下来我们在SpringBoot项目中实现一个简单的AOP demo。
实现步骤:
1.导入aop相关包
2.写一个userController类
3.使用@Aspect实现一个切面类,对userController中的所有方法进行切入
1.导入aop相关包
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
2.写一个userController类
package inesv.aopDemo;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.Map;
@RestController
@RequestMapping("user")
public class UserController {
@RequestMapping("addUser")
public String addUser(){
System.out.println("add user");
return "add";
}
@RequestMapping("selectUser")
public Map selectUser(){
Map resultMap = new HashMap();
System.out.println("select user");
return resultMap;
}
}
3.使用@Aspect实现一个切面类,对userController中的所有方法进行切入
package inesv.aopDemo;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
@Component //注册为Bean
@Aspect // 注册为一个切面类
public class LogAspect {
Logger log = LoggerFactory.getLogger(LogAspect.class);
/*
*定义一个统一切点
* execution指定了切点表达式,这个表达式代表向inesv.aopDemo包及其子包下的所有类所有public方法进行切入
*/
@Pointcut("execution(public * inesv.aopDemo..*.*(..))")
public void Pointcut() {
}
//前置通知
@Before("Pointcut()")
public void beforeMethod(JoinPoint joinPoint){
log.info("调用了前置通知:");
}
//后置通知
@After("Pointcut()")
public void afterMethod(JoinPoint joinPoint){
log.info("调用了后置通知");
}
//返回通知,a为返回内容
@AfterReturning(value="Pointcut()",returning="r")
public void afterReturningMethod(JoinPoint joinPoint,Object r){
log.info("调用了返回通知:"+r);
}
//异常通知,e为异常对象
@AfterThrowing(value="Pointcut()",throwing="e")
public void afterThrowingMethod(JoinPoint joinPoint, Exception e){
log.info("调用了异常通知");
}
//环绕通知
@Around("Pointcut()")
public Object Around(ProceedingJoinPoint pjp) throws Throwable {
log.info("around执行方法之前");
Object object = pjp.proceed();
log.info("around执行方法之后--返回值:" +object);
return object;
}
}
4.总结:以上就是AOP的简单实现,如果对切点表达式execution不了解的,可以看看这篇文章:Aspectj切入点语法定义