您好,登录后才能下订单哦!
在Spring Boot中,AOP(面向切面编程)和拦截器是两种常用的技术,用于在方法执行前后插入自定义逻辑。通过结合AOP和拦截器,我们可以实现自定义注解,从而在方法或类上添加特定的行为。本文将详细介绍如何在Spring Boot中利用AOP和拦截器实现自定义注解。
首先,我们需要定义一个自定义注解。假设我们要实现一个注解@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 {
}
这个注解可以应用于方法上,并且会在运行时保留。
接下来,我们使用AOP来实现@LogExecutionTime
注解的逻辑。AOP允许我们在方法执行前后插入自定义逻辑。
首先,确保在pom.xml
中添加了Spring Boot的AOP依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
然后,创建一个切面类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
注解的方法。
现在,我们可以在任何方法上使用@LogExecutionTime
注解来记录方法的执行时间。
import org.springframework.stereotype.Service;
@Service
public class MyService {
@LogExecutionTime
public void doSomething() {
// 模拟耗时操作
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
当调用doSomething()
方法时,控制台会输出方法的执行时间。
除了AOP,我们还可以使用拦截器来实现自定义注解的逻辑。拦截器通常用于处理HTTP请求,但也可以用于其他场景。
首先,创建一个拦截器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
方法中计算并输出方法的执行时间。
接下来,我们需要将拦截器注册到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);
}
}
现在,我们可以在控制器方法上使用@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
端点时,控制台会输出方法的执行时间。
通过结合AOP和拦截器,我们可以在Spring Boot中轻松实现自定义注解。AOP适用于在方法执行前后插入自定义逻辑,而拦截器则更适合处理HTTP请求。根据具体需求,我们可以选择合适的技术来实现自定义注解的功能。
在实际开发中,自定义注解可以用于日志记录、权限校验、性能监控等场景,帮助我们更好地管理和维护代码。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。