web-dev-qa-db-fra.com

Que fait le framework Spring? Dois-je l'utiliser? Pourquoi ou pourquoi pas?

Donc, je commence un tout nouveau projet en Java et j'envisage d'utiliser Spring. Pourquoi est-ce que j'envisage le printemps? Parce que beaucoup de gens me disent que je devrais utiliser Spring! Sérieusement, chaque fois que j'ai essayé d'amener les gens à expliquer ce qu'est exactement le printemps ou ce qu'il fait, ils ne peuvent jamais me donner une réponse directe. J'ai vérifié les intros sur le site SpringSource, et elles sont soit vraiment compliquées soit vraiment axées sur les didacticiels, et aucune d'entre elles ne me donne une bonne idée de la raison pour laquelle je devrais l'utiliser ou comment cela me facilitera la vie. Parfois, les gens jettent le terme "injection de dépendance", ce qui me rend encore plus confus, car je pense que j'ai une compréhension différente de ce que signifie ce terme.

Quoi qu'il en soit, voici un peu mon parcours et mon application:

Développé en Java pendant un certain temps, faisant du développement web back-end. Oui, je fais une tonne de tests unitaires. Pour faciliter cela, je fais généralement (au moins) deux versions d'une méthode : une qui utilise des variables d'instance et une qui n'utilise que des variables transmises à la méthode. Celle qui utilise des variables d'instance appelle l'autre, en fournissant les variables d'instance. Quand vient le temps du test unitaire, j'utilise Mockito pour simuler les objets et ensuite appeler la méthode qui n'utilise pas de variables d'instance. C'est ce que j'ai toujours compris être "l'injection de dépendance".

Mon application est assez simple, du point de vue CS. Petit projet, 1-2 développeurs pour commencer. Surtout des opérations de type CRUD avec un tas de recherche. Fondamentalement, un tas de services Web RESTful, plus un serveur Web frontal, puis finalement quelques clients mobiles. Je pense à faire le front-end en HTML/CSS/JS/JQuery, donc pas de vrais plans pour utiliser JSP. Utiliser Hibernate comme ORM et Jersey pour implémenter les services Web.

J'ai déjà commencé à coder, et je suis vraiment impatient de sortir une démo que je peux comparer et voir si quelqu'un veut investir. Il est donc évident que le temps presse. Je comprends que Spring a toute la courbe d'apprentissage, et il semble qu'il nécessite tout un tas de configuration XML, que j'essaie généralement d'éviter comme la peste. Mais si cela peut me faciliter la vie et (surtout) si cela peut accélérer le développement et les tests, je suis prêt à mordre la balle et à apprendre le printemps.

Donc s'il vous plait. Éduquez-moi. Dois-je utiliser Spring? Pourquoi ou pourquoi pas?

245
sangfroid

Que fait le framework Spring? Dois-je l'utiliser? Pourquoi ou pourquoi pas?

Spring est un cadre qui vous aide à "câbler" différents composants ensemble. Il est très utile dans les cas où vous avez beaucoup de composants et que vous pouvez décider de les combiner de différentes manières, ou souhaitez faciliter l'échange d'un composant pour un autre en fonction de différents paramètres ou environnements.

C'est ce que j'ai toujours compris être "l'injection de dépendance".

Je proposerais une définition différente:

"Concevez vos objets de manière à ce qu'ils s'appuient sur une force extérieure pour leur fournir ce dont ils ont besoin, dans l'attente que ces dépendances soient toujours injecté avant que quiconque ne leur demande de commencer à faire leur travail habituel. "

Comparez cela avec: "Chaque objet est responsable de sortir et de trouver tout et tout le monde dont il a besoin au démarrage."

il semble que cela nécessite tout un tas de configuration XML

Eh bien, la plupart des trucs XML (ou basés sur des annotations) racontent des trucs Spring comme:

  • Lorsque quelqu'un demande "HammerStore", je veux que vous créiez une instance de example.HammerStore Et que vous la renvoyiez. Mettez l'instance en cache pour la prochaine fois, car il ne doit y avoir qu'un seul magasin.
  • Quand quelqu'un demande "SomeHammer", je veux que vous vous demandiez un "HammerStore" et renvoyez le résultat de la méthode makeHammer() du magasin. Ne pas mettre en cache ce résultat.
  • Lorsque quelqu'un demande "SomeWrench", je veux que vous créiez une instance de example.WrenchImpl, Utilisez le paramètre de configuration gaugeAmount et placez-le dans la propriété setWrenchSize() de l'instance. Ne cachez pas le résultat.
  • Quand quelqu'un demande "LocalPlumber", je veux que vous créiez une instance de example.PlumberImpl. Mettez la chaîne "Pedro" dans sa méthode setName(), mettez un "SomeHammer" dans sa méthode setHammer() et mettez un "SomeWrench" dans sa méthode setWrench(). Renvoyez le résultat et mettez le résultat en cache pour plus tard, car nous n'avons besoin que d'un plombier.

De cette façon, Spring permet à vos composants de se connecter, de les étiqueter, de contrôler leur cycle de vie/mise en cache et de modifier leur comportement en fonction de la configuration.

Pour faciliter [les tests], je crée généralement (au moins) deux versions d'une méthode: une qui utilise des variables d'instance et une qui n'utilise que des variables transmises à la méthode.

Cela ressemble à beaucoup de frais généraux pour pas beaucoup d'avantages pour moi. Au lieu de cela, assurez-vous que vos variables d'instance ont protected ou visibilité du package , et recherchez les tests unitaires dans le même package com.mycompany.whatever. De cette façon, vous pouvez inspecter et modifier les variables d'instance à tout moment pendant les tests.

113
Darien

D'abord, qu'est-ce que l'injection de dépendance?

Facile. Vous avez une classe, elle a un champ privé (défini sur null) et vous déclarez un setter public qui fournit la valeur de ce champ. En d'autres termes, la dépendance de la classe (le champ) est injectée par une classe externe (via le setter). C'est ça. Rien de magique.

Deuxièmement, Spring peut être utilisé sans XML (ou très peu)

Si vous plongez avec Spring 3.0.5.GA ou supérieur, vous pouvez utiliser le support d'injection de dépendance de JDK6 +. Cela signifie que vous pouvez câbler les dépendances à l'aide de @Component et @Resource annotations.

Pourquoi utiliser Spring du tout?

De toute évidence, l'injection de dépendances favorise les tests unitaires très faciles car toutes vos classes ont des paramètres pour les dépendances importantes et ceux-ci peuvent être facilement moqués en utilisant votre cadre de simulation préféré pour fournir le comportement requis.

Cela mis à part, Spring fournit également de nombreux modèles qui agissent comme des classes de base pour que l'utilisation des technologies standard JEE soit un jeu d'enfant. Par exemple, le JdbcTemplate fonctionne bien avec JDBC, le JpaTemplate fait de bonnes choses avec JPA, JmsTemplate rend JMS assez simple. Le RestTemplate est tout simplement génial dans sa simplicité. Par exemple:

RestTemplate restTemplate = new RestTemplate();
MyJaxbObject o = restTemplate.getForObject("https://secure.example.org/results/{param1}?param2={param2}",MyJaxbObject.class,"1","2");

et tu as fini. Les paramètres sont injectés et il vous suffit de fournir des annotations JAXB pour MyJaxbObject. Cela ne devrait pas prendre de temps du tout si vous les avez générés automatiquement à partir d'un XSD à l'aide du plugin Maven JAXB. Notez qu'il n'y avait pas de casting en cours, ni de déclaration de marshaller. Tout est fait pour toi.

Je pourrais discuter indéfiniment des merveilles de Spring, mais peut-être que la meilleure chose à faire est d'essayer un simple pic de code où vous essayez de câbler un service Web RESTful pour pomper les données d'un DAO injecté qui prend en charge les transactions.

69
Gary Rowe

Tout d'abord, votre compréhension de l'injection de dépendance n'est pas fondamentalement fausse, mais très différente de ce que la plupart des gens veulent dire lorsqu'ils utilisent le terme. Ce que vous décrivez est un moyen plutôt étrange et non conventionnel d'atteindre la testabilité. Je vous conseille de vous en éloigner, car d'autres développeurs seront plutôt perplexes devant ce type de code.

L'injection de dépendances telle qu'elle est généralement comprise (et implémentée par Spring) signifie que les dépendances d'une classe (par exemple une source de données JDBC) ne sont pas récupérées par la classe elle-même, mais "injectées" par un conteneur lorsque l'instance est créée. Vous n'avez donc pas deux versions de chaque méthode qui utilise la source de données; à la place, vous avez une configuration d'injection de dépendance où la "vraie" source de données est injectée et une où une maquette est injectée. Ou, si l'injection se produit via le constructeur ou un getter, le code de test peut effectuer l'injection explicitement.

Deuxièmement, Spring n'est pas seulement une injection de dépendance, bien que ce soit sa fonctionnalité principale. Il fournit également des transactions déclaratives, la planification des travaux, l'authentification et un tas d'autres fonctionnalités (y compris une infrastructure Web MVC à part entière) dont vous pourriez avoir besoin. Il existe d'autres frameworks qui fournissent la même fonctionnalité, mais à part Spring, seuls Java EE les a tous intégrés.

29
Michael Borgwardt

Pour savoir pourquoi voulez-vous utiliser Spring, vous pouvez le lire sur http://www.wrox.com/WileyCDA/Section/Why-Use-the-Spring-Framework-.id-130098.html =

En résumé :

  • Les applications J2EE contiennent généralement des quantités excessives de code de "plomberie". De nombreux examens de code révèlent à plusieurs reprises une proportion élevée de code qui ne fait rien: code de recherche JNDI, objets de transfert, blocs try/catch pour acquérir et libérer des ressources JDBC. . . . L'écriture et la maintenance d'un tel code de plomberie constituent un fardeau majeur sur les ressources qui devraient se concentrer sur le domaine d'activité de l'application.

  • De nombreuses applications J2EE utilisent un modèle d'objet distribué lorsque cela est inapproprié. C'est l'une des principales causes de code excessif et de duplication de code. C'est également conceptuellement faux dans de nombreux cas; Les applications distribuées en interne sont plus complexes que les applications colocalisées et souvent beaucoup moins performantes. Bien sûr, si les besoins de votre entreprise imposent une architecture distribuée, vous devez implémenter une architecture distribuée et accepter le compromis qui en découle (et Spring propose des fonctionnalités pour vous aider dans de tels scénarios). Mais vous ne devriez pas le faire sans raison impérieuse.

  • Le modèle de composant EJB est indûment complexe. EJB a été conçu comme un moyen de réduire la complexité lors de l'implémentation de la logique métier dans les applications J2EE; il n'a pas réussi à atteindre cet objectif dans la pratique.

  • EJB est surutilisé. EJB a été essentiellement conçu pour les applications transactionnelles distribuées en interne. Bien que presque toutes les applications non triviales soient transactionnelles, la distribution ne doit pas être intégrée au modèle de composant de base.

  • De nombreux "modèles de conception J2EE" ne sont pas, en fait, des modèles de conception, mais des solutions de contournement pour les limitations technologiques. La surutilisation de la distribution et l'utilisation d'API complexes telles que les EJB ont généré de nombreux modèles de conception douteux; il est important de les examiner d'un œil critique et de rechercher des approches plus simples et plus productives.

  • Les applications J2EE sont difficiles à tester unitairement. Les API J2EE, et en particulier le modèle de composant EJB, ont été définis avant le décollage du mouvement agile. Ainsi, leur conception ne prend pas en compte la facilité des tests unitaires. Grâce aux API et aux contrats implicites, il est étonnamment difficile de tester des applications basées sur EJB et de nombreuses autres API J2EE en dehors d'un serveur d'applications. Pourtant, les tests unitaires en dehors d'un serveur d'applications sont essentiels pour obtenir une couverture de test élevée et reproduire de nombreux scénarios de défaillance, tels que la perte de connectivité à une base de données. Il est également essentiel de garantir que les tests peuvent être exécutés rapidement pendant le processus de développement ou de maintenance, minimisant ainsi le temps improductif en attente de redéploiement.

  • Certaines technologies J2EE ont tout simplement échoué. Le principal délinquant ici est les beans entité, qui se sont révélés peu désastreux pour la productivité et dans leurs contraintes sur l'orientation des objets.

19
Rudy

Que fait le framework Spring?

Le printemps n'est pas seulement aujourd'hui, ce qui était connu comme un cadre simple, c'est un écosystème complet.

Sujets couverts par l'écosystème printanier:

  • Framework Spring (par exemple, injection de dépendance, AOP ...)

  • Nuage de printemps

  • Données de printemps

  • Sécurité du printemps

  • Lot de printemps

  • Spring Social

Voir ici pour une couverture complète de l'écosystème. Il est possible de sélectionner des projets, afin que vous puissiez utiliser Google Guice pour DI et par exemple Spring Security pour gérer les choses liées à la sécurité. Vous n'avez pas à acheter dans tout l'écosystème.

Le cadre Spring lui-même couvre aujourd'hui principalement

  • Injection de dépendance

  • Programmation orientée aspect, y compris la gestion déclarative des transactions de Spring

  • Application Web Spring MVC et infrastructure de service Web RESTful

  • Support de base pour JDBC, JPA, JMS

Source spring.io

En général, vous pourriez dire que Spring est une collection de modèles et de pratiques implémentés dans le code, ce qui pourrait aider à améliorer ou accélérer votre cycle de développement d'applications.

Pour ce qu'il (le core-framework) est le plus connu pour ses capacités dans le domaine de l'injection de dépendance . Le ressort lui-même a, ce qu'on appelle Inversion du conteneur de contrôle ou court IoC Container ou encore plus court le conteneur (pour lequel "ressort "est parfois utilisé également).

Qu'est-ce que l'injection de dépendance?

L'injection de dépendance signifie que votre objet reçoit chaque dépendance à d'autres objets via un mécanisme externalisé.

Disons, vous avez une voiture, la manière typique, elle est mise en œuvre est:

public class Car {

    Engine e;

    public Car() { 
        e = new Engine(); 
    }

}

L'objet de voiture dépend d'un moteur. Étant donné que le moteur est implémenté en tant que membre de la voiture, il ne peut pas être remplacé par exemple un moteur de test.

Maintenant injection de dépendance entre en jeu:

public class Car {

    Engine e;

    public Car(Engine e) { 
        this.e = e; 
    }

}

Après cela, vous pouvez changer de moteur. Ce que vous voyez ci-dessus s'appelle injection constructeur. Il existe d'autres types comme par exemple setter - injection ou méthode - injection. Comment Spring vous aide-t-il avec cela? Spring lui permet de marquer les composants à injecter avec l'annotation @Autowired et fait automatiquement le câblage de l'objet injecté - il est probable que le composant que vous souhaitez injecter ait lui-même des dépendances. Les injectables - pour ainsi dire - sont marqués via @Component

public class Car {

    Engine e;

    @Autowired
    public Car(Engine e) { 
        this.e = e; 
    }

}

Mais ce n'est qu'une des nombreuses fonctionnalités que Spring a à offrir.

Dois-je utiliser Spring? Pourquoi ou pourquoi pas?

Étant donné que le printemps n'est pas très intrusif et offre de nombreuses aides, vous devriez envisager d'utiliser le printemps. Surtout pour les nouveaux projets, Spring Boot est très attrayant. start.spring.io offre une interface facile à utiliser point'n'click - pour générer un modèle de projet pour commencer. Il est même possible d'utiliser curl pour récupérer un modèle:

curl start.spring.io

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/

:: Spring Initializr ::  https://start.spring.io

This service generates quickstart projects that can be easily customized.
Possible customizations include a project's dependencies, Java version, and
build system or build structure. See below for further details.

The services uses a HAL based hypermedia format to expose a set of resources
to interact with. If you access this root resource requesting application/json
as media type the response will contain the following links:
+-----------------+-----------------------------------------+
| Rel             | Description                             |
+-----------------+-----------------------------------------+
| gradle-build    | Generate a Gradle build file            |
| gradle-project  | Generate a Gradle based project archive |
| maven-build     | Generate a Maven pom.xml                |
| maven-project * | Generate a Maven based project archive  |
+-----------------+-----------------------------------------+

...

D'un autre côté, des frameworks comme spark ou dropwizard offrent également un bon point de départ pour la création rapide d'applications Web.

13
Thomas Junk

Auparavant, nous écrivions des applications et des services Web simples, efficaces et rapides en utilisant uniquement le noyau Java, les servlets et JSP, html et xml, l'API JDBC. C'était assez bon; JUnit était un bon outil pour tester. Nous nous sommes assurés que notre code fonctionnait.

Hibernate est venu pour simplifier SQL et permettre un véritable mappage des tables de base de données avec des objets Java, permettant aux relations hiérarchiques d'être reflétées dans le mappage des relations d'objets ou ORM comme nous l'appelons. J'ai adoré. Surtout que nous n'avons pas eu à mapper le ResultSet dans un Java.

Struts est venu ajouter le modèle Model View Controller à nos applications Web, c'était bien.

Les EJB étaient un énorme frais généraux et la douleur et les annotations faisaient ressembler le code à du poulet et maintenant le printemps a jailli sur nous, innocents. Cela me semble exagéré.

Par exemple, nous empaquetons maintenant notre simple URL jdbc, utilisateur, passons d'abord à jdbc.properties, puis dans les propriétés d'hibernation puis dans les haricots Spring pour la troisième fois!

Par rapport à tout cela, pensez à obtenir une connexion là où vous en avez besoin est vraiment aussi simple que ci-dessous en Java pur, ce que nous faisons vraiment après avoir traversé toutes ces choses avec Hot Spring avec Spring:

Connection connection = DriverManager.getConnection(url, user, pass);

En soi, cela va de soi que c'est un grand tour et un tour complet pour faire une chose simple rapidement et facilement sans autres gros avantages. C'est comme emballer des tonnes et des tonnes de papier cadeau autour d'un petit cadeau sympa qui est tout ce que vous gardez vraiment de toute façon.

Un autre exemple est une mise à jour par lots. Avec Spring, il est compliqué impliquant plusieurs classes, interfaces avant de pouvoir utiliser le JdbcTemplate pour effectuer une mise à jour par lots. Avec plain jdbc c'est simplement:

Statement statement = connection.createStatement();
statement.addBatch(sqlquery);
statement.executeBatch();

Ne peut pas être plus simple ou plus rapide que cela.

Je ne soutiens pas ce cadre. Désolé. Qui diable veut des injections chaque fois qu'ils ont besoin de quelque chose?

13
Uma

C'est un framework écrit en Java avec beaucoup de choses incluses pour rendre votre application web fonctionnelle (par exemple le support de l'internationalisation). Il fournit également un bon moyen de structurer votre application en couches. Utilisez-le, cela vous fera gagner beaucoup de temps à long terme.

Un bon livre pour en savoir plus sur Spring est: Expert Spring MVC et Web Flow

4
Bernard