自定义注解实现AOP面向切面编程

本文介绍了如何在Spring中使用AspectJ进行AOP编程,包括引入Maven依赖、自定义注解、定义切面类以及在Controller中应用注解进行日志记录和异常处理。主要涉及前置增强、环绕增强和后置处理等AOP概念,展示了如何在方法调用前后打印日志信息,并在发生异常时进行相应处理。
摘要由CSDN通过智能技术生成

直接上代码

1、maven导入依赖

<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.9.5</version>
</dependency>

2、自定义一个注解

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface LogOperation {
    String value()default "";
    int type()default 0;
}

3、自定义一个类写切入点代码

@Component
@Aspect
public class LogTrackAspect {

    @Pointcut(value = "@annotation(logOperation)")
    public void access(LogOperation logOperation){

    }
//前置增强
    @Before("access(logOperation)")
    public void doBefore(JoinPoint joinPoint,LogOperation logOperation) throws Throwable {

        System.out.println("-aop 日志记录启动-" + new Date());
        System.out.println("获取到的值"+logOperation.value());

    }
    
    //环绕增强,是在before前就会触发
    @Around("@annotation(logOperation)")
    public Object around(ProceedingJoinPoint pjp, LogOperation logOperation) throws Throwable {
        System.out.println("-aop 日志环绕阶段-" + new Date());
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
 
//        GET 请求其实可以从request里获取出参数
//       Map<String,String[]> map=request.getParameterMap();
//        System.out.println("获取参数:"+map.get("username")[0])
 
        String url = request.getRequestURL().toString();
        String ip = IpUtil.getIpAddr(request);
        String logTrackValue = logTrack.value();
        Object[] pipArrary = pjp.getArgs();
        if (pipArrary.length>1){ //多参,不是Map/JsonObject方式
            List<Object> argList = new ArrayList<>();
            for (Object arg : pjp.getArgs()) {
          // request/response无法使用toJSON
            if (arg instanceof HttpServletRequest) {
                       argList.add("request");
                 } else if (arg instanceof HttpServletResponse) {
                  argList.add("response");
                 } else {
                    argList.add(JSON.toJSON(arg));
            }
            }
         Signature signature = pjp.getSignature();
         MethodSignature methodSignature = (MethodSignature) signature;
        // 参数名数组
        String[] parameterNames = ((MethodSignature) signature).getParameterNames();
            System.out.println("参数名数组:"+new ArrayList(Arrays.asList(parameterNames)));
            System.out.println("参数是:"+argList.toString());
            System.out.println("logTrackValue:"+logTrackValue);
            System.out.println("url:"+url);
            System.out.println("ip:"+ip);
            return pjp.proceed();
            
        }
 
        Object param =  pipArrary[0];
        System.out.println("logTrackValue:"+logTrackValue);
        System.out.println("url:"+url);
        System.out.println("ip:"+ip);
        System.out.println("param:"+param.toString());
        return pjp.proceed();
 
    }

    
    @AfterThrowing(value = "serviceStatististics(operation)", throwing = "e")
    public void doAfterThrowing(LogOperation operation, Throwable e) {
        //设置异常信息
//        long happenTime = System.currentTimeMillis();
//        logException.setHappentime(new Date(happenTime));
//        logException.setExceptionjson(e.getMessage());
//        logException.setExceptionmessage(e.getMessage());
//        logExceptionMapper.insert(logException);
    }
}

4、将注解加到你想要的切入的方法上

@Controller
@RequestMapping("/user")
public class UserController {
    @Autowired
    private UserService userService;

    @RequestMapping("/test")
    @ResponseBody
    @LogOperation(value = "测试切面")	//当你访问user/test时,就会执行LogTrackAspect 类中的代码
    public String test(){
        return "test切面";
    }
}

过滤的顺序顺序如下:
@Around-joinPoint.proceed(args)前
@Before
@Around-joinPoint.proceed(args)后
@After
@AfterReturning/@AfterThrowing

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值