Annotations

  • Helps to transfer some of the configuration from Java files to Java Classes.
  • In Spring we can configure URL mapping directly inside the controllers using @RequestMapping annotation.
  • This is done with the help of several utility classes like AnnotationUtils.
  • AnnotationUtils is used to handle various annotation operations.
    • It allows to check annotation at class,method and field level.
    • It is composed mainly of public and static methods.
    • It looks for annotation at superclass level and interface too
    • AnnotationUtils uses 3 elements of reflection API to deal with annotations.
      • Annotation: Represnts Annotation
      • AnnotationElement: represents annotated element.
      • Method: Provides information about a method in some class or interface.
Public methods of Annotation Utils class
      • getAnnotation
        • There are 3 forms of this method
          • first one takes in parameter as Annotation instance
          • second one takes in parameter as AnnotationElement instance
          • third one takes in parameter as Method Object.
        • All of them return annotation from a field,class or method
      • getRepeateableAnnotation
        • Accessible for Method or Annotated element passed in parameter.
        • 2 methods with this name exist.
        • They return the element on which annotation is present.
          • for example they can return the methods annotated with @RequestMapping annotation.
      • findAnnotation: looks for annotation in a method or Class object passed in parameter.
      • isAnnotationDeclaredLocally
        • checks if annotation is declared locally in class and is not inherited.
      • isAnnotationInherited
        • checks if Annotation is inherited from another class(i.e. not declared locally)
      • getAnnotationAttributes
        • get attributes of another annotation
      • getValue
        • gets the value of annotation
        • Two methods exist
          • first one returns global value of annotation
          • second one the value of specific annotation's parameters.
      • getDefaultValue
        • gets the default value of given annotation or annotation's attributes
Usage of Annotation Util Methods
  • web MVC
    • AnnotationMethodHandlerAdapter, used until 3.1 Spring's version as main handler for annotated method, uses AnnotationUtils to check different annotations available for methods level, like: @RequestMapping, @ResponseStatus, @ResponseBody or @ModelAttribute.
    • The AnnotationMethodHandlerAdapter successor, RequestMappingHandlerMapping, works with AnnotationUtils to resolve @RequestMapping and construct RequestMappingInfo object which encapsulates the mapping configuration (variables, HTTP methods, accepted headers etc.).
    • RequestMappingHandlerAdapter is the third important class of web MVC project which uses AnnotationUtils. It invokes findAnnotation() method in 2 public singletons, both are instances of MethodFilter class. One represents @InitBinder annotation and the second @ModelAttribute.
  • web
    • HandlerMethodInvoker uses AnnotationUtils to know what is the meanning of @ModelAttribute annotation, if the object must be validated with @Valid or if the @InitBinder method is present.
    • Another key class of this project, HandlerMethodResolver, calls AnnotationUtils method to determine the type of method (handler, binder or model-attribute oriented). It accomplishes it through 3 methods: isHandlerMethod, isInitBinderMethod and isModelAttributeMethod. Each takes in parameter the Method's instance.
  • context
    • The utilitary class for parsing beans annotations, BeanAnnotationHelper, uses findAnnotation() method from AnnotationUtils to deal with classes annotated with @Bean. The helper uses it for example, to determine the bean's name.
    • One more class at this level, AnnotationAsyncExecutionInterceptor, employs AnnotationUtils to resolve an annotation. It invokes findAnnotation() method to resolve the name of method executed at runtime.
  • beans
    • AnnotationUtils is used here to retrieve annotations for beans. We can find these uses in StaticListableBeanFactory or DefaultListableBeanFactory classes.
In the example below we have created some Custom Annotations and Classes referring them.Then we are using AnnotationUtils to get Annotations on Class and Inherited Class.

Custom Annotations
StaticTextAnnotation.java
 package com.springimplant.mvc.annotations;  
 import java.lang.annotation.ElementType;  
 import java.lang.annotation.Retention;  
 import java.lang.annotation.RetentionPolicy;  
 import java.lang.annotation.Target;  
 @Retention(RetentionPolicy.RUNTIME)  
 @Target({ElementType.METHOD})  
 public @interface StaticTextAnnotation {  
       String text() default "Default text for static text annotation";  
       String value() default "Default value";  
 }  
ClassNameAnnotation.java
 package com.springimplant.mvc.annotations;  
 import java.lang.annotation.ElementType;  
 import java.lang.annotation.Retention;  
 import java.lang.annotation.RetentionPolicy;  
 import java.lang.annotation.Target;  
 @Retention(RetentionPolicy.RUNTIME)  
 @Target({ElementType.TYPE})  
 public @interface ClassNameAnnotation {  
      String className() default "Empty class name";  
 }  

Classes implementing Annotations

AnnotationParent.java
 package com.springimplant.mvc.entity;  
 import javax.servlet.http.HttpServletRequest;  
 import com.springimplant.mvc.annotations.ClassNameAnnotation;  
 import com.springimplant.mvc.annotations.StaticTextAnnotation;  
 @ClassNameAnnotation(className="TestChildren")  
 public class AnnotationParent {  
      @StaticTextAnnotation(value= "Custom text value", text = "Test text")  
       public String test(HttpServletRequest request) {  
        return "test";  
       }  
 }  
AnnotationChildren.java
 package com.springimplant.mvc.entity;  
 public class AnnotationChildren extends AnnotationParent {  
 }  

PlayController.java
 package com.springimplant.mvc.controllers;  
 import java.lang.annotation.Annotation;  
 import java.lang.reflect.Method;  
 import javax.servlet.http.HttpServletRequest;  
 import org.springframework.core.annotation.AnnotationUtils;  
 import org.springframework.stereotype.Controller;  
 import org.springframework.web.bind.annotation.RequestMapping;  
 import com.springimplant.mvc.annotations.ClassNameAnnotation;  
 import com.springimplant.mvc.annotations.StaticTextAnnotation;  
 import com.springimplant.mvc.entity.AnnotationChildren;  
 import com.springimplant.mvc.entity.AnnotationParent;  
 @Controller  
 @RequestMapping("/play")  
 public class PlayController {  
      @RequestMapping("/annotation")  
      public String annotationTest()  
      {  
           try {  
                Method method=AnnotationParent.class.getMethod("test",new Class[]{HttpServletRequest.class});  
                Annotation staticTextAnnot=AnnotationUtils.findAnnotation(method,StaticTextAnnotation.class);  
                System.out.println("@StaticTextAnnotation of method is: "+staticTextAnnot);  
             System.out.println("@StaticTextAnnotation method value: "+AnnotationUtils.getValue(staticTextAnnot, "text"));  
             System.out.println("@StaticTextAnnotation method default value: "+AnnotationUtils.getDefaultValue(staticTextAnnot, "text"));  
             System.out.println("@StaticTextAnnotation value: "+AnnotationUtils.getValue(staticTextAnnot));  
             // inheriting annotations tests  
             Annotation classNameAnnotation = AnnotationUtils.findAnnotation(AnnotationChildren.class, ClassNameAnnotation.class);  
             System.out.println("@ClassNameAnnotation of TestChildren.class is: "+classNameAnnotation);  
             System.out.println("@ClassNameAnnotation method value: "+AnnotationUtils.getValue(classNameAnnotation, "className"));  
             System.out.println("@ClassNameAnnotation method default value: "+AnnotationUtils.getDefaultValue(classNameAnnotation, "className"));  
             System.out.println("@ClassNameAnnotation value: "+AnnotationUtils.getValue(classNameAnnotation));  
           } catch (NoSuchMethodException e) {  
                // TODO Auto-generated catch block  
                e.printStackTrace();  
           } catch (SecurityException e) {  
                // TODO Auto-generated catch block  
                e.printStackTrace();  
           }  
           return "annotation";  
      }  
 }  

dsfds 

No comments:

Post a Comment

Spring Boot

What is circular/cyclic dependency in spring boot? When two services are interdependent on each other, that is to start one service, we requ...