N'injecter qu'une seule dépendance dans le constructeur du Bean-Service ?

a marqué ce sujet comme résolu.

Hello,

Voici un exemple pour illustrer ma question :

@Service
public class EmployeeService {
    private final DepartmentService departmentService;
    private final String additionalParameter;

        @Autowired  // CETTE ANNOTATION EST OPTIONNELLE DEPUIS UNE CERTAINE VERSION DE SPRING
        public EmployeeService(
                String additionalParameter,
                DepartmentService departmentService
        )
        {
            this.departmentService = departmentService;
            this.additionalParameter = additionalParameter;
        }

Le plugin Spring d’Intellij IDEA me dit que "Could not autowire. No beans of 'String' type found.", à juste titre puisque Spring va tenter d’injecter ces deux dépendances. Or, je souhaiterais que le deuxième paramètre ne soit pas une dépendance à injecter justement, mais une simple chaîne de caractères.

Cela signifie donc que je devrais pouvoir exécuter ça : new EmployeeService("bidule");, sans avoir besoin de spécifier le second paramètre, puisque Spring le ferait lui-même.

Sauf que je ne comprends pas comment faire. Je sais qu’il y a l’annotation @Value mais visiblement ce n’est pas non plus ce que je recherche. J’ai l’impression que dès qu’on déclare un Bean de type Service, on est obligé de subir la DI sur absolument tous les paramètres du constructeur, ce qui est bizarre.

Merci beaucoup et bonne soirée !

Jars

Lorsque tu annotates tes classes avec @Service (ou @Component et autres), tu demandes à Spring de gérer ces beans pour toi. Donc si dans une autre classe, tu as besoin de ce bean, Spring pourra te le fournir.

Donc quand tu dis que tu veux exécuter new EmployeeService("bidule");, ça va à l’encontre de ce principe. En demandant à Spring de gérer tes beans, tu lui demandes de créer les instances nécessaires et de te le fournir lorsque tu en as besoin. Donc si tu as besoin de bean, tu demandes à Spring, tu ne le crées pas toi-même "à la main".

Dans le cas que tu présentes, il faudrait plus de détails sur l’utilité de cette classe et de ce paramètres. En particulier, il serait bon de savoir à quelle fréquence tu devrais créer un nouveal EmployeeService. Une seule fois au démarrage de ton application ? Une fois par requête ? Plusieurs fois? Selon les cas, tu pourrais:

  • Passer cette chaine de caractères en tant que paramètres aux méthodes de EmployeeService qui en ont besoin
  • Si cette valeur est statique, utiliser @Value
  • Ne pas laisser Spring gérer ce service en particulier (donc enlever l’annotation @Service) et le créer à la main. Tu pourrais avoir quelque chose du genre
@Component
class EmployeeServiceFactory {
  private final DepartmentService departmentService;
  
  @Autowired
  public EmployeeServiceFactory(DepartmentService departmentService) {
    this.departmentService = departmentService;
  }
  
  public EmployeeService getEmployeeService(String additionalParameter) {
    return new EmployeeService(additionalParameter, departmentService);
  }
}

Cette dernière solution est sans doute celle qui répond le mieux à tes critères mais qui personnellement me semble la moins "Spring-friendly".

+0 -0

Oui en fait j’ai été induit en erreur par le fait que je me situais dans une classe de test, où je mocke les dépendances et où je ne demande pas à Spring de les injectés (d’où le fait que je souhaitais instancier moi-même).

Dans le tunnel d’exécution hors-tests, en effet, Spring gère tout de A à Z. Et ma question est alors un non-sens.

Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte