Xml Configuration Versus Annotation Based Configuration

Spring annotation-based DI vs xml configuration?

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.

Java-based vs annotation-based configuration/autowiring

Java based Configuration:

The official Spring documentation refers to configuring your beans using a Java class annotated with @Configuration and containing @Bean methods as 'Java Configuration'. This allows you to be absolutely free of all XML in your application (at least as far as Spring goes). This support was added in Spring 3.0, and has gotten more powerful.

Source

In other words, there is no configuration file required. If everything is fine with your application.

Annotation based Configuration:

Starting from Spring 2.5 it became possible to configure the dependency injection using annotations. So instead of using XML to describe a bean wiring, you can move the bean configuration into the component class itself by using annotations on the relevant class, method, or field declaration.

Source

In other words, there are XML configuration files yet but bean wiring, is configured using annotations.

Note: Annotation injection is performed before XML injection. Thus, the latter configuration will override the former for properties wired through both approaches.

Note: Annotation wiring is not turned on in the Spring container by default. So, we can use annotation-based wiring, we will need to enable it in our Spring configuration file.

Xml configuration versus Annotation based configuration

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. But that an interface is going to be injected as a SubtypeY instead of a SubtypeX should not be included in the class, because if now you wish to inject SubtypeX, you have to change your code, whereas you had an interface contract before anyways, so with XML, you would just need to change the XML mappings and it is fairly quick and painless to do so.

I haven't used JPA annotations, so I don't know how good they are, but I would argue that leaving the mapping of beans to the database in XML is also good, as the object shouldn't care where its information came from, it should just care what it can do with its information. But if you like JPA (I don't have any expirience with it), by all means, go for it.

In general:
If an annotation provides functionality and acts as a comment in and of itself, and doesn't tie the code down to some specific process in order to function normally without this annotation, then go for annotations. For example, a transactional method marked as being transactional does not kill its operating logic, and serves as a good code-level comment as well. Otherwise, this information is probably best expressed as XML, because although it will eventually affect how the code operates, it won't change the main functionality of the code, and hence doesn't belong in the source files.

Do we need xml file for doing Spring configuration using Annotation?

XML is not required for Spring configuration. You can configure Spring with pure Java-based configuration (annotations).

For example, instead of using the XML you posted in your question you can create a class with @Configuration and @ComponentScan annotations:

@Configuration
@ComponentScan(basePackages = {"com.example.point", "com.example.shapes"})
public class MySpringConfig {

public static void main(String[] args) {
// Create Spring ApplicationContext from annotation config
ApplicationContext context =
new AnnotationConfigApplicationContext(MySpringConfig.class);

// ...
}
}

See Java-based container configuration in the Spring Framework reference documentation.

Benefits of JavaConfig over XML configurations in Spring?

There are some advantages

  1. Java is type safe. Compiler will report issues if you are
    configuring right bean class qualifiers.
  2. XML based on configuration can quickly grow big. [Yes we can split
    and import but still]
  3. Search is much simpler, refactoring will be bliss. Finding a bean
    definition will be far easier.

There are still people who like XML configuration and continue to do it.

References:
Java configuration advantages
Some more reasons

@Autowired vs XML

This was actually a topic of lively conversation around the time that Spring 3.0 came out in 2009 and JavaConfig was added to the core system base.

In theory, being able to externalize application setup is a great thing. However, it turns out that in practice there are two distinct groups of setup choices: the application shape or dependency graph, and particular values like API keys, database connection strings, and so on that vary between environment but usually don't change the way that the beans are wired.

Experience has shown that the dependency graph, which is essentially what you'd express in XML, is almost never changed without also making changes to the accompanying implementation code anyway, so there is very little real-world benefit to defining the graph in XML. On the other hand, writing @Bean methods in Java means that it's a lot easier to test configuration when needed, the compiler can ensure type safety, and decision logic (such as conditionals) are simpler to implement.

Furthermore, the availability of annotations means that it's possible to extend the domain-specific language for configuration fairly easily in Java--just create a new annotation and its accompanying processor (such as @ConditionalOnProperty); Spring Boot itself is an extreme example of the flexibility of this model. In XML, on the other hand, injecting new tags or attributes into a schema is a lot more of a hassle.

There are times when XML may still be the better choice (I've particularly gone with it for writing out Spring Integration pipelines, which can be easier to read in XML than in the Java DSL), but the real-world benefits turned out not to be all that valuable in most cases, and the safety and flexibility of configuration as code has won out.



Related Topics



Leave a reply



Submit