Tuesday, 25 March 2014

Using @Autowired and @Component - Spring Dependency Injection

In this example we will discuss spring dependency injection using annotations. Here I'll introduce you to two simple annotations, @Component and @Autowired. In the previous example, we have declared those beans in the application context xml file. But in this file, we will create only one bean and we will inject that bean into another class via annotations.

Simple bean - Message.java


package spring2;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;


@Component("msgObject")
public class Message {

private String message;

    @Autowired
    public void setMessage(String message)
    {
        this.message=message;
    }
   
    public String getMessage()
    {
        return message;
    }
}

The @Autowired annotation allows the container to automatically inject the message property from the application-context.xml file. The container searches for String bean object in the xml file and injects it here. If multiple String beans exist, then we will get an error.

The @Component tells that Message is a component, a bean whose object has to be created. The "msgObject" is the name of the created object.

Application context - application-context.xml


<?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:context="http://www.springframework.org/schema/context"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
                            http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
                            http://www.springframework.org/schema/context
                            http://www.springframework.org/schema/context/spring-context-3.0.xsd">
       
        <context:annotation-config/>
        <context:component-scan base-package="spring2"/>
       
        <bean id="myMsg" class="java.lang.String">
            <constructor-arg type="java.lang.String" value="Rama"/>
        </bean>
</beans>


Here we have created only one bean that too for java.lang.String. As you can the name of the object is myMsg and we are using the String(String) constructor to create the object. In Java code, the snippet will be


String myMsg=new String("Rama");


The first line, <context:annotation-config/> searches for annotations i.e. it searches for where the dependencies has to be injected.
The second line, <context:component-scan/> searches for dependencies (those values which has to be injected). This takes base-package attribute which will be the package where the dependencies are scanned.

Dependencies are nothing but objects that are essential to create/use other objects.

http://www.springframework.org/schema/context/spring-context-3.0.xsd contains definitions for annotation-config and component-scan tags.

Namespace is a name given to a set of tags. These tags are defined in XSD files (xml schema definition files). In our application-context.xml we will be using tags from different xsd files and sometimes multiple xsd files might contain tags with the same name. So in order to avoid the ambiguous situation, a namespace is provided. Here, context is the namespace. We call it tag prefix here, telling the container that we are using the tag that is defined in the spring-context-3.0.xsd file.

Main class - SpringPrg1.java



package spring2;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class SpringPrg1 {
    public static void main(String args[])
    {
        ApplicationContext ctx=new ClassPathXmlApplicationContext("spring2/application-context.xml");
        Message msg=ctx.getBean("msgObject",Message.class);
        System.out.println(msg.getMessage());
    }
}

Here, we will get the msgObject which is not defined in the XML file, as you can see. Instead, it is written using annotation in the Message class itself.

Here, we have used ctx.getBean("msgObject",Message.class) instead of ctx.getBean("msgObject") in order to avoid explicit type-casting.

No comments:

Post a Comment