Adding custom annotations to your java beans

Java annotations are syntactic meta-information that can be added to your Java source code. You can annotate classes, methods, variables, method parameters and even packages.

The great advantage of Java annotations over javadoc tags is that those bits of information can be reflective and thus they can be made available to the VM at runtime (using the the Java Relection API).

Other than this, modern Java frameworks (like Spring) make heavy use of annotations in order to let the developer, extend, inject data and configure existent behaviors.

In this article we will define our own custom annotations, and we will use reflection to analyze and enhance the behavior of our Java beans at run-time.

Let’s suppose we want to write a mechanism that transforms (let’s say serialize) a given collection of java beans instances to a CSV file .CSV stands for Comma Separated Values. If you want to learn more about CSV files please check out this wikipedia article.

We don’t want to “serialize” all the fields, so will use annotations to mark only the fields we wish to “export”.

The first step will be the write the annotations class. We will call this one CSVExport.java :

As you can see all annotations related classes are included in the java.lang.annotation.* package. Other than this we will need to mark this annotation with a RetentionPolicy that will make it available at run-time, and we will specify that the annotation can only be used in conjunction with class methods (in our case those methods will be the bean getters).

At this point we will write a “model” java bean and we will mark the getters we want to serialize with our newly defined custom annotation.

Only the method that were annotated with @CSVExport will be serialized to the resulting file. If no annotations is present the specified getter method will be ignored.

The next step will be to write the class that actual export our collection. We will call this one CollectionToCSV.java:

The most important method buildCSVRow , as it iterates through the methods of the T.class (where T appears as a generic type, but in our case will be a TestModel instance), checks if the getter is marked with the @CSVExport annotation, and if the answer is yes the method will be invoked and the result will be included in our serialization.

If we run the main method the result will be:

If in the TestModel class we remove all the getters annotations nothing will be exported.