【问题标题】:Spring dependency injection with inheritance带有继承的Spring依赖注入
【发布时间】:2021-11-05 15:18:09
【问题描述】:

我已决定将我的服务从 Spring setter-injection 更新为 constructor-injection 以逐步摆脱循环依赖关系。问题是服务使用继承,并且父服务和子服务都有自己的字段。所以问题是 - 使用Lombok 实现构造函数注入的最佳方法是什么。 以下是原始代码示例:

@Setter(onMethod_ = @Autowired)
public abstract class BaseService {
    
    protected FooService fooService;
}

@Service
@Setter(onMethod_ = @Autowired)
public class ConcreteService extends BaseService {
    
    private BarService barService;
}

FooService 用于BaseServiceConcreteService。 以下是可能的解决方案:

1.ConcreteService 中实现constructor-injection

@Setter(onMethod_ = @Autowired)
public abstract class BaseService {
    
    protected FooService fooService;
}

@Service
@RequiredArgsConstructor
public class ConcreteService extends BaseService {
    
    private final barService BarService;
}

我们很好地使用了@RequiredArgsConstructor注解,因为不需要调用superLombok不支持调用super)。即使两个类中有更多字段,代码看起来也很紧凑。但是我们在BaseService 中仍然没有constructor-injection

2. 将受保护的构造函数添加到BaseService 并在ConcreteService 构造函数中调用super

@RequiredArgsConstructor(AccessLevel.PROTECTED)
public abstract class BaseService {
    
    protected final FooService fooService;
}

@Service
public class ConcreteService extends BaseService {
    
    private final BarService barService;
    
    public ConcreteService(FooService fooService, BarService barService) {
        super(fooService);
        this.barService = barService;
    }
}

实现的主要目标 - constructor-injection 已实现,BaseService 看起来不错,但 ConcreteService 有一个丑陋的构造函数,其中应该传递两个服务的所有参数(并且可能是大量参数)。让我们再试一次。

3.将所有字段移至ConcreteService,在BaseService中实现protected getter以访问FooService

public abstract class BaseService {
    
    protected abstract FooService getFooService();
}

@Service
@RequiredArgsConstructor
public class ConcreteService extends BaseService {
    
    private final FooService fooService;
    private final BarService barService;

}

主要目标也实现了 - 我们有一个constructor-injection,构造函数看起来很干净,但现在我们应该在所有BaseService 继承者中都有一个FooService(当然可以有多个字段)。

所有解决方案都各有利弊,但也许有更好的解决方案?

【问题讨论】:

    标签: java spring inheritance dependency-injection lombok


    【解决方案1】:

    归根结底,这与其说是一个技术问题,不如说是一个意见问题。这些很棒的工具(即 Lombok、Spring 等)是为了让编码更容易,所以当有疑问时,我们应该回到基础。考虑从抽象类继承类的情况,而您没有这些工具。显然,初始化它的正确(也是唯一可能的)方法(如果您想保持代码解耦)是使用继承类中的构造函数参数(也非常类似于您的第二个选项)。

    如果看起来很丑而且数量很多,那只能说明设计不够理想,可能是这个领域的问题,而不是技术领域的问题。也许班级应该分成几个?在这种情况下使用抽象类而不是接口/具体类会更好吗?显然,我不知道您的代码必须解决的挑战,但值得考虑设计。

    【讨论】:

      猜你喜欢
      • 2015-09-03
      • 1970-01-01
      • 2023-03-28
      • 2017-06-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-24
      相关资源
      最近更新 更多