LiorH
LiorH

Reputation: 18824

Spring context files organization and best practices

We have started using Spring framework in my project. After becoming acquainted with the basic features (IoC) we have started using spring aop and spring security as well.

The problem is that we now have more than 8 different context files and I feel we didn't give enough thought for the organization of those files and their roles. New files were introduced as the project evolved. We have different context files for: metadata, aop, authorization, services, web resources (it's a RESTful application). So when a developer wants to add a new bean it's not always clear in which file he should add it. We need methodology.

The question:

Is there a best practice for spring files organization?

Should the context files encapsulate layers (DAL , Business Logic, Web) or use cases ? or Flows?

Upvotes: 22

Views: 12408

Answers (7)

Kariem
Kariem

Reputation: 4913

I would follow spring's recommendations and place the context files in META-INF/spring as described in the Spring Roo documentation. In general, I would recommend trying out roo and following their project structure and layout.

Example

src/
+-- main/
|   +-- java/
|   \-- resources/
|       +-- META-INF/
|       |   \-- spring/                    ‹ normal spring context files
|       |       +-- context.xml
|       |       \-- context-services.xml
|       \-- other files
|
+-- test/
|   +-- java/
|   \-- resources/
|       +-- META-INF/
|       |   \-- spring/                    ‹ context files for testing
|       |       +-- context-test.xml
|       |       \-- context-dao-test.xml   
|       \-- other files
|
\-- pom.xml

Spring XML vs annotations

There are many good articles on the topic, but I would like to break up a common misconception, because both approaches have their merits: If you want to separate the configuration from the actual implementation, it is easier with XML, but you can achieve the same thing with annotations, as krosenvold said. However, when using XML configuration files, bean names are only required, if the bean has to be referenced directly. You can always use auto-wiring by name or by type.

The only important thing is that you should stay consistent throughout the project, or, where possible, across your company's projects.

Upvotes: 1

Jase
Jase

Reputation:

yep - split on similar roles for the beans therein. As for annotations, I believe they "may" have a small role to play, perhaps with transaction definitions, but otherwise they just forever bind your code and you might as well be adding spring (or any other 3rd party) references directly everywhere. For me annotations=shortcut and technical debt. They aren't externally configurable, so its not trivial to rewire, or unwire your code, and limits reuse. A given bean is forever stuck with its annotated dependencies and configuration so cant be used by multiple projects/processes simultaneously with different wiring and config. just my 2 cents.

Upvotes: 1

Domchi
Domchi

Reputation: 10823

Start with applicationContext.xml and separate when there's a lot of beans which have something in common.

To give you some idea of a possible setup, in the application I'm currently working on, here's what I have in server:

  • applicationContext.xml
  • securityContext.xml
  • schedulingContext.xml
  • dataSourcecontext.xml
  • spring-ws-servlet.xml (Spring Web Services related beans)

For GUI clients, since this project has several, there is one folder with shared context files, and on top of that, each client has its own context folder. Shared context files:

  • sharedMainApplicationContext.xml
  • sharedGuiContext.xml
  • sharedSecurityContext.xml

App-specific files:

  • mainApplicationContext.xml and
  • guiContext.xml and
  • commandsContext.xml (menu structure)
  • sharedBusinessLayerContext.xml (beans for connecting to server)

Upvotes: 7

cliff.meyers
cliff.meyers

Reputation: 17734

Breaking the config into separate files is useful to me in terms of testing. On a small project, I'll put Spring Security config into "securityContext.xml" and the rest of my beans into "applicationContext.xml." Then while running integration tests, it's easy to enable or disable security simple by choosing whether to include securityContext.xml. This almost resembles AOP in a way, in that you add more functionality to the application by choosing whether to include particular files.

Upvotes: 0

krosenvold
krosenvold

Reputation: 77231

If you're still reasonably early in the project I'd advice you strongly to look at annotation-driven configuration. After converting to annotations we only have 1 xml file with definitions and it's really quite small, and this is a large project. Annotation driven configuration puts focus on your implementation instead of the xml. It also more or less removes the fairly redundant abstraction layer which is the spring "bean name". It turns out the bean name exists mostly because of xml (The bean name still exists in annotation config but is irrelevant in most cases). After doing this switch on a large project everyone's 100% in agreement that it's a lot better and we also have fairly decent evidence that it's a more productive environment.

I'd really recommend anyone who's using spring to switch to annotations. It's possible to mix them as well. If you need transitional advice I suppose it's easy to ask on SO ;)

Upvotes: 19

duffymo
duffymo

Reputation: 309008

I find that I break them out by layer.

When I write unit tests for each layer I override the production context with values pertinent for the tests.

Upvotes: 1

kgiannakakis
kgiannakakis

Reputation: 104198

Spring context files contain definitions of beans, so I think that it is best to follow OO principle and structure them the same way you structure your classes in packages. We usually create packages to encapsulate a set of classes that work together to solve a specific problem. A package usually encapsulates a horizontal layer (database layer, middleware, business logic or part of them). There are occasions that a package contain classes that correspond to a horizontal layer (use case or flow as you've mentioned). In general I would recommend to create one context file for every package or set of packages. When you add a new bean, add it to the context file that corresponds to the package of the class.

Of course this shouldn't be a very strict rule, as there might be cases that it would beneficial to follow another practice.

Upvotes: 5

Related Questions