spring annotation inheritance

@Autowired/@Inject (method)

When you use @Inherited on a class annotation, this means that when that annotation is queried on a non-annotated subclass, the Java will look for it in the superclass.

When you use @Inherited on a method annotation, this means that when that annotation is queried on a non-annotated method overridden in subclass, Java will look for it in the superclass.

If your setter method is annotated with @Autowired on the superclass, but the setter method is not overridden in subclass (which is usually the case), the annotation does not need to be @Inherited to be found when you look for annotated methods into the subclass.

Spring looks for all annotated setter methods in the class hierarchy. If a setter is annotated with @Autowired in the superclass and is overridden in the subclass without the @Autowired annotation, then Spring will not detect it and will not inject the dependency.

Code:
class A {
  @Autowired setFirst(First f) {}
  @Autowired setSecond(Second s) {}
}

class B extends A {
  @Overrides setFirst(First f) {}
}

In a bean definition declared as A, both setFirst() and setSecond() will be invoked, while in a bean definition declared as B, only setSecond() will be invoked, because setFirst() is overridden without @Autowired.
This behaviour is not spring-related, but java-related.

@Transactional(class/method)

the @Transactionalannotation has @Inherited.

From the docs:

Indicates that an annotation type is automatically inherited. If an Inherited meta-annotation is present on an annotation type declaration, and the user queries the annotation type on a class declaration, and the class declaration has no annotation for this type, then the class’s superclass will automatically be queried for the annotation type. This process will be repeated until an annotation for this type is found, or the top of the class hierarchy (Object) is reached. If no superclass has an annotation for this type, then the query will indicate that the class in question has no such annotation.

Note that this meta-annotation type has no effect if the annotated type is used to annotate anything other than a class. Note also that this meta-annotation only causes annotations to be inherited from superclasses; annotations on implemented interfaces have no effect.

Docs of @Transactional:

@Target(value={METHOD,TYPE})
@Retention(value=RUNTIME)
@Inherited
@Documented
public @interface Transactional
Advertisements

How do Annotations Work In Java?

Basically, annotations are just markers which are read by the compiler or the application. Depending on their retention policy they are available at compile time only or are readable at runtime using reflection.

Many frameworks use runtime retention, i.e. they reflectively check whether some annotations are present on a class, method, field etc. and do something if the annotation is present (or not). Additionally, members of annotations can be used to pass further information.

What are Annotations ?

One word to explain Annotation is Metadata. Metadata is data about data. So Annotations are metadata for code. For example look at following piece of code.

1.@Override
2.public String toString() {
3.return "This is String Representation of current object.";
4.}

I have overridden the toString() method and used @Override annotation in above code. Even if I don’t put @Override, code works properly without any issue. So what’s the advantage and what does this annotation stand for? @Override tells the compiler that this method is an overridden method (metadata about method) and if any such method does not exist in parent class, then throw a compiler error (method does not override a method from its super class). Now if I would have made a typography mistake and used method name as toStrring() {double r} and if I wouldn’t have used @Override, my code would have compiled and executed successfully but outcome would be different from what I would have accepted. So now we understand what annotations are but still it’s good to read formal definitions

Annotation is special kind of Java construct used to decorate a class, method, field, parameter, variable, constructor, or package. It’s the vehicle chosen by JSR-175 to provide metadata.

Why Were Annotations Introduced?

Prior to annotation (and even after) XML were extensively used for metadata and somehow a particular set of Application Developers and Architects thought XML maintenance was getting troublesome. They wanted something which could be coupled closely with code instead of XML which is very loosely coupled (in some cases almost separate) from code. If you google “XML vs. annotations”, you will find a lot of interesting debates. Interesting point is XML configurations were introduced to separate configuration from code. Last two statements might create a doubt in your mind that these two are creating a cycle, but both have their pros and cons. Let’s try to understand with an example.

Suppose, you want to set some application wide constants/parameters. In this scenario, XML would be a better choice because this is not related with any specific piece of code. If you want to expose some method as a service, annotation would be a better choice as it needs to be tightly coupled with that method and developer of the method must be aware of this.

Another important factor is that annotation defines a standard way of defining metadata in code. Prior to annotations people also used their own ways to define metadata. Some examples are – using marker interfaces, comments, transient keywords etc. Each developer decided his own way to decide metadata, but annotation standardized things.

These days most frameworks use combination of both XML and Annotations to leverage positive aspects of both.

How Annotations Work and How to Write Custom Annotations

Before I start this explanation, I will suggest you download this sample code for annotations (AnnotationsSample.zip) and keep that open in any IDE of your choice, as it will help you to understand following explanation better.

Writing annotations is very simple. You can compare annotation definition to an interface definition. Let’s have a look at two examples – One is standard @Override annotation and second is a custom annotation @Todo

1.@Target(ElementType.METHOD)
2.@Retention(RetentionPolicy.SOURCE)
3.public @interface Override {
4.}

Something seems fishy about @Override, it’s not doing anything, how it checks if a method is defined in parent class. Well, don’t be surprised, I am not kidding you. Override annotation’s definition has that much code only. This is the most important part to understand and I am reiterating myself – Annotations are only metadata and they do not contain any business logic. Tough to digest but true. If annotations do not contain the logic than someone else must be doing something and that someone is consumer of this annotation metadata. Annotations only provide some information about the attribute (class/method/package/field) on which it is defined. Consumer is a piece of code which reads this information and then performs necessary logic.

When we are talking about standard annotations like @Override – JVM is the consumer and it works at bytecode level. Now that’s something application developers can’t control and can’t use for custom annotations. So we need to write consumers for our annotations by ourselves.

Let’s understand the key terms used for writing annotations one by one. In the above examples, you will see annotations are used on annotations.

J2SE 5.0 provides four annotations in the java.lang.annotation package that are used only when writing annotations:

@Documented – Whether to put the annotation in Javadocs

@Retention – When the annotation is needed

@Target? – Places the annotation can go

@Inherited – Whether subclasses get the annotation.

@Documented – A simple market annotations which tells whether to add Annotation in java doc or not.

@Retention – Defines for how long the annotation should be kept.

RetentionPolicy.SOURCE – Discard during the compile. These annotations don’t make any sense after the compile has completed, so they aren’t written to the bytecode. Examples @Override, @SuppressWarnings
RetentionPolicy.CLASS – Discard during class load. Useful when doing bytecode-level post-processing. Somewhat surprisingly, this is the default.
RetentionPolicy.RUNTIME – Do not discard. The annotation should be available for reflection at runtime. This is what we generally use for our custom annotations.

@Target – Where annotation can be placed. If you don’t specify this, annotation can be placed anywhere. Following are the valid values. One important point here is, it’s inclusive only which means if you want annotation on 7 attributes and just want to exclude only one attribute, you need to include all 7 while defining target.

ElementType.TYPE (class, interface, enum)

ElementType.FIELD (instance variable)

ElementType.METHOD

ElementType.PARAMETER

ElementType.CONSTRUCTOR

ElementType.LOCAL_VARIABLE

ElementType.ANNOTATION_TYPE (on another annotation)

ElementType.PACKAGE (remember package-info.java)

@Inherited – Controls whether annotation should affect subclass.

Now what goes inside an annotation definition? Annotations only support primitives, string and enumerations. All attributes of annotations are defined as methods and default values can also be provided

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@interface Todo {
public enum Priority {LOW, MEDIUM, HIGH}
public enum Status {STARTED, NOT_STARTED}
String author() default "Yash";
Priority priority() default Priority.LOW;
Status status() default Status.NOT_STARTED;
}

Following is an example of how the above annotation can be used

@Todo(priority = Todo.Priority.MEDIUM, author = "Yashwant", status = Todo.Status.STARTED)
public void incompleteMethod1() {
//Some business logic is written
//But it’s not complete yet
}

If we have only one attribute inside an annotation, it should be named “value” and can be used without attribute name while using it.

@interface Author{
String value();
}
@Author("Yashwant")
public void someMethod() {
}

So far so good. We have defined our custom annotation and applied it to some business logic methods. Now it’s time to write a consumer. For that we will need to use Reflection. If you are familiar with Reflection code, you know reflection provides Class, Method and Field objects. All of these have a getAnnotation() method which returns the annotation object. We need to cast this object as our custom annotation (after checking with instanceOf()) and then we can call methods defined in our custom annotation. Let’s look at the sample code, which uses above annotation:

Class businessLogicClass = BusinessLogic.class;
for(Method method : businessLogicClass.getMethods()) {
Todo todoAnnotation = (Todo)method.getAnnotation(Todo.class);
if(todoAnnotation != null) {
System.out.println(" Method Name : " + method.getName());
System.out.println(" Author : " + todoAnnotation.author());
System.out.println(" Priority : " + todoAnnotation.priority());
System.out.println(" Status : " + todoAnnotation.status());
}
}

FROM HERE

A spring AOP way of doing custom annotation

Spring MVC – @RequestBody and @ResponseBody

In this post i want to dig into spring mvc a little, revealing what happens behind the scenes when a request is converted to your parameter object and vice versa. Before we start, i want to explain the purpose of these annotations.

What are @RequestBody and @ResponseBody for?

They are annotations of the spring mvc framework and can be used in a controller to implement smart object serialization and deserialization. They help you avoid boilerplate code by extracting the logic of messageconversion and making it an aspect. Other than that they help you support multiple formats for a single REST resource without duplication of code. If you annotate a method with @ResponseBody, spring will try to convert its return value and write it to the http response automatically. If you annotate a methods parameter with @RequestBody, spring will try to convert the content of the incoming request body to your parameter object on the fly.

Here is an example

@Controller
@RequestMapping(value = "/bookcase")
public class BookCaseController {

    private BookCase bookCase;

    @RequestMapping(method = RequestMethod.GET)
    @ResponseBody
    public BookCase getBookCase() {
        return this.bookCase;
    }

    @RequestMapping(method = RequestMethod.PUT)
    @ResponseStatus(HttpStatus.NO_CONTENT)
    public void setBookCase(@RequestBody BookCase bookCase) {
        this.bookCase = bookCase;
    }

}

So what is Spring doing behind the scenes when we are using those Annotations?

Depending on your configuration, spring has a list of HttpMessageConverters registered in the background. A HttpMessageConverters responsibility is to convert the request body to a specific class and back to the response body again, depending on a predefined mime type. Every time an issued request is hitting a @RequestBody or @ResponseBody annotation spring loops through all registered HttpMessageConverters seeking for the first that fits the given mime type and class and then uses it for the actual conversion.

How can i add a custom HttpMessageConverter?

By adding @EnableWebMvc respectively <mvc:annotation-driven />, spring registers a bunch of predefined messageconverters for JSON/XML and so on. You can add a custom converter like the following

 

 

@Configuration
@EnableWebMvc
@ComponentScan
public class WebConfiguration extends WebMvcConfigurerAdapter {

    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> httpMessageConverters) {
        httpMessageConverters.add(new BookCaseMessageConverter(new MediaType("text", "csv")));
    }
}

 

In this example i’ve written a converter that handles the conversion of a BookCase, which is basically a List of Books. The converter is able to convert csv content to a BookCase and vice versa. I used opencsv to parse the text.

Here is the model

public class Book {

    private String isbn;

    private String title;

    public Book(String isbn, String title) {
        this.isbn = isbn;
        this.title = title;
    }

    // ...
}

public class BookCase extends ArrayList<Book> {

    public BookCase() {
    }

    public BookCase(Collection<? extends Book> c) {
        super(c);
    }
}

and the actual converter

public class BookCaseMessageConverter extends AbstractHttpMessageConverter<BookCase> {

    public BookCaseMessageConverter() {
    }

    public BookCaseMessageConverter(MediaType supportedMediaType) {
        super(supportedMediaType);
    }

    public BookCaseMessageConverter(MediaType... supportedMediaTypes) {
        super(supportedMediaTypes);
    }

    @Override
    protected boolean supports(Class<?> clazz) {
        return BookCase.class.equals(clazz);
    }

    @Override
    protected BookCase readInternal(Class<? extends BookCase> clazz, HttpInputMessage httpInputMessage) throws IOException, HttpMessageNotReadableException {
        CSVReader reader = new CSVReader(new InputStreamReader(httpInputMessage.getBody()));
        List<String[]> rows = reader.readAll();
        BookCase bookCase = new BookCase();
        for (String[] row : rows) {
            bookCase.add(new Book(row[0], row[1]));
        }
        return bookCase;
    }

    @Override
    protected void writeInternal(BookCase books, HttpOutputMessage httpOutputMessage) throws IOException, HttpMessageNotWritableException {
        CSVWriter writer = new CSVWriter(new OutputStreamWriter(httpOutputMessage.getBody()));
        for (Book book : books) {
            writer.writeNext(new String[]{book.getIsbn(), book.getTitle()});
        }
        writer.close();
    }
}

The Result

We can now issue text/csv requests to our Resource along with application/json and xml which are basically supported out of the box.

 

 

PUT /bookcase
Content-Type: text/csv
"123","Spring in Action"
"456","Clean Code"

Response
204 No Content



GET /bookcase
Accept: text/csv

Response
200 OK
"123","Spring in Action"
"456","Clean Code"

Thanks to the design of spring mvc, which is following the single responsibility principle, our controller stays thin. We don’t have to add a single line if we want to support new media types.

FROM HERE

@Inject and @Autowired

@Inject is part of the Java CDI standard introduced in Java EE 6 (JSR-299), read more. Spring has choosen to support using@Inject synonymously with their own @Autowired annotation.

So, to answer your question, @Autowired is springs own (legacy) annotation. @Inject is part of a new Java technology called CDI that defines a standard for dependency injection similar to Spring. In a spring application, the two annotations works the same way as Spring has decided to support some JSR-299 annotations in addition to their own.