Serveis a Spring Boot
Els serveis s’encarreguen de la lògica de negoci, la qual defineix com han de funcionar les operacions de l’aplicació. A més, actuen com una capa intermediària entre els controladors i els repositoris (o altres fonts de dades). Aquest enfocament permet una millor organització del codi i facilita el manteniment i l’escalabilitat.
1. Què és un servei?
Un servei és una classe Java que encapsula la lògica de negoci de l’aplicació:
- És el lloc on es defineixen les regles de negoci i operacions més complexes.
- Interactua amb els repositoris per accedir a la base de dades.
- Ofereix funcionalitats als controladors, que gestionen les peticions de l’usuari.
2. Components bàsics d’un servei
Els serveis a Spring Boot es defineixen utilitzant diverses anotacions i conceptes.
Anotacions dels serveis
- 1.
@Service
- Marca la classe com un component de servei, indicant que conté la lògica de negoci.
- Spring detecta les classes anotades amb
@Service
durant l’escaneig del context i les registra com a beans.
Exemple:
@Service // Marca aquesta classe com un servei de Spring
public class PaisService {
// Aquí encapsularem la lògica relacionada amb "Pais"
}
- 2.
@Autowired
- Indica a Spring que ha d’injectar automàticament una dependència (com un repositori o un altre servei) en un camp, constructor o mètode.
Exemple:
@Service
public class PaisService {
@Autowired // Spring injecta automàticament un bean compatible
private PaisRepository paisRepository;
public List<Pais> obtenirTotsElsPaisos() {
return paisRepository.findAll(); // Recupera tots els països
}
}
- 3.
@PostConstruct
- Executa un mètode específic després que Spring haja inicialitzat el bean i injectat totes les dependències.
Exemple:
@Service
public class PaisService {
@Autowired
private PaisRepository paisRepository;
@PostConstruct
public void inicialitzar() {
System.out.println("Servei inicialitzat: " + paisRepository.count() + " països a la base de dades.");
}
}
Nota: Aquesta anotació s’utilitza per a tasques d’inicialització o configuració que es realitzen després de la creació del bean.
- 4.
@PreDestroy
- Executa un mètode específic abans de destruir el bean, es sol utilitzar per a tasques de neteja o alliberament de recursos.
Exemple:
@Service
public class PaisService {
@PreDestroy
public void alliberarRecursos() {
paisRepository.flush(); // Allibera la sessió de JPA, es a dir fa un commit de les dades a la base de dades
System.out.println("Servei alliberant recursos...");
}
}
3. Exemple de servei
Repositori:
@Repository
public interface PaisRepository extends JpaRepository<Pais, Long> {
// Operacions CRUD disponibles gràcies a JpaRepository
List<Pais> findByNomContaining(String partNom); // Cerca països pel nom parcial
}
Servei:
@Service
public class PaisService {
private final PaisRepository paisRepository; // Dependència injectada
// Injecció per constructor
@Autowired
public PaisService(PaisRepository paisRepository) {
this.paisRepository = paisRepository;
}
// Lògica de negoci: Obtenir tots els països
public List<Pais> obtenirTotsElsPaisos() {
return paisRepository.findAll(); // Recupera tots els països de la base de dades
}
// Lògica de negoci: Cerca països pel nom
public List<Pais> cercarPaisosPerNom(String partNom) {
return paisRepository.findByNomContaining(partNom); // Cerca països que contenen "partNom"
}
@PostConstruct
public void inicialitzar() {
System.out.println("Servei inicialitzat amb " + paisRepository.count() + " països.");
}
}
4. Variants de serveis
- Serveis senzills:
- Gestionen operacions bàsiques, com ara accedir o modificar dades.
- Exemple:
PaisService
en l’exemple anterior.
- Serveis compostos:
- Utilitzen altres serveis com a dependències.
- Exemple:
@Service public class InformeService { private final PaisService paisService; @Autowired public InformeService(PaisService paisService) { this.paisService = paisService; } public void generarInforme() { List<Pais> paisos = paisService.obtenirTotsElsPaisos(); System.out.println("Informe generat amb " + paisos.size() + " països."); } }
Al exemple:
InformeService
és un servei que depèn dePaisService
.- En el mètode
generarInforme
, s’obtenen tots els països utilitzantpaisService
i es mostra un missatge amb el nombre de països.- Obté una llista de països des de PaisService i mostra per consola quants s’han obtingut.
- Composició de serveis: InformeService no implementa la lògica per accedir als països directament, sinó que reutilitza PaisService per a això.
- InformeService només genera informes; la lògica per obtenir països es delega a PaisService.
- Serveis transaccionals:
- S’utilitzen per garantir que una sèrie d’operacions es realitzen completament o es desfan.
- Exemple:
@Service @Transactional public class TransaccioService { private final PaisRepository paisRepository; @Autowired public TransaccioService(PaisRepository paisRepository) { this.paisRepository = paisRepository; } public void eliminarPaisAmbTransaccio(Long id) { paisRepository.deleteById(id); // Aquí pots incloure altres operacions dins de la transacció } }
6. En resum
Aspecte | Descripció |
---|---|
Què és un servei? | Classe que encapsula la lògica de negoci i interactua amb repositoris o altres serveis. |
Tipus d’injecció | Constructor (recomanat), Setter, Directa al camp. |
Anotacions principals | @Service , @Autowired , @PostConstruct . |
Exemples d’ús | Serveis senzills, compostos, i transaccionals per garantir operacions segures i modulars. |