假设我有以下 JPA 存储库:
public interface IGreetingRepository extends JpaRepository<Greeting, Long> {
}
根据文档,您必须生成一个服务接口,如下所示:
public interface IGreetingService {
Greeting getGreetingById(Long id);
List<Greeting> getAllGreetings();
Greeting saveGreeting(Greeting greeting);
void deleteGreeting(Long id);
}
并在实施后:
@Service
@Qualifier("greetingService")
public class GreetingServiceImpl implements IGreetingService {
@Autowired
@Qualifier("greetingRepository")
IGreetingRepository greetingRepository;
@Override
public Greeting getGreetingById(Long id) {
return greetingRepository.findOne(id);
}
@Override
public List<Greeting> getAllGreetings() {
return greetingRepository.findAll();
}
@Override
public Greeting saveGreeting(Greeting greeting) {
return greetingRepository.save(greeting);
}
@Override
public void deleteGreeting(Long id) {
greetingRepository.delete(id);
}
}
为了在我的控制器中使用我的服务,我会像这样注入它:
@Autowired
@Qualifier("greetingService")
GreetingService greetingService;
我不明白的是,这样做而不是直接注入JPA存储库接口并为我保存2个类有什么好处?:
@Autowired
@Qualifier("greetingRepository")
IGreetingRepository greetingRepository;
接口有几个优点:
抽象
接口就像合同。实现接口的服务需要提供一系列具有良好定义签名的方法。任何想要遵守接口的服务都必须有一组特定的元素。这允许您使用相同的客户端连接到不同的服务。
可用性
如果您的服务实现了一个接口,您可以完全重写它(或用不同的接口替换它)并且客户端可以继续使用您的服务而不会出现问题。他们最多会注意到性能上的差异,但几乎没有。
安全
接口仅代表意图声明。任何地方都没有代码。通过公开接口,您不会损害服务的源代码。
维护
如果服务公开了一个接口,您的开发环境可以轻松验证该服务的新版本是否满足(至少)该接口中公开的要求。这是一种自动化流程的简单方法,可防止您忘记实现某些功能。此功能通常会提高项目的维护率。
综上所述,几乎不言而喻的是,尽可能公开接口是一种好习惯。像 spring 这样的系统迫使您公开接口而不是实现,这对您的服务来说是个好消息。