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

Spring Boot中基于Meta注解的cursorBatchSize动态注入自定义注解问题

问题原因

原来的写法行不通,因为Spring的@Value注解不能直接用在自定义注解的属性上——注解属性的默认值是编译期确定的常量,@Value在这里不会被Spring解析,所以不管配置文件怎么配置,始终只会用默认的100。

解决方案

我们需要借助Spring的环境配置解析能力,结合Spring Data MongoDB的查询扩展机制,动态设置cursorBatchSize。具体步骤如下:

1. 重新定义自定义注解

去掉无效的@Value和@Meta元注解,改成带占位符的属性定义:

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

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
public @interface DynamicMeta {
    // 用占位符支持配置文件注入,默认值100
    String cursorBatchSize() default "${dynamic.cursor.batch.size:100}";
}

2. 实现查询后置处理器

编写一个QueryPostProcessor,在MongoDB查询执行前,解析@DynamicMeta注解的配置值,动态设置查询的Meta信息:

import org.springframework.context.EnvironmentAware;
import org.springframework.core.env.Environment;
import org.springframework.data.mongodb.core.query.Meta;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.repository.query.MongoQueryExecution;
import org.springframework.data.mongodb.repository.query.MongoQueryMethod;
import org.springframework.data.mongodb.repository.query.QueryPostProcessor;

public class DynamicMetaQueryPostProcessor implements QueryPostProcessor<Query, MongoQueryExecution>, EnvironmentAware {

    private Environment environment;

    @Override
    public void setEnvironment(Environment environment) {
        this.environment = environment;
    }

    @Override
    public MongoQueryExecution postProcess(MongoQueryExecution execution, MongoQueryMethod queryMethod, Query query) {
        // 优先读取方法上的注解,没有则读取类上的
        DynamicMeta dynamicMeta = queryMethod.getMethod().getAnnotation(DynamicMeta.class);
        if (dynamicMeta == null) {
            dynamicMeta = queryMethod.getRepositoryInterface().getAnnotation(DynamicMeta.class);
        }

        if (dynamicMeta != null) {
            // 解析占位符为实际数值
            String batchSizeStr = environment.resolvePlaceholders(dynamicMeta.cursorBatchSize());
            int batchSize = Integer.parseInt(batchSizeStr);
            // 给查询设置cursorBatchSize
            query.with(new Meta().cursorBatchSize(batchSize));
        }
        return execution;
    }
}

3. 注册处理器到Spring容器

在配置类中把上面的处理器注册成Bean:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MongoConfig {

    @Bean
    public DynamicMetaQueryPostProcessor dynamicMetaQueryPostProcessor() {
        return new DynamicMetaQueryPostProcessor();
    }
}

4. 使用自定义注解

直接在Repository接口或方法上添加@DynamicMeta即可:

import org.springframework.data.mongodb.repository.MongoRepository;
import java.util.List;

// 类级别的配置,所有方法默认使用这个配置
@DynamicMeta
public interface UserRepository extends MongoRepository<User, String> {

    // 方法级别的配置,会覆盖类级别
    @DynamicMeta(cursorBatchSize = "${dynamic.cursor.batch.size:200}")
    List<User> findByAgeGreaterThan(int age);
}

这样配置后,执行查询时Spring会自动读取application.properties中的dynamic.cursor.batch.size值,动态设置MongoDB查询的游标批次大小。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 15:35:41