SpringBoot中怎么利用AOP和拦截器实现自定义注解

发布时间:2022-07-04 10:18:04 作者:iii
来源:亿速云 阅读:221

SpringBoot中怎么利用AOP和拦截器实现自定义注解

在Spring Boot中,AOP(面向切面编程)和拦截器是两种常用的技术,用于在方法执行前后插入自定义逻辑。通过结合AOP和拦截器,我们可以实现自定义注解,从而在方法或类上添加特定的行为。本文将详细介绍如何在Spring Boot中利用AOP和拦截器实现自定义注解。

1. 自定义注解

首先,我们需要定义一个自定义注解。假设我们要实现一个注解@LogExecutionTime,用于记录方法的执行时间。

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface LogExecutionTime {
}

这个注解可以应用于方法上,并且会在运行时保留。

2. 使用AOP实现注解逻辑

接下来,我们使用AOP来实现@LogExecutionTime注解的逻辑。AOP允许我们在方法执行前后插入自定义逻辑。

2.1 添加依赖

首先,确保在pom.xml中添加了Spring Boot的AOP依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

2.2 创建切面类

然后,创建一个切面类LogExecutionTimeAspect,用于处理@LogExecutionTime注解的逻辑。

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class LogExecutionTimeAspect {

    @Around("@annotation(LogExecutionTime)")
    public Object logExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable {
        long startTime = System.currentTimeMillis();

        Object proceed = joinPoint.proceed();

        long executionTime = System.currentTimeMillis() - startTime;

        System.out.println(joinPoint.getSignature() + " executed in " + executionTime + "ms");

        return proceed;
    }
}

在这个切面类中,我们使用@Around注解来定义环绕通知。@Around注解的参数@annotation(LogExecutionTime)表示这个通知会应用于所有带有@LogExecutionTime注解的方法。

2.3 使用注解

现在,我们可以在任何方法上使用@LogExecutionTime注解来记录方法的执行时间。

import org.springframework.stereotype.Service;

@Service
public class MyService {

    @LogExecutionTime
    public void doSomething() {
        // 模拟耗时操作
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

当调用doSomething()方法时,控制台会输出方法的执行时间。

3. 使用拦截器实现注解逻辑

除了AOP,我们还可以使用拦截器来实现自定义注解的逻辑。拦截器通常用于处理HTTP请求,但也可以用于其他场景。

3.1 创建拦截器

首先,创建一个拦截器LogExecutionTimeInterceptor,用于处理@LogExecutionTime注解的逻辑。

import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;

@Component
public class LogExecutionTimeInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if (handler instanceof HandlerMethod) {
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            Method method = handlerMethod.getMethod();
            if (method.isAnnotationPresent(LogExecutionTime.class)) {
                long startTime = System.currentTimeMillis();
                request.setAttribute("startTime", startTime);
            }
        }
        return true;
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        if (handler instanceof HandlerMethod) {
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            Method method = handlerMethod.getMethod();
            if (method.isAnnotationPresent(LogExecutionTime.class)) {
                long startTime = (Long) request.getAttribute("startTime");
                long executionTime = System.currentTimeMillis() - startTime;
                System.out.println(method.getName() + " executed in " + executionTime + "ms");
            }
        }
    }
}

在这个拦截器中,我们在preHandle方法中记录方法的开始时间,并在afterCompletion方法中计算并输出方法的执行时间。

3.2 注册拦截器

接下来,我们需要将拦截器注册到Spring Boot中。创建一个配置类WebConfig,用于注册拦截器。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Autowired
    private LogExecutionTimeInterceptor logExecutionTimeInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(logExecutionTimeInterceptor);
    }
}

3.3 使用注解

现在,我们可以在控制器方法上使用@LogExecutionTime注解来记录方法的执行时间。

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class MyController {

    @GetMapping("/doSomething")
    @LogExecutionTime
    public String doSomething() {
        // 模拟耗时操作
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "Done";
    }
}

当访问/doSomething端点时,控制台会输出方法的执行时间。

4. 总结

通过结合AOP和拦截器,我们可以在Spring Boot中轻松实现自定义注解。AOP适用于在方法执行前后插入自定义逻辑,而拦截器则更适合处理HTTP请求。根据具体需求,我们可以选择合适的技术来实现自定义注解的功能。

在实际开发中,自定义注解可以用于日志记录、权限校验、性能监控等场景,帮助我们更好地管理和维护代码。

推荐阅读:
  1. springboot中过滤器和拦截器如何实现
  2. 怎么在SpringBoot中利用AOP处理请求日志

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

springboot aop

上一篇:C#怎么对桌面应用程序自定义鼠标光标

下一篇:Node.js中async和await关键字如何使用

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》