How do you make a multi-module spring configuration?


How do you make a multi-module spring configuration?



I have a multi-module (maven) spring build. All the modules publish some beans, and most also consume beans defined further down the dependency graph. Although most of it is annotation declared beans, almost every module also has one or two xml-declared beans.

Although we have a half-decent solution, but I am really wondering what is the correct/optimal way to organize the xml files in this scenario? Do you use import between the modules or is there some other way ? Do you put all the xml files in one place or spread them around according to the dependency graph? How does your solution handle partial spring contexts (typical integration tests) ?

I'd also like to have this organized in a way that lets me leverage my IDE's spring support optimally (IDEA and a few eclipse users).




GWT using domain models /services from external module (jar)?

1:



CXF JAX-RS is causing BusException
We use wildcarded imports in the modules to allow other modules contribute beans to the module declaring the import:.
spring: add xml context on-the-fly?
<import resource="classpath*:com/acme/**/*-core-support.xml" /> 

Modularity

Modules that want to contribute to the "host" just have to place a correctly named files in src/main/resources/com/acme in this case to be picked up automagically.


Setting values from a class to Spring context file
If you use classpath scanning (by <context:component-scan /> it will become even easier)..
JPA Multiple Persistence Unit bug
Another thing that helps in that regard is some small Spring extension that picks up beans of a given type and republishes them in ApplicationContext again.


How to bind CustomDateEditor to all Date fields in Springframework?
By doing something like this:.
Ibatis : Is there a way of adding a rowhandler in an Ibatis resultmap subselect within the sqlmap xml?
<plugin:list id="beanList" class="com.acme.MyCoolPluginInterface" />  <bean class="com.acme.MyPluginHost">    <property name="plugins" ref="beanList" /> </bean> 
In combination with the wildcarded import this will:.
org.springframework.transaction.annotation.Transactional vs javax.jdo.annotations.Transactional
  1. Collect all beans found in the ApplicationContext that implement MyCoolPluginInterface and wrap them in a list registered as beanList in the ApplicationContext.
  2. Allow the MyPluginHost to reference that list.
In fact, you now can simply extend your app by adding plugin modules to the classpath (aka dependency in Maven).. That tiny Spring extension is called Spring Plugin and published under Apache 2 licence.

See http://github.com/SpringSource/spring-plugin for more info.

There's also a more advanced sample project at Github, that shows how this works and improves modularity at GitHub.

The app is sample code for my "Whoops! Where did my architecture go?" presentation which you can see the slides here or watch a recording here..

Different environments

Usually we configure our apps to run in the target environment (using JNDI lookups and stuff).

Of course you would like to use the standard PropertyPlaceholderConfigurer mechanisms to externalize configuration that has to be touched by admins or will change through various environments.. For integration tests we usually have additional config files in src/main/test that get loaded additionally to the normal config files overriding the critical beans that tie the configuration to the environment.

E.g.

if you have a datasource in your normal config file.
 <jee:jndi-lookup id="dataSource" jndi-name="jdbc/MyDataSource" /> 
you would override this in your test-context.xml by using.
 <bean id="dataSource" class="...DataSource" />     <!-- config -->  </bean> 
and importing that after the original one in the test class.
 @ConfigurationContext(locations = {"app-context.xml", "test-context.xml"})  public FooBarIntegrationtest {    // ... 

}


2:


We simply create the application context from multiple XML config files based on usage.

. For example, for testing without a server, the context is created by using all the config files in each service module.. When deployed, we access the services via Spring Remoting, and thus the client uses an application context that is initialized via an XML config which defines the proxy beans that enable remoting.

Meanwhile the services are confgured by the same XML files as used by the test cases, but the application context is now loaded by either the DispatcherServlet or an EJB or MDB.. This setup allows us to tailor the Application Context for each scenario without having to duplicate any information in configuration files, which keeps maintenance much simpler.

Also, there is no hard dependency between config files via imports, since that is handled at the layer above that actually creates the ApplicationContext.. Can't comment on the IDE support since we are not using it yet..



85 out of 100 based on 75 user ratings 1375 reviews