Springs - SPLessons

Chapter 13

Spring Annotations

Spring Annotations

Spring Annotations are new features of Java provided by the JDK version 5.0. The functionality of the Spring Annotations is providing metadata to the application, meta data is nothing but description of code in the program.

Already Java have comments to provide metadata to the applications, but I will not be useful in program so it is the drawback in the comments. Here Spring Annotations provided the metadata to the application which also useful with the result of the code.

Before JDK 5.0 developers used to XML configuration, in this file developer has to check every compilation, program, parsing is also important and another disadvantage is long code.

Annotations are like replacement of XML file. For instance, while doing servlet, developer has to provide a web.xml file which consists of long code with servlet names and URL names. But by using Annotations it can write as single code like @webservelet (“/login”). Following file is the annotation file should be added to the spring framework.

<?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/>
  <!-- bean definitions go here -->

</beans>

When it is constructed, developers can begin annotating on the program too Express that Spring ought to default include values into methods. Few salient annotations are as follows.

The @Required annotation ought to register bean property setter techniques, then it exposes that the influenced bean property ought to inhabit in the XML configuration file at configure time, if it not happens container launch a BeanInitializationException exception. For instance @Required annotation as follows.

Student.java

package splessons;

import org.springframework.beans.factory.annotation.Required;

public class Student {
   private Integer age;
   private String name;

   @Required
   public void setAge(Integer age) {
      this.age = age;
   }
   public Integer getAge() {
      return age;
   }

   @Required
   public void setName(String name) {
      this.name = name;
   }
   public String getName() {
      return name;
   }
}

Here just created the data members age, name and also performed SET and GET methods.
 MainApp.java 

package splessons;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MainApp {
   public static void main(String[] args) {
      ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");

      Student student = (Student) context.getBean("student");

      System.out.println("Name : " + student.getName() );
      System.out.println("Age : " + student.getAge() );
   }
}

The Application Context is spring’s more best in class holder. Like BeanFactory it can stack bean definitions, wire beans together and administer beans upon solicitation. Also it includes more enterprise-specific usefulness, for example, the capacity to determine literary messages from a properties document and the capacity to distribute application events to interested event listeners. This container is characterized by the org.springframework.context.ApplicationContext interface.
Beans.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/>

  <!-- Definition for student bean -->
  <bean id="student" class="splessons.Student">
      <property name="name" value="Zara" />

      <!-- try without passing age and check the result -->
     <!-- property name="age" value="22"-->
   </bean>

</beans>

After run the code,It may raise BeanInitializationException exception and gives the error with log message as below.

Property 'age' is required for bean 'student'

After erasing comment from ‘age’  can be shown as:

<?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/>

   <!-- Definition for student bean -->
   <bean id="student" class="splessons.Student">
      <property name="name" value="sai" />
     <property name="age" value="22"/>
   </bean>

</beans>

Output 

Name : sai
Age : 22

Autowired annotation consistently useful while doing applications and it can be helped to wire bean setter techniques like @Required annotation. It can be used to wire dependency injections.

Autowired on Setter Methods:

The developer can utilize @Autowired annotations on setter methods to dispose of the <property>  in XML  file. It requires less code because no need of injecting Dependency.Example as follows.

TextEditor.java 

package splessons;

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

public class TextEditor {
   private SpellChecker spellChecker;

   @Autowired
   public void setSpellChecker( SpellChecker spellChecker ){
      this.spellChecker = spellChecker;
   }
   public SpellChecker getSpellChecker( ) {
      return spellChecker;
   }
   public void spellCheck() {
      spellChecker.checkSpelling();
   }
}

 SpellChecker.java

package splessons;

public class SpellChecker {
   public SpellChecker(){
      System.out.println("Inside SpellChecker constructor." );
   }

   public void checkSpelling(){
      System.out.println("Inside checkSpelling." );
   }
   
}

 MainApp.java 

package splessons;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MainApp {
   public static void main(String[] args) {
      ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");

      TextEditor te = (TextEditor) context.getBean("textEditor");

      te.spellCheck();
   }

 Beans.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/>

   <!-- Definition for textEditor bean without constructor-arg -->
   <bean id="textEditor" class="splessons.TextEditor">
   </bean>
   <!-- Definition for spellChecker bean -->
   <bean id="spellChecker" class="splessons.SpellChecker">
   </bean>

</beans>

activates many different annotations in beans, whether they are defined in XML or through component scanning. is for defining beans without using XML.
Output

Inside SpellChecker constructor.
Inside checkSpelling.

Autowired on Properties

package splessons; import org.springframework.beans.factory.annotation.Autowired; public class TextEditor { @Autowired private SpellChecker spellChecker; public TextEditor() { System.out.println("Inside TextEditor constructor." ); } public SpellChecker getSpellChecker( ){ return spellChecker; } public void spellCheck(){ spellChecker.checkSpelling(); } }

Beans.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/>

  <!-- Definition for textEditor bean -->
   <bean id="textEditor" class="splessons.TextEditor">
  </bean>

   <!-- Definition for spellChecker bean -->
  <bean id="spellChecker" class="splessons.SpellChecker">
   </bean>
</beans>

Output

Inside TextEditor constructor.
Inside SpellChecker constructor.
Inside checkSpelling.

@Autowired on Constructors

@Autowired useful for constructors als0 and demonstrates that the constructor ought to be authored while establishing the bean, regardless of the fact that no; components are utilized while designing the bean as a part of an XML document. Following is an example.
The content of TextEditor.java file:

package splessons;

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

public class TextEditor {
   private SpellChecker spellChecker;

   @Autowired
   public TextEditor(SpellChecker spellChecker){
      System.out.println("Inside TextEditor constructor." );
      this.spellChecker = spellChecker;
   }

   public void spellCheck(){
      spellChecker.checkSpelling();
   }
}

The configuration file Beans.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/>

   <!-- Definition for textEditor bean without constructor-arg -->
   <bean id="textEditor" class="splessons.TextEditor">
   </bean>

  <!-- Definition for spellChecker bean -->
   <bean id="spellChecker" class="splessons.SpellChecker">
  </bean>

</beans>

Output as follows

Inside TextEditor constructor.
Inside SpellChecker constructor.
Inside checkSpelling.

Autowired with (required=false) option

Below code  works only if don’t give value for age property but it  demands for name property tag.
Student.javafile will be like as follows.

package splessons; import org.springframework.beans.factory.annotation.Autowired; public class Student { private Integer age; private String name; @Autowired(required=false) public void setAge(Integer age) { this.age = age; } public Integer getAge() { return age; } @Autowired public void setName(String name) { this.name = name; } public String getName() { return name; } }

The developer might have a circumstance when give one or more bean of the similar type and need to wire one of them with a property, in such case you can utilize @Qualifier annotation.Example is as follows.

 Student.java 

package splessons;

public class Student {
   private Integer age;
   private String name;

   public void setAge(Integer age) {
      this.age = age;
   }
   
   public Integer getAge() {
      return age;
   }

   public void setName(String name) {
      this.name = name;
   }
   
   public String getName() {
      return name;
   }
}

Here the developer taken two data members such as age, name and also performed SET and GET operations.
 Profile.java 

package splessons;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;

public class Profile {
   @Autowired
   @Qualifier("student1")
   private Student student;

   public Profile(){
      System.out.println("Inside Profile constructor." );
   }

   public void printAge() {
      System.out.println("Age : " + student.getAge() );
   }

   public void printName() {
      System.out.println("Name : " + student.getName() );
   }
}

 MainApp.java 

package splessons;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MainApp {
   public static void main(String[] args) {
      ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");

      Profile profile = (Profile) context.getBean("profile");

      profile.printAge();
      profile.printName();
   }
}

The Application Context is spring’s more best in class holder. Like BeanFactory it can stack bean definitions, wire beans together and administer beans upon solicitation. Also it includes more enterprise-specific usefulness, for example, the capacity to determine literary messages from a properties document and the capacity to distribute application events to interested event listeners. This container is characterized by the org.springframework.context.ApplicationContext interface.
 Beans.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/>

   <!-- Definition for profile bean -->
   <bean id="profile" class="splessons.Profile">
   </bean>

  <!-- Definition for student1 bean -->
   <bean id="student1" class="splessons.Student">
     <property name="name" value="sai" />
      <property name="age" value="22"/>
   </bean>

  
</beans>

Parameters have been passed from beans.xml file.
Output 

Inside Profile constructor.
Age : 22
Name : sai

@JSR-250 based annotation consists of @PostConstruct, @PreDestroy and @Resource annotations. these are the optional annotations because already developers have alternative annotations.

PostConstruct and PreDestroy Annotations

@PostConstruct annotation can be used as  introduction callback and @PreDestroy annotation can be used as destruction callback like as following

 HelloWorld.java 

package splessons;
import javax.annotation.*;

public class HelloWorld {
   private String message;

   public void setMessage(String message){
      this.message  = message;
   }

   public String getMessage(){
      System.out.println("Your Message : " + message);
      return message;
   }
   @PostConstruct
   public void init(){
      System.out.println("Bean is going through init.");
   }
   @PreDestroy
   public void destroy(){
      System.out.println("Bean will destroy now.");
   }
}

 MainApp.java 

Here registerShutdownHook() method should be declared on the AbstractApplicationContext class.

package splessons;

import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MainApp {
   public static void main(String[] args) {

      AbstractApplicationContext context = 
                          new ClassPathXmlApplicationContext("Beans.xml");

      HelloWorld obj = (HelloWorld) context.getBean("helloWorld");
      obj.getMessage();
      context.registerShutdownHook();
   }
}

The Application Context is spring’s more best in class holder. Like BeanFactory it can stack bean definitions, wire beans together and administer beans upon solicitation. Also it includes more enterprise-specific usefulness, for example, the capacity to determine literary messages from a properties document and the capacity to distribute application events to interested event listeners. This container is characterized by the org.springframework.context.ApplicationContext interface.
The configuration file Beans.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/>

   <bean id="helloWorld" class="splessons.HelloWorld" init-method="init" destroy-method="destroy">
       <property name="message" value="Hello World!"/>
  </bean>

</beans>

Output

Bean is going through init.
Your Message : Hello World!
Bean will destroy now.

Summary

  • By using Spring Annotations less code will be provided.
  • Prevention of more code line is possible with Annotation.
  • Lengthy XML code can be written as small with annotation .