面向切面编程(AOP):利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
简单点理解就是:不通过修改源代码方式,在主干功能里面添加新功能
AOP的底层使用的是动态代理方式;
连接点指的是哪些方法可以被增强,这些方法称为连接点
实际被真正增强的方法,称为切入点
实际增强的逻辑部分(扩展的功能)称为通知或增强
通知有多种类型
把通知应用到切入点的过程
知道对哪个类里面的方法进行增强
execution([权限修饰符] [返回类型] [类全路径] [方法名称][参数列表])
对com.atguigu.dao.BookDao类里面的add进行增强
execution(* com.atguigu.dao.BookDao.add(…))
对com.atguigu.dao.BookDao类里面的所有的方法进行增强
execution(* com.atguigu.dao.BookDao.* (…))
对com.atguigu.dao包里面所有类,类里面所有方法进行增强
execution(* com.atguigu.dao.. (…))
权限修饰符可省略,
返回类型用通配符*代替
(…) 代表可变参数
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-aopartifactId>
dependency>
@Aspect
@Component
public class HttpAspect {
}
要加上@Aspect注解和@Component注解
这里介绍几个常见的通知
在访问到目标方法(add)方法之前,先执行此方法;
在此方法中可以获取request对象,获取请求的URL,请求方法,ip,类方法,请求参数
private final static Logger logger = LoggerFactory.getLogger(HttpAspect.class);
//这里定义looger,为了后面使用日志进行记录
@Before(value = "execution(* com.atguigu.spring5.aopanno.User.add(..))")
public void doBefore(JoinPoint joinPoint) {
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();//获取request
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());
}
注意:
如果要获取请求方法和参数,需要传入JoinPoint作为形参
@After(value = "execution(* com.atguigu.spring5.aopanno.User.add(..))")
public void after() {
System.out.println("after.........");
}
在目标方法返回对象之后,此方法接收返回值;
@AfterReturning(returning = "object", pointcut = "log()")
public void doAfterReturning(Object object) {
logger.info("response={}", object.toString());
}
@AfterThrowing(value="execution(*com.atguigu.spring5.aopanno.User.add(..))")
public void afterThrowing() {
System.out.println("afterThrowing.........");
}
//抽取切入点
@Pointcut(value = "execution(* com.atguigu.spring5.aopanno.User.add(..))")
public void pointdemo() {
}
//前置通知
@Before(value = "pointdemo()")
public void before() {
System.out.println("before.........");
}