¿Qué hace el framework Spring? ¿Debo usarlo? ¿Por qué o por qué no?

229

Por lo tanto, estoy comenzando un nuevo proyecto en Java y estoy considerando usar Spring. ¿Por qué estoy considerando la primavera? ¡Porque mucha gente me dice que debería usar la primavera! En serio, siempre que trato de que la gente explique qué es exactamente Spring o qué hace, nunca pueden darme una respuesta directa. He revisado las intros en el sitio de SpringSource, y son muy complicadas o muy centradas en los tutoriales, y ninguna de ellas me da una buena idea de por qué debería usarla o de cómo facilitará mi vida. A veces la gente habla del término "inyección de dependencia", lo que me confunde aún más, porque creo que tengo una comprensión diferente de lo que significa ese término.

De todos modos, aquí hay un poco sobre mi historial y mi aplicación:

Estuve desarrollando en Java por un tiempo, haciendo desarrollo web de back-end. Sí, hago un montón de pruebas unitarias. Para facilitar esto, normalmente hago (al menos) dos versiones de un método: una que usa variables de instancia y otra que solo usa variables que se pasan al método. El que usa variables de instancia llama a la otra, suministrando las variables de instancia. Cuando llega el momento de la prueba de unidad, uso Mockito para simular los objetos y luego hacer llamadas al método que no usa variables de instancia. Esto es lo que siempre he entendido que es la "inyección de dependencia".

Mi aplicación es bastante simple, desde una perspectiva CS. Proyecto pequeño, 1-2 desarrolladores para empezar. Principalmente operaciones de tipo CRUD con un montón de búsquedas. Básicamente, un grupo de servicios web RESTful, más un front-end web y, finalmente, algunos clientes móviles. Estoy pensando en hacer el front-end en HTML / CSS / JS / JQuery directo, por lo que no hay planes reales para usar JSP. Utilizando Hibernate como ORM y Jersey para implementar los servicios web.

Ya empecé a programar, y estoy muy ansioso por obtener una demostración que puedo comparar y ver si alguien quiere invertir. Así que obviamente el tiempo es de la esencia. Entiendo que Spring tiene una gran curva de aprendizaje, además parece que necesita una gran cantidad de configuraciones XML, que normalmente trato de evitar como la plaga. Pero si puede hacer que mi vida sea más fácil y (especialmente) si hacerlo puede hacer que el desarrollo y las pruebas sean más rápidos, estoy dispuesto a morder la bala y aprender la primavera.

Así que por favor. Educame ¿Debo usar la primavera? ¿Por qué o por qué no?

    
pregunta sangfroid 12.07.2011 - 20:54

7 respuestas

104
  

¿Qué hace el framework Spring? ¿Debo usarlo? ¿Por qué o por qué no?

Spring es un marco que te ayuda a "conectar" diferentes componentes. Es más útil en los casos en los que tiene muchos componentes y puede decidir combinarlos de diferentes maneras, o si desea facilitar el intercambio de un componente por otro, dependiendo de las diferentes configuraciones o entornos.

  

Esto es lo que siempre entendí como "inyección de dependencia".

Sugeriría una definición diferente:

"Diseñe sus objetos para que dependan de una fuerza externa que les proporcione lo que necesitan, con la expectativa de que estas dependencias siempre sean inyectadas antes de que alguien les pregunte para comenzar a hacer su trabajo habitual ".

Compare eso con: "Cada objeto es responsable de salir y encontrar todo y a todos los que necesita cuando se inicia".

  

parece que necesita un montón de configuración XML

Bueno, la mayoría de las cosas de XML (o basadas en anotaciones) están diciendo cosas de Spring como:

  • Cuando alguien pregunta por "HammerStore", quiero que crees una instancia de example.HammerStore y la devuelvas. Almacene en caché la instancia para la próxima vez, ya que solo tiene que haber una tienda.
  • Cuando alguien pregunta por "SomeHammer", quiero que te preguntes por un "HammerStore" y devuelvas el resultado del método makeHammer() de la tienda. No no almacene en caché este resultado.
  • Cuando alguien pregunte por "SomeWrench", quiero que cree una instancia de example.WrenchImpl , use la configuración gaugeAmount y colóquela en la propiedad setWrenchSize() de la instancia. No cachee el resultado.
  • Cuando alguien pide "LocalPlumber", quiero que crees una instancia de example.PlumberImpl . Coloque la cadena "Pedro" en su método setName() , ponga un "SomeHammer" en su método setHammer() , y ponga una "SomeWrench" en su método setWrench() . Devuelva el resultado y guárdelo en caché para más adelante ya que solo necesitamos un plomero.

De esta manera, Spring le permite a sus componentes de conexión, etiquetarlos, controlar sus ciclos de vida / almacenamiento en caché y alterar el comportamiento según la configuración.

  

Para facilitar [las pruebas] Normalmente hago (al menos) dos versiones de un método: una que usa variables de instancia y una que solo usa variables que se pasan al método.

Eso suena como una gran cantidad de gastos generales por no ser un gran beneficio para mí. En su lugar, haga que sus variables de instancia tengan protected o visibilidad del paquete , y localice la unidad pruebas dentro del mismo paquete com.mycompany.whatever . De esa manera, puede inspeccionar y cambiar las variables de instancia cuando lo desee durante las pruebas.

    
respondido por el Darien 13.07.2011 - 21:40
64

Primero, ¿qué es la inyección de dependencia?

Simple. Tiene una clase, tiene un campo privado (establecido en nulo) y declara un configurador público que proporciona el valor para ese campo. En otras palabras, la dependencia de la clase (el campo) está siendo inyectada por una clase externa (a través del configurador). Eso es. Nada mágico.

Segundo, Spring puede usarse sin XML (o muy poco)

Si se sumerge con Spring 3.0.5.GA o superior, puede usar el soporte de inyección de dependencia de JDK6 +. Esto significa que puedes cablear dependencias usando las anotaciones @Component y @Resource .

¿Por qué usar Spring en absoluto?

Obviamente, la inyección de dependencia promueve pruebas de unidad muy fáciles ya que todas sus clases tienen configuradores para las dependencias importantes y se pueden burlar fácilmente usando su marco de burla favorito para proporcionar el comportamiento requerido.

Dejando de lado, Spring también proporciona muchas plantillas que actúan como clases base para facilitar el uso de las tecnologías estándar JEE. Por ejemplo, JdbcTemplate funciona bien con JDBC, JpaTemplate hace cosas buenas con JPA, JmsTemplate hace que JMS sea bastante sencillo. El RestTemplate es simplemente impresionante en su simplicidad. Por ejemplo:

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

y ya está. Los parámetros se inyectan y solo debe proporcionar anotaciones JAXB para MyJaxbObject. Eso no debería tomar ningún tiempo si los ha generado automáticamente desde un XSD utilizando el complemento Maven JAXB. Tenga en cuenta que no había ningún casting allí, ni tampoco era necesario declarar a un comisario. Todo está hecho para ti.

Podría escabullirme por siempre sobre las maravillas de Spring, pero quizás lo mejor que puede hacer es probar un pico de código simple en el que intente conectar un servicio web RESTful para bombear datos de un DAO inyectado que admita transacciones.

    
respondido por el Gary Rowe 12.07.2011 - 22:40
28

En primer lugar, su comprensión de la inyección de dependencia no es fundamentalmente errónea, sino que es muy diferente de lo que la mayoría de la gente quiere decir cuando usa el término. Lo que describe es una forma bastante extraña y poco convencional de lograr la capacidad de prueba. Le aconsejo que se aleje de eso, ya que otros desarrolladores se sentirán bastante confundidos por ese tipo de código.

La inyección de dependencia como se entiende generalmente (e implementada por Spring) significa que las dependencias que tiene una clase (por ejemplo, una fuente de datos JDBC) no son recuperadas por la clase en sí, sino que son "inyectadas" por un contenedor cuando se crea la instancia. Por lo tanto, no tiene dos versiones de todos los métodos que utilizan el origen de datos; en su lugar, tiene una configuración de inyección de dependencia donde se inyecta el origen de datos "real" y otra donde se inyecta un simulacro. O, si la inyección se realiza a través del constructor o un captador, el código de prueba puede hacer la inyección explícitamente.

En segundo lugar, Spring no es solo una inyección de dependencia, aunque esa es su funcionalidad principal. También proporciona transacciones declarativas, programación de trabajos, autenticación y un montón de otras funcionalidades (incluido un marco web MVC completo) que puede necesitar. Hay otros marcos que proporcionan la misma funcionalidad, pero aparte de Spring, solo Java EE los tiene todos integrados.

    
respondido por el Michael Borgwardt 12.07.2011 - 23:34
19

¿Por qué quiere usar Spring? Puede leerlo en enlace

En resumen:

  • Las aplicaciones J2EE tienden a contener cantidades excesivas de "tuberías" código. Muchas revisiones de código revelan repetidamente una alta proporción de código que no hace nada: código de búsqueda JNDI, objetos de transferencia, Bloques try / catch para adquirir y liberar recursos JDBC. . . . Escritura y el mantenimiento de dicho código de plomería demuestra un gran drenaje de recursos eso debería centrarse en el dominio empresarial de la aplicación.

  • Muchas aplicaciones J2EE utilizan un modelo de objeto distribuido donde esto es inapropiado. Esta es una de las principales causas de código excesivo y duplicación de código También es conceptualmente incorrecto en muchos casos; Las aplicaciones distribuidas internamente son más complejas que co-ubicadas Aplicaciones, y muchas veces con mucho menos rendimiento. Claro que si tu Los requisitos del negocio dictan una arquitectura distribuida, usted necesita implementar una arquitectura distribuida y aceptar la compensación que incurre en (y Spring ofrece características para ayudar en tales escenarios). Pero no debe hacerlo sin una razón convincente.

  • El modelo de componente EJB es demasiado complejo. EJB fue concebido como una manera de reducir la complejidad al implementar la lógica de negocios en J2EE aplicaciones; no ha tenido éxito en la práctica en este objetivo.

  • EJB se usa en exceso. EJB fue esencialmente diseñado para internamente Distribuido, aplicaciones transaccionales. Mientras que casi todos los no triviales Las aplicaciones son transaccionales, la distribución no debe estar integrada en el modelo de componente básico.

  • Muchos "patrones de diseño J2EE" no son, de hecho, patrones de diseño, sino Soluciones para limitaciones tecnológicas. Uso excesivo de la distribución, y El uso de API complejas como EJB ha generado muchos cuestionamientos. patrones de diseño; Es importante examinar esto críticamente y mirar para enfoques más simples y productivos.

  • Las aplicaciones J2EE son difíciles de probar por unidad. Las API de J2EE, y En especial, el modelo de componente EJB, se definió antes que el ágil. el movimiento despegó Así, su diseño no tiene en cuenta la facilidad. de pruebas unitarias. A través de ambas APIs y contratos implícitos, es Sorprendentemente difícil de probar aplicaciones basadas en EJB y muchos otras API de J2EE fuera de un servidor de aplicaciones. Sin embargo, la prueba de unidad Fuera de un servidor de aplicaciones es esencial para lograr una alta prueba. cobertura y para reproducir muchos escenarios de fallas, como la pérdida de Conectividad a una base de datos. También es vital para asegurar que las pruebas Se puede ejecutar rápidamente durante el proceso de desarrollo o mantenimiento, minimizando el tiempo improductivo en espera de la redistribución.

  • Ciertas tecnologías J2EE simplemente han fallado. El principal delincuente aquí Es una entidad de habas, que han demostrado ser poco desastrosas para productividad y en sus limitaciones en la orientación a objetos.

respondido por el Rudy 15.07.2011 - 13:02
12

Antes, escribíamos aplicaciones y servicios web simples, eficientes y rápidos utilizando solo Core Java, Servlets y JSP, html y xml, API de JDBC. Fue lo suficientemente bueno; JUnit era una buena herramienta para probar. Descansamos que nuestro código funcionó.

Hibernate vino para simplificar SQL y habilitar la asignación real de tablas de base de datos con objetos Java, permitiendo que las relaciones jerárquicas se reflejen en la asignación de relaciones de objetos u ORM como lo llamamos. Me encantó. Especialmente que no tuvimos que volver a asignar el ResultSet a un objeto Java o tipo de datos.

Struts apareció para agregar el patrón de Model View Controller a nuestras aplicaciones web, fue bueno.

Los EJB eran una sobrecarga enorme, y el dolor y las anotaciones hacían que el código pareciera un rasguño de gallina y ahora nos ha llegado la primavera a gente inocente. Simplemente me parece una exageración.

Por ejemplo, ahora empaquetamos nuestra url jdbc simple, usuario, pasamos primero a jdbc.properties, luego a las propiedades de hibernación, y luego a Spring Beans por tercera vez.

En comparación con todo eso, considere que obtener una conexión donde la necesite es realmente tan simple como se muestra a continuación en java puro, que es lo que realmente estamos haciendo después de pasar por todo ese asunto de aire caliente con Spring:

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

Eso es en sí mismo autoexplicativo, se trata de una gran ronda y se envuelve una y otra vez para hacer algo simple de forma rápida y fácil sin ningún otro gran beneficio. Es como envolver toneladas y toneladas de papel de regalo alrededor de un pequeño y bonito regalo, que es todo lo que realmente conservas de todos modos.

Otro ejemplo es una actualización por lotes. Con Spring, es complicada e involucra bastantes clases, interfaces antes de poder usar JdbcTemplate para hacer una actualización por lotes. Con plain jdbc es simplemente:

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

No puede ser más simple o más rápido que eso.

No apoyo este marco. Lo siento. ¿Quién en el mundo quiere inyecciones cada vez que necesitan algo?

    
respondido por el Uma 15.06.2012 - 11:04
12
  

¿Qué hace el framework Spring?

La primavera es como hoy no solo lo que se conoció como un marco simple, es un ecosistema completo.

Temas cubiertos por el ecosistema de primavera:

  • Spring Framework (por ejemplo, inyección de dependencia, AOP ...)

  • Spring Cloud

  • Datos de primavera

  • Spring Security

  • Spring Batch

  • Spring Social

Consulte aquí para obtener una cobertura completa del ecosistema. Es posible seleccionar proyectos, de modo que pueda usar Google Guice para DI y, por ejemplo, Seguridad de primavera para manejar cosas relacionadas con la seguridad. No tienes que comprar todo el ecosistema.

El propio marco de Spring cubre hoy principalmente

  • Inyección de dependencia

  • Programación orientada a aspectos, incluida la gestión declarativa de transacciones de Spring

  • Aplicación web Spring MVC y marco de servicios web RESTful

  • Soporte fundamental para JDBC, JPA, JMS

Fuente spring.io

En general, se podría decir que Spring es una colección de Patrones y Prácticas implementados en código, lo que podría ayudar a mejorar o acelerar su ciclo de desarrollo de aplicaciones.

Por lo que es más conocido (el marco central) es por sus capacidades en el campo de inyección de dependencia . Spring sí tiene, lo que se llama Inversión del contenedor de control o corto Contenedor IoC o incluso más corto el contenedor (para el que a veces se usa" spring ").

¿Qué es la inyección de dependencia?

La inyección de dependencia significa que su objeto recibe todas las dependencias de otros objetos a través de un mecanismo externo.

Digamos que tienes un automóvil, la forma típica en que se implementa es:

public class Car {

    Engine e;

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

}

El objeto de coche depende de un motor. Dado que el motor se implementa como un miembro de automóvil, no se puede cambiar por ejemplo, por ejemplo. Un motor de prueba.

Ahora inyección de dependencia entra en juego:

public class Car {

    Engine e;

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

}

Después de eso, puedes cambiar los motores. Lo que ves arriba se llama inyección de constructor . Hay otros tipos como por ejemplo setter -injection o method -injection. ¿Cómo te ayuda Spring con esto? Spring le permite marcar los componentes a inyectar con la anotación @Autowired y realiza el cableado del objeto inyectado de forma automática; es probable que el componente que desea inyectar tenga dependencias. Los inyectables, por así decirlo, están marcados mediante @Component

public class Car {

    Engine e;

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

}

Pero esa es solo una de las muchas características que Spring tiene para ofrecer.

  

¿Debo usar Spring? ¿Por qué o por qué no?

Dado que Spring no es muy intrusivo y ofrece muchas ayudas, debe considerar el uso de Spring. Especialmente para nuevos proyectos, Spring Boot es muy atractivo. start.spring.io ofrece un point'n'click fácil de usar para generar una plantilla de proyecto Para empezar. Incluso es posible usar curl para recuperar una plantilla:

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  |
+-----------------+-----------------------------------------+

...

Por otro lado, marcos como spark o dropwizard ofrece un buen punto de partida para la creación rápida de aplicaciones web.

    
respondido por el Thomas Junk 15.06.2015 - 13:35
4

Es un marco escrito en Java con muchas cosas incluidas para que su aplicación web sea funcional (por ejemplo, soporte para la internacionalización). También proporciona una buena manera de estructurar su aplicación en capas. Úsalo, te ahorrará mucho tiempo a largo plazo.

Un buen libro para aprender sobre Spring es: Expert Spring MVC and Web Flow

    
respondido por el Bernard 12.07.2011 - 21:13

Lea otras preguntas en las etiquetas