Community Post

Java team briefing about Apache Tika

Ethan Millar

Java developers can avail different configuration elements from Spring MVC framework to handle the beans and inject them when required. In this article, they will make you learn about XML configurations used in Spring MVC, advantages, and disadvantages, and uses in detail. To gain knowledge about the same, read the post thoroughly.

Spring MVC framework provides different configuration elements that are helping or instructing the Spring container to effectively manage the beans and inject the beans when required. Some of the XML configurations that are most commonly seen in our spring configuration files are:

  • context:component-scan
  • mvc:annotation-config
  • context:annotation-driven

<context:annotation-config> is used to activate applied annotations in already registered beans in application context.

<context:component-scan> can also do what <context:annotation-config> does but <context:component-scan> also scans packages to find and register beans within the application context.

The functionality of the above annotations are similar and there is little variations on how they are reacting on the specific scenarios.

Advantages and Disadvantages:

The often sighted โ€œproโ€ of annotation is that they are attached to the program artifacts they describe. 1) This gives the metadata information relevance that is not always there when viewed in an XML file. 2) However, when searching an application for all the applicable and like program characteristics, an XML document makes the search concise.

Annotations can replace XML deployment descriptors and configurations. 1) Annotations are typically much simpler to code than XML. 2) XML is not always the easiest of documents to read or maintain and it is often very verbose.

Some configuration/deployment information can now be shared across programming environments. 1) Annotations, as part of the actual source code, will not support and promote any cross-platform sharing.

Uses Of Annotation-Config, Annotation-Driven And Component-Scan

  • annotation-config allow us to use @Autowire, @Required and @Qualifier annotations.
  • component-scan allow @Component, @Service, @Controller, etc.. annotations.
  • annotation-driven <mvc:annotation-driven /> declares explicit support for annotation-driven MVC controllers (i.e. @RequestMapping, @Controller, although support for those is the default behaviour), as well as adding support for declrative validation via @Valid and message body marshalling with @RequestBody/ResponseBody.

1) context:component-scan

This element has been introduced in Spring configuration from version 2.5. If you have worked with the previous versions of Spring, all the beans has to be manually configured in the XML files.

There are no annotations supported in the Java beans. This will result in lot of XML code in the configuration files and every time developer has to update the XML file for configuring the new beans.

  • context:component-scan element in the spring configuration file would eliminate the need for declaring all the beans in the XML files.

Below declaration in your spring configuration file:

<context:component-scan base-package="org.controller"/>

The above declaration in the spring application configuration file would scan the classes inside the specified package and create the beans instance.

The following are the annotations scanned by this element:

  • @Component
  • @Repository
  • @Service
  • @Controller

One advantage of this element is that it also resolves @Autowired and @Qualifier annotations. Therefore if you declare <context:component-scan>, is not necessary anymore declare <context:annotation-config> too.

2) mvc:annotation- config mvc:annotation-driven is used for enabling the Spring MVC components with its default configurations.

If you donโ€™t include mvc:annotation-driven then also your MVC application would work, if you have used the context:component-scan for creating the beans or defined the beans in your XML file.

But, mvc:annotation-driven does some extra job on configuring the special beans that would not have been configured if you are not using this element in your XML file.

This tag would register the HandlerMapping and HandlerAdapter required to dispatch requests to your @Controllers. In addition, it also applies some defaults based on what is present in your classpath.

Such defaults are:

  • Using the Spring 3 Type ConversionService as a simpler and more robust alternative to JavaBeans PropertyEditors
  • Support for formatting Number fields with @NumberFormat
  • Support for formatting Date, Calendar, and Joda Time fields with @DateTimeFormat, if Joda Time is on the classpath
  • Support for validating @Controller inputs with @Valid, if a JSR-303 Provider is on the classpath
  • Support for reading and writing XML, if JAXB is on the classpath
  • Support for reading and writing JSON, if Jackson is on the classpath

3) context:annotation-driven context:annotation-config is used for activating annotations in beans already registered in the application context.

That means it will resolve @Autowired and @Qualifier annotations for the beans which are already created and stored in the spring container.

context:component-scan can also do the same job, but context:component-scan will also scan the packages for registering the beans to application context.

context:annotation-config will not search for the beans registration, this will only activate the already registered beans in the context.

Example of <context:annotation-config> <context:component-scan>

I will elaborate both tags in detail with some examples which will make more sense to us.

For reference, below are 3 beans. BeanA has reference to BeanB and BeanC additionally.

package com.example.beans;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@SuppressWarnings("unused")
@Component
public class BeanA {
    private BeanB beanB;
    private BeanC beanC;
    public BeanA(){
        System.out.println("Creating bean BeanA");
    }
    @Autowired
    public void setBeanB(BeanB beanB) {
        System.out.println("Setting bean reference for BeanB");
        this.beanB = beanB;
    }
    @Autowired
    public void setBeanC(BeanC beanC) {
        System.out.println("Setting bean reference for BeanC");
        this.beanC = beanC;
    }
}

//Bean B  
package com.example.beans;
import org.springframework.stereotype.Component;
@Component
public class BeanB {
    public BeanB(){
        System.out.println("Creating bean BeanB");
    }
}

//Bean C
package com.example.beans;
import org.springframework.stereotype.Component;
@Component
public class BeanC {
    public BeanC(){
        System.out.println("Creating bean BeanC");
    }
}

BeanDemo class is used to load and initialize the application context.

package com.example.test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class BeanDemo {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("classpath:beans.xml");
    }
}

a) Define only bean tags

<bean id="beanA" class="com.example.beans.BeanA"></bean>
<bean id="beanB" class="com.example.beans.BeanB"></bean>
<bean id="beanC" class="com.example.beans.BeanC"></bean>

Output: Creating bean BeanA

Creating bean BeanB

Creating bean BeanC

In this case, all 3 beans are created and no dependency in injected in BeanA because we didnโ€™t used any property/ref attributes.

b) Define bean tags and property ref attributes


<bean id="beanA" class="com.example.beans.BeanA">
    <property name="beanB" ref="beanB"></property>
    <property name="beanC" ref="beanC"></property>
</bean>
<bean id="beanB" class="com.example.beans.BeanB"></bean>
<bean id="beanC" class="com.example.beans.BeanC"></bean>

Output:

Creating bean BeanA

Creating bean BeanB

Creating bean BeanC

Setting bean reference for BeanB

Setting bean reference for BeanC

Now the beans are created and injected as well.

c) Using only <context:annotation-config />

<context:annotation-config />

//No Output

<context:annotation-config /> activate the annotations only on beans which have already been discovered and registered. Here, we have not discovered any bean so nothing happened.

d) Using <context:annotation-config /> with bean declarations

<context:annotation-config />
<bean id="beanA" class="com.example.beans.BeanA"></bean>
<bean id="beanB" class="com.example.beans.BeanB"></bean>
<bean id="beanC" class="com.example.beans.BeanC"></bean>

Output:

Creating bean BeanA

Creating bean BeanB

Setting bean reference for BeanB

Creating bean BeanC

Setting bean reference for BeanC

In above configuration, we have discovered the beans using <bean> tags. Now when we use <context:annotation-config />, it simply activates @Autowired annotation and bean injection inside BeanA happens.

e) Using only <context:component-scan />

<context:component-scan base-package="com.example.beans" />

Output:

Creating bean BeanA

Creating bean BeanB

Setting bean reference for BeanB

Creating bean BeanC

Setting bean reference for BeanC

Above configuration does both things as I mentioned earlier in start of post. It does the bean discovery (searches for @Component annotation in base package) and then activates the additional annotations (e.g. Autowired).

f) Using both <context:component-scan /> and <context:annotation-config />

<context:annotation-config />
<context:component-scan base-package="com.example.beans" />
<bean id="beanA" class="com.example.beans.BeanA"></bean>
<bean id="beanB" class="com.example.beans.BeanB"></bean>
<bean id="beanC" class="com.example.beans.BeanC"></bean>

Output:

Creating bean BeanA

Creating bean BeanB

Setting bean reference for BeanB

Creating bean BeanC

Setting bean reference for BeanC

Example of mvc:annotation-driven

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans.xsd

http://www.springframework.org/schema/context

http://www.springframework.org/schema/context/spring-context.xsd

http://www.springframework.org/schema/mvc

                           http://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <context:component-scan base-package="org.springbyexample.web.servlet.mvc" />

    <mvc:annotation-driven />

    <mvc:view-controller path="/index.html" />

    <bean id="tilesConfigurer"
          class="org.springframework.web.servlet.view.tiles2.TilesConfigurer"
          p:definitions="/WEB-INF/tiles-defs/templates.xml" />

    <bean id="tilesViewResolver"
          class="org.springframework.web.servlet.view.UrlBasedViewResolver"
          p:viewClass="org.springbyexample.web.servlet.view.tiles2.DynamicTilesView"
          p:prefix="/WEB-INF/jsp/"
          p:suffix=".jsp" />

    <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource"
          p:basenames="messages" />

    <!-- Declare the Interceptor -->
    <mvc:interceptors>    
        <bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor"
              p:paramName="locale" />
    </mvc:interceptors>

    <!-- Declare the Resolver -->
    <bean id="localeResolver" class="org.springframework.web.servlet.i18n.SessionLocaleResolver" />

</beans>

You have just learned about advantages, disadvantages, and uses of XML configurations used in Spring MVC framework by Java developers. For any doubts or queries, please comment in below section. We will give you the required solutions.

Ethan Millar

I am a technical writer for the last nine years at Aegis Softtech. I especially write articles related to Java, support, services and latest updates .