Spring annotation-based DI vs xml configuration?

JavaSpringConfigurationDependency InjectionAnnotations

Java Problem Overview


Recently in our team we started discussing using spring annotations in code to define spring dependencies. Currently we are using context.xml to define our dependencies. Would you give me some clues for either approach, and when one is better to be used?

Edit: I know this seems a duplicate question to a more-general one, but I am interested in the impacts of annotations vs configuration for dependency injection only, which I believe would have different answers and attitude than the general question.

Java Solutions


Solution 1 - Java

After reading some related posts here and having further discussion in the team we come to the following conclusions. I hope the would be useful to others here.

About XML configuration (which we are using up to now), we decided to keep it for dependencies defined by libraries (regardless if being developed by us, or by third parties).
Libraries, by definition, provide a particular functionality and can be used in various scenarios, not necessarily involving DI. Therefore, using annotations in the library projects we develop ourselves, would create a dependency of the DI framework (Spring in our case) to the library, making the library unusable in non-DI context. Having extra dependencies is not considered a good practice among our team (an in general IMHO).

When we are assembling an application, the application context would define the necessary dependencies. This will simplify dependency tracking as the application becomes the central unit of combining all the referenced components, and usually this is indeed where all the wiring up should happen.

XML is also good for us when providing mock implementations for many components, without recompiling the application modules that will use them. This gives us flexibility when testing running in local or production environment.

In regards to annotations, we decided that we can benefit using them when the injected components will not vary -- for instance only a certain implementation for a component will be used troughout the application.

The annotations will be very useful for small components/applications that will not change or support different implementations of a dependency at once, and that are unlikely to be composed in a different way (for instance using different dependencies for different builds). Simple micro-services would fit in this category.

Small enough components, made up with annotations, can be used right out of the box in different projects, without having the respective applications to cover them in their XML configuration. This would simplify the application dependency wiring for the application and reduce repetitive setups.

However, we agreed that such components should have the dependencies well described in our technical documentation, so that when assembling the entire application, one can have an idea of these dependencies without scrolling through the code, or even loading the module in the IDE.

A negative side effect of annotation-configured components, is that different components could bring clashing transitive dependencies, and again it is up to the final application to resolve the conflicts. When these dependencies are not defined in XML, the conflict resolution approaches become quite limited and straying far from the best practices, if they are at all possible. So, when going with annotations, the component has to be mature enough about what dependencies it is going use.

In general if our dependencies may vary for different scenarios, or a module can be used with different components, we decided to stick to XML. Clearly, there MUST be a right balance between both approaches, and a clear idea for the usages.


An important update regarding the mixed approach. Recently we had a case with a test framework we created for our QA team, which required dependencies from another project. The framework was designed to use the annotation approach and Spring configuration classes, while the referenced project had some xml contexts that we needed to reference. Unfortunately, the test classes (where we used org.testng with spring support) could only work with either the xml or java configuration classes, not mixing both.

This situation illustrates a case where mixing the approaches would clash and clearly, one must be discarded. In our case, we migrated the test framework to use spring xml contexts, but other uses could imply the other way around.

Solution 2 - Java

Some advantages of using XML configuration:

  1. The XML configuration is at one place, instead of being scattered all over the source code in case of annotations. Some people may argue that IDEs like STS allow you to look at all annotations based configuration in one place, but I never like having dependencies on IDEs.
  2. Its takes a little more efforts to write XML config, but it saves a lot of time later when you search for dependencies and try to understand the project.
  3. XML keeps configuration well organized and simple. Hence is easier to understand, it helps new relatively inexperienced team members get up to speed quickly.
  4. Allows you to change the config without a need to recompile and redeploy code. So it is better, when it comes to production support.

So in short XML configuration takes a little more efforts, but it saves you a lot of time & headache later in big projects.

2.5 years later:

We use annotations mostly these days, but most crucial change is that we create many small projects (instead of a one big project). Hence understanding dependencies is not a problem anymore; as each project has it's unique purpose and relatively small codebase.

Solution 3 - Java

from my experience, I would prefer(or rather am forced by limitations) to use a combination of XML and annotation based DI . If I need to inject a Map of elements inside a bean , I would have to define a util:map and autowire it . Also, I need to use XML DI to inject datasource into the sessionFactory if I have multiple datasources and so on . So a combination of both would be requited .

I prefer the usage of component-scan to autodetect the services and Dao . This cuts down a lot of Configuration (We cut down the configuration files by around 50% switching to component-scan). Annotation based DI supports both byName(@Resource) and byType(@Autowired).

In short my advice to be to go for a fixture of both . I feel that more annotation support will definitely be on cards in future Spring releases.

Solution 4 - Java

Take a look at this answer here: https://stackoverflow.com/questions/182393/xml-configuration-versus-annotation-based-configuration

A short quote directly from there:

> Annotations have their use, but they are not the one silver bullet to > kill XML configuration. I recommend mixing the two! > > For instance, if using Spring, it is entirely intuitive to use XML for > the dependency injection portion of your application. This gets the > code's dependencies away from the code which will be using it, by > contrast, using some sort of annotation in the code that needs the > dependencies makes the code aware of this automatic configuration. > > However, instead of using XML for transactional management, marking a > method as transactional with an annotation makes perfect sense, since > this is information a programmer would probably wish to know.

EDIT: Also, take a look at the answers here: https://stackoverflow.com/questions/4995170/java-dependency-injection-xml-or-annotations They most probably target the area of your interest much better.

Solution 5 - Java

From my own experience annotations better than xml configuration. I think in any case you can override xmls and use annotations. Also Spring 4 give us a huge support for annotations, we can override security from xml to annotations e.t.c, so we will have not 100 lines xml but 10 lines Java Code.

Solution 6 - Java

> Are annotations better than XML for configuring Spring? > > The introduction of annotation-based configurations raised the > question of whether this approach is 'better' than XML. The short > answer is it depends. The long answer is that each approach has its > pros and cons, and usually it is up to the developer to decide which > strategy suits them better. Due to the way they are defined, > annotations provide a lot of context in their declaration, leading to > shorter and more concise configuration. However, XML excels at wiring > up components without > > > touching their source code or recompiling them. Some developers prefer > having the wiring close to the source while others argue that > annotated classes are no longer POJOs and, furthermore, that the > configuration becomes decentralized and harder to control. > > No matter the choice, Spring can accommodate both styles and even mix > them together. It’s worth pointing out that through its JavaConfig > option, Spring allows annotations to be used in a non- invasive way, > without touching the target components source code and that in terms > of tooling, all configuration styles are supported by the Spring Tool > Suite.

my personal option is that xml is better since you have all at one place and you do not need to deep into your packages to search the class.

Solution 7 - Java

We can not tell which method is good, it depends on your project. We can nither avoid xml nor annotation. One advantage of using xml is that we can understand the project structure just seeing the xml context files, but annotation reduces lots of meta configuration. So I prefer 30% xml and 70% annotation.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionIvaylo SlavovView Question on Stackoverflow
Solution 1 - JavaIvaylo SlavovView Answer on Stackoverflow
Solution 2 - JavaPritesh MhatreView Answer on Stackoverflow
Solution 3 - JavaAravind AView Answer on Stackoverflow
Solution 4 - JavanowaqView Answer on Stackoverflow
Solution 5 - JavaArtur YolchyanView Answer on Stackoverflow
Solution 6 - JavaAdam OstrožlíkView Answer on Stackoverflow
Solution 7 - JavaUday Pratap MauryaView Answer on Stackoverflow