Vous êtes sur la page 1sur 41

JAVA Annotation

Problem [1]
public class Person {
private String name;

public String getName() {
return name;
}

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

public static void main(String[] args) {
Person p = new Person();
p.setName("Daniel");
System.out.println("Name: "+p.getName());
}
}
Problem [2]
@Data
public class Person {
private String name;

public static void main(String[] args) {
Person p = new Person();
p.setName("Daniel");
System.out.println("Name:
"+p.getName());
}
}
Problem [3]
public class MyUtils
{
private static final Logger log =
LoggerFactory.getLogger(MyUtils.class);

public void myAlgorithm()
{
log.info("This is my algorithm.");
}
}
Problem [4]
@Slf4j
public class MyUtils
{
public void myAlgorithm()
{
log.info("This is my algorithm.");
}
}
Goal
Understanding how to Annotate.
Understanding how annotation
preprocessor work.
Understanding how Project Lombok
work.

Definition
Anotasi adalah catatan yg dibuat oleh
pengarang atau orang lain untuk
menerangkan, mengomentari, atau
mengkritik teks karya sastra atau
bahan tertulis lain. (KBBI)
A note by way of explanation or
comment added to a text or diagram.
(Oxford Dictionary)
Introduction
An annotation, in the Java computer
programming language, is a form of
syntactic metadata that can be added to
Java source code.
Classes, methods, variables, parameters
and packages may be annotated.
Java annotations can be reflective in that
they can be embedded in class files
generated by the compiler and may be
retained by the Java VM to be made
retrievable at run-time.
Annotation Example
@API
package com.djph.annotation.lombok1;

@Entity
public class MyObject
{
@NotNull
private String name;

@Autowired
public MyObject()
{
}

@Transactional
public void myMethod(@Valid Object obj)
{
}
}
History [1]
The Java platform has various ad-hoc
annotation mechanismsfor example,
the transient modifier, or the
@deprecated javadoc tag.
The general purpose annotation (also
known as metadata) facility was
introduced to the Java Community
Process as JSR-175 in 2002 and
approved in September 2004.
History [2]
Annotations became available in the
language itself beginning with version
1.5 of the JDK.
A provisional interface for compile-
time annotation processing was
provided by the apt tool in JDK version
1.5, and was formalized through JSR-
269 and integrated into the javac
compiler in version 1.6.
Built-in annotations [1]
Annotations applied to Java code:
@Override
@Deprecated
@SuppressWarnings
@SafeVarargs (Since Java 7)
@FunctionalInterface (Since Java 8)
Built-in annotations [2]
Annotations applied to other
annotations:
@Retention
@Documented
@Target
@Inherited
@Repeatable (Since Java 8)
Built-in annotations (Example)
public class MyObject
{
@Override
public String toString()
{
return "MyObject{"+'}';
}
}
Custom annotations
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target
({
ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR,
ElementType.FIELD, ElementType.LOCAL_VARIABLE,
ElementType.METHOD, ElementType.PACKAGE,
ElementType.PARAMETER, ElementType.TYPE
})
@Retention(RetentionPolicy.RUNTIME) //RetentionPolicy.CLASS,
RetentionPolicy.RUNTIME
public @interface MyAnnotation
{
String value();
}
Custom annotation (Note) [1]
In annotations with a single element,
the element should be named value.


If there is just one element named
value, then the name can be omitted.
public @interface MyAnnotation {
String value();
}
@MyAnnotation(Im value of element value.")
public class MyObject { ... }
Custom annotation (Note) [2]
If no values, then no parentheses
needed.



It is also possible to use multiple
annotations on the same declaration.
public @interface NoValue { }

@NoValue
public class MyObject { ... }
@Author(name = "Jane Doe")
@EBook
class MyClass { ... }
Custom annotation (Note) [3]
If the annotations have the same type,
then this is called a repeating
annotation. Repeating annotations are
supported as of the Java SE 8
release.


@Author(name = "Jane Doe")
@Author(name = "John Smith")
class MyClass { ... }
Where Annotations Can Be Used
in Java 8
Class instance creation expression:

Type cast:

implements clause:

Thrown exception declaration:


new @Interned MyObject();
myString = (@NonNull String) str;
class UnmodifiableList<T> implements
@Readonly List<@Readonly T> { ... }
void monitorTemperature() throws
@Critical TemperatureException { ... }
Access Annotations using
Reflection
Class clazz = MyObject.class;
Annotation[] atType = clazz.getAnnotations();
Annotation[] atField =
clazz.getField("myField").getAnnotations();
Annotation[] atMethod = clazz.getMethod("myMethod",
parameterTypes).getAnnotations();
Annotation Processor at Runtime
[1]
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface NotNull {
}
public class MyEntity {
@NotNull
public String name;
}
Annotation Processor at Runtime
[2]
public class NotNullProcessor {
public void validate(Object obj) throws Exception {
Class clazz = obj.getClass();
Field[] fields = clazz.getDeclaredFields();
for(Field field : fields) {
field.setAccessible(true);
Annotation annotation =
field.getAnnotation(NotNull.class);
if(annotation!=null) {
Object objValue = field.get(obj);
if(objValue==null) {
throw new RuntimeException("Attribute
'"+field.getName()+"' cannot be null.");
}
}
}
}
}
Annotation Processor at Runtime
[3]
public class NotNullProcessorTest {
public static void main(String[] args) throws Exception {
MyEntity e1 = new MyEntity();
e1.name = "Daniel";

MyEntity e2 = new MyEntity();
e2.name = null;

NotNullProcessor nnp = new NotNullProcessor();
nnp.validate(e1);
System.out.println("Object e1 valid.");
nnp.validate(e2);
}
}
Annotation Processor at Runtime
[4]
Object e1 valid.
Exception in thread "main"
java.lang.RuntimeException: Attribute 'name'
cannot be null.
at
com.djph.annotation.rtprocessor.NotNullProcesso
r.validate(NotNullProcessor.java:20)
at
com.djph.annotation.rtprocessor.NotNullProcesso
rTest.main(NotNullProcessorTest.java:18)
Annotation Processing Tool
(apt)
The apt tool is a command-line utility for
annotation processing.
It includes a set of reflective APIs and
supporting infrastructure to process program
annotations (JSR 175).
The apt tool first runs annotation processors
that can produce new source code and other
files.
JSR 269 support (JDK 6), javac now acts
analogously to the apt command in JDK 5.
The apt tool and its associated API contained
in the package com.sun.mirror have been
deprecated since Java SE 7.

Create Annotation
Preprocessor
@SupportedAnnotationTypes({"*"})
@SupportedSourceVersion(SourceVersion.RELEAS
E_7)
public class SimpleProcessor extends
AbstractProcessor
{
@Override
public boolean process(Set<? extends
TypeElement> annotations, RoundEnvironment
roundEnv)
{
return false;
}
}
Create Annotation Preprocessor
(Note)
Set<? extends Element> elements =
roundEnv.getElementsAnnotatedWith(MyAnnotation.class);
TypeElement te = (TypeElement) element;
PackageElement pe = (PackageElement)
te.getEnclosingElement();
String packageLocation = pe.getQualifiedName().toString();
String sourceFile = te.getQualifiedName().toString()+'_';
Filer filer = processingEnv.getFiler();
JavaFileObject javaFileObject = filer.createSourceFile(sourceFile);
Writer writer = javaFileObject.openWriter();
processingEnv.getMessager().printMessage(Diagnostic.Kind.NOT
E, "Processing annotation done.");
Use for??? [1]
Create custom javadoc.
Create web service document.

Use for??? [2]
public class Employee {
private Double salary;
{...Setter...} {...Getter...}
}
Criteria cr = session.createCriteria(Employee.class);
cr.add(Restrictions.eq("salary", 2000));
List results = cr.list();
public class Employee_ {
public static final String salary = "salary";
}
Criteria cr = session.createCriteria(Employee.class);
cr.add(Restrictions.eq(Employee_.salary, 2000));
List results = cr.list();
Only that???
Context context = ((JavacProcessingEnvironment)
processingEnv).getContext();

TreeMaker treeMaker = TreeMaker.instance(context);

JavacElements elementUtils = (JavacElements)
processingEnv.getElementUtils();

JCTree.JCClassDecl classDecl = (JCTree.JCClassDecl)
elementUtils.getTree(element);
How javac work after JDK
1.5???
AST
Modify AST Example
methodDecl.body = treeMaker.Block(0, List.of(
treeMaker.Exec(
treeMaker.Apply(
List.<JCTree.JCExpression>nil(),
treeMaker.Select(
treeMaker.Select(
treeMaker.Ident(elementUtils.getName("System")),
elementUtils.getName("out")
),
elementUtils.getName("println")
),
List.<JCTree.JCExpression>of(
treeMaker.Literal("Hello, world!!!")
)
)
),
methodDecl.body
));
How to run???
Using apt processor (JDK 1.5)
Using javac processor (JDK 1.6)
Create file
javax.annotation.processing.Processo
r that contains all processor class,
separate by new line at folder META-
INF.services
Project Lombok
Project Lombok is annotation
processor compiler plugin for javac
that provides a handful of very
focused annotations for your classes
to generate you highly optimized
implementations of some of the most
common boilerplate code that Java
developer needs.
Created by Reinier Zwitserloot & Roel
Spilker.
How Project Lombok work???
Use for?
@Data
public class Person {
private String name;

public static void main(String[] args) {
Person p = new Person();
p.setName("Daniel");
System.out.println("Name:
"+p.getName());
}
}
Project Lombok Annotation
@Data
@Getter / @Setter
@ToString
@val
@Log
Trick or Hack???
The annotation processing spec
doesn't allow you to modify existing
classes.
The annotation processing API doesn't
provide a mechanism for changing the
AST of a class.
Disadvantages
Debug
WYSIWYG
Time Bomb
Thank You

Vous aimerez peut-être aussi