Spring Boot中@SafeVarargs与@Autowired类的兼容问题问询
解决@SafeVarargs与Spring Boot 2+代理冲突的方案
以下是几种可行的解决思路,针对你遇到的final方法无法被CGLIB代理导致mapper为null的问题:
方案一:用List参数替代可变参数,保留友好调用入口
将核心方法的可变参数改为List<Consumer<Dto>>,移除final修饰符让Spring代理正常工作,同时通过私有重载方法保留可变参数的调用方式,把@SafeVarargs限制在私有方法上:
@Repository public class Dao { private final DbMapper mapper; @Autowired public Dao(DbMapper mapper) { this.mapper = mapper; } // 核心非final方法,支持Spring代理 public Flux<Dto> getAll(List<Consumer<Dto>> filters) { return Flux.fromIterable(LibraryQueryBuilder.builder() .filters(filters.toArray(new Consumer[0])) .build() .execute(mapper) .getAll()); } // 私有重载方法,使用@SafeVarargs消除警告 @SafeVarargs private final Flux<Dto> getAll(Consumer<Dto>... filters) { return getAll(Arrays.asList(filters)); } }
方案二:升级Java至9+,移除方法final修饰符
Java 9及以上版本允许@SafeVarargs用于非final的公共实例方法,直接去掉final即可兼容Spring代理:
@Repository public class Dao { private final DbMapper mapper; @Autowired public Dao(DbMapper mapper) { this.mapper = mapper; } @SafeVarargs public Flux<Dto> getAll(Consumer<Dto>... filters) { return Flux.fromIterable(LibraryQueryBuilder.builder() .filters(filters) .build() .execute(mapper) .getAll()); } }
方案三:切换为JDK动态代理
让Dao实现接口,配置Spring使用JDK动态代理(基于接口而非类继承),这样即使方法是final的也不影响代理逻辑:
- 定义Dao接口:
public interface DaoInterface { Flux<Dto> getAll(Consumer<Dto>... filters); }
- 实现接口并保留final方法:
@Repository public class Dao implements DaoInterface { private final DbMapper mapper; @Autowired public Dao(DbMapper mapper) { this.mapper = mapper; } @SafeVarargs @Override public final Flux<Dto> getAll(Consumer<Dto>... filters) { return Flux.fromIterable(LibraryQueryBuilder.builder() .filters(filters) .build() .execute(mapper) .getAll()); } }
- 添加配置启用JDK代理:
spring.aop.proxy-target-class=false
方案四:替换@SafeVarargs为@SuppressWarnings("unchecked")
去掉final和@SafeVarargs,用@SuppressWarnings("unchecked")抑制泛型可变参数的编译器警告:
@Repository public class Dao { private final DbMapper mapper; @Autowired public Dao(DbMapper mapper) { this.mapper = mapper; } @SuppressWarnings("unchecked") public Flux<Dto> getAll(Consumer<Dto>... filters) { return Flux.fromIterable(LibraryQueryBuilder.builder() .filters(filters) .build() .execute(mapper) .getAll()); } }
内容的提问来源于stack exchange,提问作者RMSD
相关产品推荐
相关产品推荐

