本文采用SpringBoot技术编写一个Spring AOP 示例。
一、引入依赖
<!--引入AOP依赖--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId></dependency>
:::warning 注意:在完成了引入AOP依赖包后,不需要去做其他配置。AOP的默认配置属性中,spring.aop.auto属性默认是开启的,也就是说只要引入了AOP依赖后,默认已经增加了@EnableAspectJAutoProxy,不需要在程序主类中增加@EnableAspectJAutoProxy来启用。 :::
二、定义切面
定义切面类:在类上添加@Aspect 和@Component 注解即可将一个类定义为切面类。
@Aspect 注解 使之成为切面类
@Component 注解 把切面类加载到到IOC容器中,Bean交给Spring容器管理
package com.king.aop.aspect;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 org.springframework.web.context.request.RequestContextHolder;import org.springframework.web.context.request.ServletRequestAttributes;import javax.servlet.http.HttpServletRequest;import java.util.Arrays;import java.util.Objects;/*** 日志切面* @PackageName com.king.aop.aspect* @ClassName LogAspect* @Auther jgg* @Date 2021-7-5 10:16*/@Aspect@Componentpublic class LogAspect {private static final Logger logger = LoggerFactory.getLogger(LogAspect.class);@Pointcut("execution(public * com.king.aop.controller.*.*(..))")public void webLog(){}/*前置通知*/@Before("webLog()")public void doBefore(JoinPoint joinPoint) throws Throwable{//接收到请求,记录请求信息ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();HttpServletRequest request= attributes.getRequest();//记录请求信息System.out.println("URL" + request.getRequestURL().toString());System.out.println("request.getMethod() = " + request.getMethod());System.out.println("IP:" + request.getRemoteHost());System.out.println("Class+Methord" + joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName());System.out.println("params" + Arrays.toString(joinPoint.getArgs()));logger.info("user ip: {}",request.getRemoteAddr());}//后置异常通知@AfterThrowing("webLog()")public void throwss(JoinPoint jp){System.out.println("方法异常时执行...");}//后置最终通知,final增强,不管是抛出异常或者正常退出都会执行@After("webLog()")public void after(JoinPoint jp){System.out.println("方法最后执行...");}@AfterReturning(returning = "obj",pointcut = "webLog()")public void doAfterReturing(Objects obj) throws Throwable{System.out.println("方法返回值为:"+obj);logger.info("方法返回值为: {}",obj);}/*** 环绕通知* @param point* @throws Throwable*/@Around("webLog()")public void doAround(ProceedingJoinPoint point) throws Throwable{System.out.println("方法环绕Running...");try {Object proceed = point.proceed();System.out.println("方法环绕proceed,结果是 :" + proceed);logger.info("方法返回值:{}",proceed);} catch (Throwable throwable) {throw throwable;}}}
采用自定义注解的形式实现 Spring AOP
自定义注解
import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;/*** @PackageName com.king.aop.aspect* @ClassName UserAspect* @Auther jgg* @Date 2021-7-6 9:31*/@Target({ElementType.METHOD,ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)public @interface UserAccess {String desc() default "No Data!";}
定义切面
package com.king.aop.aspect;import org.aspectj.lang.JoinPoint;import org.aspectj.lang.ProceedingJoinPoint;import org.aspectj.lang.annotation.*;import org.springframework.stereotype.Component;import java.util.Date;/*** @PackageName com.king.aop.aspect* @ClassName UserAccessAspect* @Auther jgg* @Date 2021-7-6 9:35*/@Component@Aspectpublic class UserAccessAspect {@Pointcut(value ="@annotation(com.king.aop.aspect.UserAccess)")public void access(){}@Before("access()")public void doBefore(JoinPoint point){System.out.println("-aop 日志记录启动-" + new Date());}/*环绕通知*/@Around("@annotation(userAccess)")public Object around(ProceedingJoinPoint pjp, UserAccess userAccess) {//获取注解里的值System.out.println("second around:" + userAccess.desc());try {return pjp.proceed();} catch (Throwable throwable) {throwable.printStackTrace();return null;}}//进来切点这,最后经过的一个站,也是方法正常运行结束后@After("access()")public void after(JoinPoint joinPoint) {System.out.println("-aop 日志记录结束-" + new Date());}}
三、知识补充
切点表达式
https://www.cnblogs.com/javazhiyin/p/9993299.html
原文链接:https://blog.csdn.net/qq_35387940/article/details/85261279
https://www.cnblogs.com/zhangxufeng/p/9160869.html
