You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot中如何在端点被访问时自动调用指定函数?

可行解决方案

1. Spring AOP 全局/精准切入(推荐)

AOP能实现无侵入式的逻辑插入,不管是所有端点还是特定端点,都能通过切点表达式灵活配置执行时机。

示例代码:

第一步:引入AOP依赖(Maven)

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

第二步:定义切面类

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class DataInitAspect {

    private final FunctionIHaveToCall functionIHaveToCall;

    // 构造注入需要调用的类
    public DataInitAspect(FunctionIHaveToCall functionIHaveToCall) {
        this.functionIHaveToCall = functionIHaveToCall;
    }

    // 切点:匹配所有控制器的GetMapping方法
    @Before("execution(* com.yourpackage.controller.*.*(..)) && @annotation(org.springframework.web.bind.annotation.GetMapping)")
    public void initDataBeforeEndpoint() {
        functionIHaveToCall.setData();
    }

    // 若要匹配所有控制器方法(不限请求方式),切点改为:
    // @Before("execution(* com.yourpackage.controller.*.*(..))")
}

如果只针对特定端点,可缩小切点范围,比如指定某个控制器的具体方法:

@Before("execution(* com.yourpackage.controller.DataController.getdata(..))")

2. 自定义注解 + AOP(灵活控制特定端点)

如果需要手动指定哪些端点执行初始化逻辑,自定义注解配合AOP的方式更灵活。

示例代码:

第一步:自定义注解

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 NeedDataInit {
}

第二步:在目标控制器方法上标注注解

@GetMapping("/data")
@NeedDataInit
public Set<Mission> getdata() {
    return dataService.getData();
}

第三步:修改切面的切点规则

@Before("@annotation(com.yourpackage.annotation.NeedDataInit)")
public void initDataForAnnotatedEndpoints() {
    functionIHaveToCall.setData();
}

3. Filter 全局请求拦截

如果需要对所有HTTP请求(包括非控制器请求,如静态资源)执行初始化逻辑,使用Filter更合适。

示例代码:

import jakarta.servlet.*;
import jakarta.servlet.annotation.WebFilter;
import java.io.IOException;

@WebFilter(urlPatterns = "/*") // 可配置拦截路径,比如仅拦截/api/*
@Component
public class DataInitFilter implements Filter {

    private final FunctionIHaveToCall functionIHaveToCall;

    public DataInitFilter(FunctionIHaveToCall functionIHaveToCall) {
        this.functionIHaveToCall = functionIHaveToCall;
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        // 执行初始化逻辑
        functionIHaveToCall.setData();
        // 放行请求,执行后续逻辑
        chain.doFilter(request, response);
    }
}

关于你试过的方案补充说明

  • @ModelAttribute:若配合@ControllerAdvice使用,确实能全局执行,但它的设计初衷是向Model中添加属性,若你不需要往模型塞数据,AOP更贴合需求。
  • HandlerInterceptor:可能是之前配置有误,它本身可以实现请求前拦截(重写preHandle方法),需检查拦截路径配置、拦截器注册是否正确。但相比AOP,切点表达式的匹配灵活性稍弱。

内容的提问来源于stack exchange,提问作者Marcus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 22:50:20