如何通过构造方法赋值Builder对象及解决Bean循环依赖报错
问题解答
1 构造方法赋值实现
你首先需要在类中新增对应的成员变量来存储配置对象,不要在构造方法中调用@Bean修饰的settingsTemplate()方法赋值,正确的写法如下:
public class BigtableChannelPrimer implements ChannelPrimer { // 新增成员变量存储配置,后续其他方法可直接调用 private EnhancedBigtableStubSettings settingsTemplate; // 如果需要复用Builder,可新增成员存储Builder实例 private EnhancedBigtableStubSettings.Builder settingsBuilder; private List<String> appName; // 构造方法直接给成员变量赋值 public BigtableChannelPrimer( EnhancedBigtableStubSettings settingsTemplate, List<String> appName) { this.settingsTemplate = settingsTemplate; // 如果需要存Builder,这里直接从settings对象转 this.settingsBuilder = settingsTemplate.toBuilder(); this.appName= appName; } // 其余原有方法... }
另外你原有create()方法里存在语法错误:调用setProjectId(projectId)后直接调用了build(),此时返回的是EnhancedBigtableStubSettings实例而非Builder,需要删掉末尾多余的build()和多余的右括号,修正后如下:
EnhancedBigtableStubSettings.Builder builder = EnhancedBigtableStubSettings.newBuilder() .setProjectId(projectId);
2 类内其他方法复用Builder的方案
有两种可选方案:
- 方案一:构造方法中将传入的
settingsTemplate通过toBuilder()方法转为Builder实例,存在类成员变量中,其他方法直接调用该成员即可 - 方案二:不存Builder实例,需要用的时候调用
this.settingsTemplate.toBuilder()生成新的Builder实例,适合不需要复用修改状态的场景
3 循环依赖报错原因
报错是因为你的Bean定义逻辑形成了闭环:
settingsTemplate是定义在BigtableChannelPrimer类中的实例方法,Spring要创建这个Bean,必须先实例化BigtableChannelPrimer类的对象- 而
BigtableChannelPrimer类本身的实例化(通过create()方法生成Bean),又依赖settingsTemplate这个Bean注入到构造方法中 - 同时你还存在两个错误的Bean定义写法:
settingsTemplate()方法是private权限,@Bean方法不允许用private修饰;create()方法也是类实例方法,要调用它也需要先有类实例,进一步加重了循环依赖
你可以把settingsTemplate这个Bean的定义移到单独的配置类中,或者直接删除这个@Bean方法,因为你在create()方法中已经手动构建了EnhancedBigtableStubSettings实例传给构造方法,不需要再单独注册这个Bean。
内容的提问来源于stack exchange,提问作者Sweety
相关产品推荐
相关产品推荐

