1

Before the spiel, I think the question essentially boils down to this:

How can I instantiate correctly @Configuration beans from an application's XML-based configuration?

In an attempt to modularize my project and follow something of a clean architecture, I have created a Maven project composed of three modules. There is a "web" module an "interface" module and a "core" module and both web and core use Spring's Java-based configuration.

Module structure and packaging

The web module declares in it's POM a runtime dependency on the core module and a compile-time dependency on the interface module. The core module is the implementation of the interface module, the latter being composed of only Java interfaces and DTOs. (This is an attempt to program to interface modules.)

When I start the web module I want all the Spring-managed beans from the core module to become known to the web module's application context. I've had some success doing this the "XML-way" by creating an XML file in the core module that looks like this:

// This xml snippet is part of the "core" module
<beans>
    <context:annotation-config />
    <context:component-scan base-package="com.acme.core"/>
</beans>

... and referencing this in the web module configuration like so:

// The configuration of the "web" module
@Configuration
@ImportResource("classpath*:come/acme/configuration/spring/*.xml")
public class RootConfig {}

It works but I'm not happy with the solution because I want all the configuration for the core module to be done the Java way.

So to that end, I note that Spring says one can do the following:

...@Configuration classes may be declared as normal definitions within Spring XML files:

<beans>
    <context:annotation-config/>
    <bean class="com.acme.configuration.spring.CoreConfig"/>
</beans>

That would be (almost) ideal if it worked because the XML file in the core module would be very lean and essentially just bootstrapping the meaty configuration in CoreConfig. However it doesn't work for me and the web module cannot find any of the beans that are defined in the core module. I think this might be because if the beans are instantiated then they are done so in a different application context or maybe because CoreConfig, being marked with @Configuration, is special and instantiating it this way from the XML file doesn't trigger the creation of the other beans it defines.

Incidentally, I'd rather have a way to do this without any XML configuration but referencing com.acme.configuration.spring.AppConfig directly from the web module is not possible since there is no compile time dependency on the code. (Sigh) Modularizing is so far proving to be more trouble than it's worth...

chrisjleu
  • 4,329
  • 7
  • 42
  • 55
  • 2
    Add `@Configuration` classes to your projects in your web do a component scan for `com.acme.configuration` this will pickup all `@Configuration` classes (if the are there). Or put your xml files in a well known location (for instance `/META-INF/spring`) and in yuor `web.xml` do `classpath*:/META-INF/spring/*.xml` that would pickup all xml configuration files. – M. Deinum Jun 05 '14 at 09:26
  • It's not that simple... picking up the XML file of the core module is not the issue in any case; the web module finds the XML file of the core module just fine but I don't know if the `@Configuration` annotation on the `CoreConfig` bean is respected. `CoreConfig` is instantiated but more has to happen to instantiate the beans listed in `CoreConfig` and any other annotations it has that do important things. – chrisjleu Jun 05 '14 at 11:59

1 Answers1

1

The following works when specified in the config class of the "Web" module in my example:

@Configuration
@ComponentScan(basePackages={"com.acme.configuration"})
public class RootConfig {}

In fact, it is what @M. Deinum said to do in a comment on the question. In this example, all com.acme.configuration packages, regardless of whether they might be in another Maven module, will be picked up and processed correctly. It is necessary then, by convention, that all configuration classes of other modules be placed in com.acme.configuration. With this approach there is no need for any XML configuration file to "bootstrap" the configuration as I was trying to do.

chrisjleu
  • 4,329
  • 7
  • 42
  • 55