面向切面AOP介绍
面向切面(AOP)Aspect Oriented Programming是一种编程范式,与语言无关,是一种程序设计思想,它也是spring的两大核心之一。
- 1.引入依赖
在pom.xml文件中,添加以下依赖
<!--使用aop的组件-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
- 2.新建aspect包,包下建HttpAspect.java文件
private final static org.slf4j.Logger logger = LoggerFactory.getLogger(HttpAspect.class);
此为自带日志框架,
- @Aspect—— 切面
- @Component —— 把普通pojo实例化到spring容器中
- logger.info()——以日志形式输出
- @Pointcut() —— 定义切点
- execution() ——切入点表达式
- “*”(表达式中的*) —— 代表所有,任意
- @Before —— 在被拦截的方法执行前就执行该before注解的方法
- @After —— 在被拦截的方法执行后执行该after注解的方法
- @AfterReturning —— 在被拦截的方法执行后执行该after注解的方法,并将被拦截方法的返回值传给该方法
简便方法:
先定义切点,再使用切点,就不用每个方法都写长长的切点了
@Pointcut("execution(public * com.demo.springbootdemo.controller.GirlController.*(..))")
public void log(){
}
@Before("log()") 等价于 @Before(pointcut = "log()")
@After("log()")
完整代码如下:
package com.demo.springbootdemo.aspect;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.util.logging.Logger;
@Aspect /*切面*/
@Component /*把普通pojo实例化到spring容器中*/
public class HttpAspect {
private final static org.slf4j.Logger logger = LoggerFactory.getLogger(HttpAspect.class); //自带日志框架
@Pointcut("execution(public * com.demo.springbootdemo.controller.GirlController.*(..))")
public void log(){
}
/* @Before在方法执行前就被执行
方法里面加两个点,表示任何参数都会会拦截
girlController中所有方法都会被拦截 */
@Before("execution(public * com.demo.springbootdemo.controller.GirlController.*(..))")
public void doBefore(JoinPoint joinPoint){
logger.info("11111111"); // 以日志形式输出
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
/* url */
logger.info("url={}",request.getRequestURL());
/* method */
logger.info("method={}",request.getMethod());
/* ip */
logger.info("ip={}",request.getRemoteAddr());
/* 类方法 */
logger.info("class_method={}",joinPoint.getSignature().getDeclaringTypeName()+"."+joinPoint.getSignature().getName());
/* 参数 */
logger.info("args={}",joinPoint.getArgs());
}
//@Before在方法执行后被执行
/*@After("execution(public * com.demo.springbootdemo.controller.GirlController.*(..))")
public void doAfter(){
System.out.println("222222");
}*/
//方式二 ,省略每一个都写长长的重复内容
@After("log()")
public void doAfter(){
logger.info("2222222");
}
@AfterReturning(returning = "object" , pointcut = "log()")
public void doAfterReturning(Object object){
//logger.info("response={}",object.toString()); 为了方便后续代码使用,先注释掉
}
}