Selección del marco de inyección de dependencia de Java

Estoy buscando ayuda para decidir qué marco de inyección de dependencia se adapta mejor a nuestras necesidades y si este es o no el camino a seguir en primer lugar.

Configuración:

Estoy trabajando con una base de código de ~300k líneas de código. Tenemos una serie de clientes "principales", así como un gran cliente adicional. Este último requería una versión individual de nuestro software que luego proporcionamos.

Desde entonces apareció la perspectiva de cooperar con otros socios. En el futuro, algunos de ellos pueden requerir versiones de software individualizadas; esto puede variar desde el mero diseño de la interfaz de usuario hasta la exclusión de grandes secciones de funcionalidad.

Por lo tanto, nuestro objetivo actual es modularizar nuestra base de código, preferiblemente utilizando la inyección de dependencia (DI).

El código base está escrito en Java, sin embargo, usamos JNI e implementamos una gran parte de la funcionalidad en C++. Esto debe tenerse en cuenta al decidir la idoneidad del marco.

Actualmente nuestro principal objetivo es modularizar las líneas de productos, es decir, grandes secciones de nuestra base de código. En la práctica, sin embargo, es muy probable que también haya modularización de características medianas a pequeñas.

Investigación

Por el momento, se prefiere una solución DI, aunque esto no es un requisito. Los marcos que estoy investigando son principalmente:

  • Daga 2
  • Guisa
  • Resorte DI

Además de estas, hay más soluciones que se consideran al menos brevemente:

  • koin
  • Java EE6 CDI
  • Palillo de dientes

Aspectos que estamos considerando:

  • Capacidad de modularización
  • Esfuerzo para utilizar el marco en una base de código grande
  • Rendimiento, especialmente uso de memoria wrt
  • Ofuscación de código (no es la máxima prioridad, sin embargo, surgieron algunas sospechas, si uno de nuestros clientes intentó descompilar nuestro código, por lo tanto, también tendremos que considerar esto)

Daga 2

Hasta ahora este parece ser el favorito. El marco evita la reflexión, lo que se desea, especialmente en el uso de la memoria, ya que es una limitación de recursos para nuestros clientes.

La depuración de Dagger 2 parece más fácil que con Spring y Guise, debido a la trazabilidad adecuada y su enfoque en nombres de clases legibles por humanos.

Por último, pero no menos importante, parece haber una forma de ofuscar el código usando ProGuard. También se minimiza el repetitivo.

Sin embargo, estoy considerando la curva de aprendizaje de Dagger 2, ya que algunos afirman que puede tener un alto grado de complejidad. Además, parece @Overrideque Dagger 2 no es compatible, lo que hace que sea necesario refactorizar más, ya que dichas clases deberán dividirse en módulos si se van a inyectar.

También es un problema encontrar errores solo en el tiempo de ejecución si algo sale mal con la inyección. Esto tiene el potencial de que los clientes se encuentren con errores de tiempo de ejecución que han pasado desapercibidos en la preparación.

Guisa

Al igual que Spring DI, Guise ya tiene una gran comunidad, algo que Dagger 2 aún puede carecer, por lo que encontrar respuestas a las preguntas puede ser más fácil. Una gran ventaja de Spring DI es la conexión de clases mediante información de tipos.

Sin embargo, al igual que Spring DI, Guise usa la reflexión, por lo tanto, en cuanto al rendimiento, no es tan bueno. Para consideraciones relacionadas con la memoria, esto es un menos.

Los desarrolladores de Dagger 2 afirman haberse centrado en una mejor capacidad de depuración, también afirman que con Guise, es posible que algunos puntos de interrupción ni siquiera se entiendan en la ejecución. Por lo tanto, algunas aplicaciones que utilizan Guise pueden no ser adecuadas para fines de depuración.

Resorte DI

Este parece ser el veterano entre los marcos. Hay una comunidad gigante detrás de Spring, por lo que es probable que todo esté bien documentado y las respuestas se puedan encontrar fácilmente en línea. Sin embargo, la comunidad de Spring parece estar bastante inactiva, lo que significa que si bien hay muchas respuestas disponibles en línea, es difícil encontrar nuevas.

Framework usa XML, aunque leí que también existe la opción de usar anotaciones. Ambos casos son reflejo, por lo tanto, nuevamente no son óptimos cuando se considera el uso de RAM.

La funcionalidad como F3 de Eclipse no está disponible cuando se trata de dependencias inyectadas. Hay Spring IDE, sin embargo, esto no se considera una opción en absoluto.

Spring DI viene con una gran cantidad de código repetitivo, algo que llama la atención con nuestra base de código de 300 000 líneas.

Preguntas

Principalmente, me gustaría escuchar su opinión sobre estos marcos, ya sea que recomiende o no uno y si considera que alguno de ellos es adecuado para la tarea que describí. Estas cosas me interesan especialmente:

  • ¿Son estos marcos adecuados para la modularización que pretendemos lograr?
  • ¿La diferencia de rendimiento es tan notable como parece?
  • ¿Hay algún factor importante que deba considerar al decidir sobre un marco que aún no se ha mencionado? Tal vez algunos de ustedes vean dificultades típicas al tratar con DI que son evidentes para ustedes con respecto a nuestra configuración que no son evidentes para mí en este momento.
  • ¿Spring DI o Guise ofrecen ofuscación de código? ¿Y ProGuard es tan fácil de incluir como se afirma?
  • ¿Deberían considerarse seriamente otros marcos dado el código base como se describe?

En general, agradezco cualquier información sobre este tema, ya que no soy un experto en DI. Si ve alguna señal de alerta en esta descripción, especialmente razones evidentes por las que cualquiera de los marcos disponibles no es una buena opción en nuestro caso, entonces esta es información valiosa.

Gracias.

Respuestas (1)

También debe incluir hk2 ( https://javaee.github.io/hk2/ ) en consideración. Es la base de los servidores GlassFish y WebLogic y también es el proveedor DI de primera elección para Jersey. A diferencia de los demás, fue diseñado para ser dinámico y fácil de introducir en las bases de código existentes (que era exactamente lo que se hacía en WebLogic).

En WebLogic, se usó para desenredar un gran montón desagradable de código espagueti al permitir la introducción de código basado en servicios. hk2 ahora es propiedad de Eclipse ( https://github.com/eclipse-ee4j/glassfish-hk2 ) y todavía se está desarrollando activamente (¡le hice un cambio el martes!)

¡Espero que esto ayude!

Gracias por la recomendación. Diré, sin embargo, que la última pregunta de SO sobre el tema (hk2) tiene casi un mes y no hay mucha actividad a la vista. Una comunidad pequeña siempre es mala en términos de documentación y resolución de problemas. Evaluamos los marcos que mencioné y tendemos a usar Dagger 2, a partir de ahora.