Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Customised annotation in spring

Tags:

java

spring

I have seen few examples where customized annotations were used. example

@SimpleAnnotation
class SampleBean {
  @SimpleAnnotation
  public String getName() {
    return "AAA";
  }

  public void setName(String name) {
  }

  public int getHeight() {
    return 201;
  }
}

@Target( { ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@interface SimpleAnnotation {
}

Can anyone tell why we use this?

like image 238
Junaidaj Avatar asked Oct 21 '11 07:10

Junaidaj


People also ask

What are custom annotations?

Annotations provide an alternative to the use of XML descriptors. Also, we are able to attach them to packages, classes, interfaces, methods, and fields, annotations by themselves have no effect on the execution of a source code (Program).

What is custom annotation in Java?

Java annotations are a mechanism for adding metadata information to our source code. They're a powerful part of Java that was added in JDK5. Annotations offer an alternative to the use of XML descriptors and marker interfaces.


2 Answers

You can create your own meta-annotations that collect several other Spring annotations to reduce meta-boilerplate in your code:

@Service
@Scope(value = "prototype")
@Transactional(readOnly = true, rollbackFor = RuntimeException.class)
public @interface ReadOnlyService {}

And then you can simply write:

@ReadOnlyService
public class RoleService {

}

Spring will find the @ReadOnlyService and semantically replace it with:

@Service
@Scope(value = "prototype")
@Transactional(readOnly = true, rollbackFor = RuntimeException.class)
public class RoleService {

}

Of course having custom annotations pays of when you have tons of services annotated with the same set of Spring annotations that can be replaced with one, well named annotation.

Examples taken from: Avoid Spring Annotation Code Smell: Use Spring 3 Custom Annotations

like image 199
Tomasz Nurkiewicz Avatar answered Sep 30 '22 15:09

Tomasz Nurkiewicz


Spring supports for many Annotation the concept of "meta-annotation". (I am not sure if it is for all.)

This mean that you can build your own annotation and annotate the annotation with one of springs "core" annotations.

For example:

@Target({ ElementType.FIELD, ElementType.PARAMETER, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Service
public @interface MyService {

}

Then you can use this annotation instead of @Service. (Btw: @Service, @Repository, @Controller use the same technique to "inherit" from @Component)


One example that make heavy use of this is "inherit" from @Qualifier. For an example and some explanation have a look at Spring Reference Chapter: 3.9.3 Fine-tuning annotation-based autowiring with qualifiers (The Example with @Genre is at the end of the chapter.)

One very usefull construct that can be done with that technique is, that it enables you to combine several Annotations to a (in your use case) more meaning full. So instead of writing at every class of some type allways the same two annotations, for example: @Service and @Qualifiyer("someting") (the org.springframework.beans.factory.annotation.Qualifier). You can create your custom annotation that is annotated with this two annotations, and then use in your beans only this one custom annotation. (@See Avoid Spring Annotation Code Smell Use Spring 3 Custom Annotations)

If you want to see how powerfull this technique can be use, you can have a look at Context and Dependency Injection Framework.


Question from the comment:

The @interface also has some variables defined inside it, what does that signify?

The Annotations (defined by @Interface) work a bit like beans. This Fields are the properties that can/must be define if you use the annotations. The values can be later on be read via reflection API.

For example the @Controller Annotation in Spring:

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Controller {
   String value() default "";
}

The field with name value is that field that can be used without explicit name it: (@Controller("myUrl") is the same @Controller(value="myUrl"))

like image 29
Ralph Avatar answered Sep 30 '22 16:09

Ralph