uso tutorial programación programa para mediante libro interfaces graficas framework español desarrollo crear book aplicaciones java spring maven

java - tutorial - maven-módulos separados para interfaces e implementación con Spring



spring framework pdf español (6)

Estamos trabajando en Mavenizar nuestro proyecto Java y nos gustaría configurar una separación limpia entre las interfaces y las implementaciones para cada módulo. Para hacerlo, queremos dividir cada módulo en dos submódulos uno para interfaces y objetos de datos utilizados por ellos y otro para implementaciones. Por ejemplo:

+commons +commons-api +commons-impl

Los POM de los módulos se configurarán de forma que ningún módulo dependa de los submódulos impl. De esta forma, ningún código de un módulo podrá "ver" los detalles de implementación de otro módulo.

Lo que estamos teniendo problemas, es dónde poner nuestros XML de primavera. En nuestro proyecto, importamos automáticamente archivos XML de primavera utilizando importación de comodines, como

<import resource="classpath*:**/*-beans.xml"/>

De esta manera, la ubicación de Spring XMLs realmente no importa en el tiempo de ejecución, ya que todos los módulos se cargan en el mismo cargador de clases y las estrictas reglas de dependencia en los POM no se aplican.

Sin embargo, durante el desarrollo queremos que el IDE (utilizamos Intellij IDEA) reconozca las clases de implementación a las que se hace referencia desde los XML de Spring. También queremos que IDEA reconozca los granos definidos en otros módulos.

Si ponemos los XML de primavera en los submódulos API, no "verán" las clases de implementación en los submódulos impl. Si los colocamos en los submódulos impl, sus beans no serán "vistos" desde otros módulos. Probablemente sea posible configurar el proyecto IDEA para reconocer XML de primavera de módulos en los que no existe dependencia, pero preferimos que nuestros POM contengan toda la información de la estructura del proyecto y no dependan de los archivos del proyecto IDEA.

Consideramos crear un tercer submódulo solo para contener Spring XML (y quizás también hibernar xmls). Por ejemplo:

+commons +commons-api +commons-impl +commons-config

Los módulos externos dependerán tanto de commons-api como de commons-config y commons-config dependerán tanto de commons-api como de common-impl , con la dependencia de commons-impl marcada como "provided" (para evitar la resolución transitiva).

Sin embargo, esto parece una solución compleja e incómoda y creemos que debe haber una forma mejor y más simple de lograr la separación interfaz / impl con Maven y Spring.


En resumen, ¿quiere Idea para anular el gráfico de dependencia de maven, pero evite mantener esta configuración en los archivos de proyectos de ideas?

Una opción es agrupar las dependencias de implementación en un perfil de experto. Este perfil no estaría habilitado por defecto, pero debería poder marcarlo como activo bajo la idea.


Dos ideas vienen a la mente:

  1. Tendrás uno (o más) módulos donde todos los módulos (api + impl) son dependencias, podrías colocar tus archivos de configuración de primavera allí.
  2. Coloque los archivos de configuración de resorte en los módulos api y declare una dependencia en el módulo impl con alcance provided esta manera se conocerán las implementaciones, mientras que no hay dependencia de la API para la implementación.

Lo que necesita es un alcance de dependencia de tiempo de ejecución:

tiempo de ejecución : este ámbito indica que la dependencia no es necesaria para la compilación, pero es para la ejecución. Está en los classpaths de tiempo de ejecución y de prueba, pero no en el classpath de compilación.

( https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html )

Defina una dependencia de tiempo de ejecución de un módulo impl a otro módulo impl donde use las clases impl en la configuración * -beans.xml. Intellij reconocerá correctamente esto en los archivos de configuración de primavera, pero no los completará automáticamente en el código (pero lo hará en el código de prueba).

Además, si alguien usó las clases en el código, la compilación a través de maven fallaría, porque la dependencia del tiempo de ejecución no está en una ruta de clase de compilación.


  • commons-impl en el ámbito de tiempo de ejecución en módulos externos

    1. bienes comunes (pom dependencyManagement) =>

      + commons-api (compilar)

      + commons-impl (compilar)

      + commons-config (compilar)

    2. commons-impl (dependencias pom) =>

      + commons-api (compilar)

      + commons-config (compilar)

    3. módulos externos (dependencias pom) =>

      + commons-impl ( tiempo de ejecución )

      + commons-api (compilar)

      + commons-config (compilar)


Puedes lograr el desacoplamiento de api e impl como este:

+ commons (pom) + pom.xml <--- serves as a parent aggregator (see below) + commons-api (jar) <--- contains models, interfaces and abstract classes only + commons-impl (jar) <--- depends on commons-api + commons-config (jar) <--- depends on commons-impl only (no need to depend on commons-api as it is brought in transitively) + external-project (war or jar) <--- has commons-config as a dependency

Parent aggregator pom (especificar el orden de compilación):

<modules> <module>commons-api</module> <module>commons-impl</module> <module>commons-config</module> </modules>

El módulo de configuración puede omitirse si solo contiene la configuración del contexto de la aplicación de primavera. El xml de configuración de la aplicación debe estar en la estructura de ruta de clases y carpetas del módulo que contiene el artefacto que está implementando. Entonces, si estás construyendo un artefacto de guerra, el contexto de la aplicación debería estar allí.

La única configuración que debería estar en su módulo de commons estaría en un paquete de prueba de su módulo de impl.


  1. mantenga el número de módulos lo menos posible;

    Esto acelera el tiempo de construcción del proyecto y simplifica su diseño.

  2. mantenga la estructura de los módulos tan simple como sea posible: raíz simple + todos los submódulos en la misma carpeta, por ejemplo:

    pom.xml commons-api/ commons-runtime/ module-a-api/ module-a-runtime/ ...

Esto simplifica la navegación en todo el proyecto, cuando el número de módulos es realmente alto (> 50)

  1. proporcionar dependencias con ámbito de tiempo de ejecución a los módulos de tiempo de ejecución solo cuando sean necesarios;

    Esto mantiene su arquitectura clara. Utilice burlas en lugar de dependencia explícita a otro módulo de tiempo de ejecución.

  2. mantén tus contextos de api spring en los módulos api, define tus beans públicos como abstract bean + interface;

  3. mantenga sus contextos de implementación en módulos de tiempo de ejecución, anule los API con sus implementaciones a través de perfiles de primavera (use <beans profile = "default").

Resultado: diseño y diseño simple y transparente; soporte ide completo; no hay dependencias explícitas en las partes internas del módulo de tiempo de ejecución.