Java中如何实现仅含3个参数的CourseService构造器并完成依赖初始化?
现有代码中CourseService继承自CourseBase,当前构造器仅接收CourseBaseOneRepository、CourseBaseTwoRepository两个参数。在构造器内实例化CourseGroupService时,mathRepository、biologyRepository等多个成员变量未初始化。需求是:将CourseService构造器调整为仅含3个参数,且无需将所有Repository放入构造器参数,实现这些变量的初始化。
相关代码示例:
// CourseGroupService代码 @Getter @Setter @AllArgsConstructor public class CourseGroupService { private MathRepository mathRepository; private BiologyRepository biologyRepository; // 其余Repository成员变量 public CourseGroupService(/* 对应参数列表 */) { /* 构造方法实现 */ } } // CourseService代码 public class CourseService extends CourseBase { private CourseGroupService courseGroupService; private MathRepository mathRepository; // 其余Repository成员变量 private CourseBaseOneRepository courseBaseOneRepository; private CourseBaseTwoRepository courseBaseTwoRepository; public CourseService(CourseBaseOneRepository repo1, CourseBaseTwoRepository repo2) { super(repo1, repo2); this.courseGroupService = new CourseGroupService(this.mathRepository, ...); } }
方案1:利用依赖注入框架(如Spring)自动处理
如果项目使用Spring这类依赖注入框架,不用手动传递所有Repository,直接把CourseGroupService作为第三个参数注入即可:
修改后代码:
// CourseGroupService保留@AllArgsConstructor,Spring会自动注入所有所需Repository @Getter @Setter @AllArgsConstructor public class CourseGroupService { private MathRepository mathRepository; private BiologyRepository biologyRepository; // 其余Repository成员变量 } // CourseService构造器改为3个参数 public class CourseService extends CourseBase { private CourseGroupService courseGroupService; private CourseBaseOneRepository courseBaseOneRepository; private CourseBaseTwoRepository courseBaseTwoRepository; public CourseService(CourseBaseOneRepository repo1, CourseBaseTwoRepository repo2, CourseGroupService courseGroupService) { super(repo1, repo2); this.courseBaseOneRepository = repo1; this.courseBaseTwoRepository = repo2; this.courseGroupService = courseGroupService; // 直接使用已初始化完成的实例 } }
Spring会通过CourseGroupService的全参构造器自动注入所有需要的Repository实例,CourseService只需要接收现成的CourseGroupService,不用关心每个Repository的初始化细节。
方案2:用工厂模式封装初始化逻辑
如果不依赖DI框架,可以编写一个工厂类来统一创建CourseGroupService实例,把工厂作为第三个参数传入:
修改后代码:
// 新增工厂类,统一处理Repository的初始化逻辑 public class CourseGroupServiceFactory { public CourseGroupService create() { MathRepository mathRepo = new MathRepository(); BiologyRepository biologyRepo = new BiologyRepository(); // 其余Repository的初始化逻辑 return new CourseGroupService(mathRepo, biologyRepo, ...); } } // CourseService构造器调整为3个参数 public class CourseService extends CourseBase { private CourseGroupService courseGroupService; private CourseBaseOneRepository courseBaseOneRepository; private CourseBaseTwoRepository courseBaseTwoRepository; public CourseService(CourseBaseOneRepository repo1, CourseBaseTwoRepository repo2, CourseGroupServiceFactory factory) { super(repo1, repo2); this.courseBaseOneRepository = repo1; this.courseBaseTwoRepository = repo2; this.courseGroupService = factory.create(); // 通过工厂获取已初始化的实例 } }
把所有Repository的初始化逻辑都封装到工厂类中,CourseService只依赖工厂对象,构造器参数保持3个,无需关心具体的Repository创建过程。
方案3:给CourseGroupService使用单例模式
如果CourseGroupService是全局复用的实例,可以改成单例模式,让其内部自行完成所有Repository的初始化:
修改后代码:
@Getter @Setter public class CourseGroupService { private static volatile CourseGroupService instance; private MathRepository mathRepository; private BiologyRepository biologyRepository; // 其余Repository成员变量 // 私有构造器,禁止外部直接实例化 private CourseGroupService() { // 内部自行初始化所有Repository this.mathRepository = new MathRepository(); this.biologyRepository = new BiologyRepository(); // 其余Repository的初始化逻辑 } // 双重校验锁实现线程安全的单例获取 public static CourseGroupService getInstance() { if (instance == null) { synchronized (CourseGroupService.class) { if (instance == null) { instance = new CourseGroupService(); } } } return instance; } } // CourseService构造器设为3个参数,第三个参数可传入配置类或其他占位对象 public class CourseService extends CourseBase { private CourseGroupService courseGroupService; private CourseBaseOneRepository courseBaseOneRepository; private CourseBaseTwoRepository courseBaseTwoRepository; public CourseService(CourseBaseOneRepository repo1, CourseBaseTwoRepository repo2, CourseConfig config) { super(repo1, repo2); this.courseBaseOneRepository = repo1; this.courseBaseTwoRepository = repo2; this.courseGroupService = CourseGroupService.getInstance(); // 获取已初始化的单例实例 } }
单例模式下CourseGroupService自行完成所有Repository的初始化,CourseService只需要通过单例方法获取实例,第三个参数可以用配置类之类的对象,满足构造器仅3个参数的要求。
内容的提问来源于stack exchange,提问作者lnikoli31

