Spring Framework in modular design by Apache Maven

Asked

Viewed 649 times

2

I created a modular web project using Apache Maven with the following structure:

proj-build
|--- proj-utils
|--- proj-persistence
|--- proj-services
|--- proj-web
`--- proj-ear

Description

proj-build: This group the modules only for carrying out the chain build in the modules, that is, each project has its own configuration when the build is carried out, without any relationship with this project Parent(proj-build).

proj-utils: This module gathers utility classes such as: Exception Classes, Classes that configure Hibernate Sessionfactory, etc..

proj-persistence: This module gathers entity classes, DAO classes, DAO interfaces. It has dependencies like JPA, Hibernate, etc..

proj-services: This module brings together classes that implement the business logic. It is dependent on the proj-persistence module.

web-project: This module brings together the Controllers classes, HTML pages, CSS pages, Javascript and any other features you need on the pages. Has dependency with proj-services module, Spring MVC, Spring Security, JSTL, Java Servlet, etc..

projector-Ear: This module is dependent on all other modules except proj-build. This module packages the other modules in an EAR package.

My question is: How do I apply the Spring DI/Ioc Framework as a dependency on this modular project? I apply the dependency on all modules or on some specific module?

1 answer

2


Spring configurations can be distributed among the projects, each configuring its respective components. This ensures the possibility of unit testing in each module.

Some modules will have dependencies. For example, the proj-services you’ll probably need the proj-persistence, right? in which case there are two exits:

Import configuration

Configuration of one project can include configuration of another, simply by making an import.

Imagine you have a file called spring-config-service.xml and this project depends on the utils and of persistence. So in the configuration of this project, do so:

<import resource="classpath:/spring-config-persistence.xml" />
<import resource="classpath:/spring-config-util.xml" />

Inclusion via annotation in unit tests

Another alternative (even more flexible) is to include settings only in unit tests.

Example:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {
        "classpath:/spring-config-service.xml",
        "classpath:/spring-config-persistence.xml",
        "classpath:/spring-config-util.xml"})
@Configurable
public class UnitTests { ... }

In the above example, you can see that it is possible to add as many settings as necessary to initialize Spring in the current test.

This is very good because you could even create specific settings for the test, with mocks and everything you need, although the same can be achieved using profiles.

Important note

In both cases of import the project must properly declare its Maven dependencies and the configuration files must be in their respective directories resource so that they are available on classpath test.

Configuration of the final application

Finally, being a web application that will be distributed in a WAR, you can define all the settings that should be loaded with a parameter, thus:

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
        /WEB-INF/spring-config-web.xml
        classpath:/spring-config-service.xml",
        classpath:/spring-config-persistence.xml",
        classpath:/spring-config-util.xml"})
    </param-value>
</context-param>

Note: if the settings are packaged in Jar files and Spring complains that it doesn’t, try adding an asterisk (*) after the term classpath in the definition, as in the following.

classpath*:/spring-config-util.xml
  • First thank you for answering me. And just to clarify, in the first case it is about the module proj-services, where the imports so that it is possible to inject the DAO’s and utility classes into the module proj-services from what I understand. Already in the last case, which is the file configuration web.xml, is referenced all the configuration files of each module, which is where the container will take all the configuration to interact with all the modules as a whole, so I understood. Correct me if I got it wrong.

  • (NOTE: in the above comment the container I’m trying to say is the DI/Ioc container of Spring) But in the case of the files pom.xml of each module, these will be dependent on the artifact spring-context right? Except for the module proj-web, in which it will be dependent on spring-mvc, that in a transitive way will have the spring-context.

  • @klaytonbrito Regarding the first comment. If you use import in a file do not need to declare all on web.xml. As for the second, you can declare the spring-context in all of them, including the web. It is not good practice to depend directly on undeclared dependencies. To avoid redundancies, use a Parent pom with a section dependencyManagement declaring all project dependencies.

  • I get it. About the Parent pom it is good to reuse the proj-build? Or is it better to create another module for dependencies? Something else, I created one context.xml which contains the configuration of a Datasource JNDI for database connection and put in the META-INF module proj-web so that it can be used by Spring Security, but the hibernate.cfg.xml who is in the proj-persistence you will need to point to the Datasource JNDI of the context.xml, if I use this property then it will work correctly? <property name="connection.datasource">java:/comp/env/jdbc/projbanco</property>

  • The Parent pom it is better to be a separate project, just for that. At least for me it works better. As for the datasource you can configure Hibernate by Spring (example). There does not repeat the configuration.

  • Got it, the Hibernate configuration link you passed is very interesting. Thank you very much for the help, man. Your answers enlightened me many things and I learned several new things.

Show 1 more comment

Browser other questions tagged

You are not signed in. Login or sign up in order to post.