Suppose I have the following JPA repository:
public interface IGreetingRepository extends JpaRepository<Greeting, Long> {
}
And according to the documentation you would have to generate a service interface as follows:
public interface IGreetingService {
Greeting getGreetingById(Long id);
List<Greeting> getAllGreetings();
Greeting saveGreeting(Greeting greeting);
void deleteGreeting(Long id);
}
And after the implementation:
@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);
}
}
And to make use of my service in my controllers I would inject it like this:
@Autowired
@Qualifier("greetingService")
GreetingService greetingService;
What I don't understand is, what is the advantage of doing it like this instead of directly injecting the JPA repository interface and saving me the 2 classes?:
@Autowired
@Qualifier("greetingRepository")
IGreetingRepository greetingRepository;
Interfaces have several advantages:
Abstraction
An interface is like a contract. The service that implements an interface is required to offer a series of methods with well-defined signatures. Any service that wants to comply with the interface will have to have a certain set of elements. This allows you to connect to different services using the same client.
Usability
If your service implements an interface, you could completely rewrite it (or replace it with a different one) and clients could continue to consume your service without problems. They will at most notice differences in performance, but little else.
Security
An interface represents only a statement of intent. There is no code anywhere. By exposing an interface you are not compromising the source code of the service.
Maintenance
If a service exposes an interface, your development environment can easily verify that a new version of the service meets (at least) the requirements exposed in the interface. It's an easy way to automate a process that prevents you from forgetting to implement some of the functionality. This feature often improves the maintenance rate of projects.
With all of this, it seems almost self-evident that it is good practice to expose interfaces whenever possible. That a system like spring forces you to expose interfaces instead of implementations is good news for your service.