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

SpringBoot+Spring-Data-JPA:每次请求时ArrayList/JSON对象重复填充

解决Spring Boot中Prototype Service导致数据重复填充的问题

我之前处理过类似的场景,你遇到的重复填充问题,核心原因大概率是对Spring的Bean作用域理解不到位,或者Service内部的状态管理有问题,下面给你拆解原因和解决方案:

为什么会出现重复填充?

1. Controller是单例,但Prototype Service没有被正确获取

Spring中Controller默认是singleton作用域,也就是整个应用生命周期只有一个实例。如果你用@Autowired直接注入prototype作用域的Service,Controller只会在初始化时创建一次Service实例,后续所有请求都会复用这个Service——这就导致Service里的集合每次调用都会累加数据,自然返回的列表越来越长。

2. Service内部的状态没有重置

如果你的Service类里把存储Site的ArrayList定义成了成员变量,而不是在getItinerary方法内部创建,那不管Service是不是prototype,只要复用实例,集合里的数据就会不断叠加。

具体解决方案

方案一:让Controller每次请求都获取新的Prototype Service

因为Controller是单例,不能直接依赖注入prototype Bean,得用动态获取的方式:

方式1:使用@Lookup注解

在Controller里定义一个抽象方法来获取Service,Spring会动态实现这个方法,每次调用都返回新的Service实例:

@RestController
public class SiteController {

    @Lookup
    protected SiteService getSiteService() {
        return null; // 占位,Spring会自动实现
    }

    @RequestMapping("/getItinerary")
    public List<Site> getItinerary() {
        // 每次请求都拿到新的Service实例
        SiteService service = getSiteService();
        return service.getItinerary();
    }
}

方式2:通过ApplicationContext获取

直接注入ApplicationContext,每次请求时手动获取新的Service Bean:

@RestController
public class SiteController {

    @Autowired
    private ApplicationContext context;

    @RequestMapping("/getItinerary")
    public List<Site> getItinerary() {
        SiteService service = context.getBean(SiteService.class);
        return service.getItinerary();
    }
}

方案二:重置Service内部的状态(最稳妥的辅助方案)

不管Service的作用域是什么,都不要把集合作为成员变量,而是在getItinerary方法内部创建新的集合,从数据库查询后直接填充并返回:

@Service
@Scope("prototype")
public class SiteService {

    @Autowired
    private SiteRepository siteRepository;

    public List<Site> getItinerary() {
        // 每次调用都创建新的集合,避免数据累加
        List<Site> siteList = new ArrayList<>();
        siteList.addAll(siteRepository.findAll());
        return siteList;
    }
}

这样即使Service实例被复用,每次调用方法都会生成全新的列表,不会出现重复数据。

方案三:排查数据库查询逻辑

最后可以确认下你的SiteRepository查询方法(比如findAll())是否返回了重复数据——比如数据库里本身有没有重复的Site记录,或者查询条件是否存在问题。可以在Service里加日志打印查询到的列表长度,排除数据库层面的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 06:54:47