Slide 1

Slide 1 text

Anotações Java Além da Reflexão Wellington Costa Pereira

Slide 2

Slide 2 text

Wellington Costa Pereira ● +4 anos de experiência ● Mestrando em Ciências da Computação (UECE) ● Programar é vida! ● Open source <3 ● Compartilhar conhecimento <3 Github: https://github.com/WellingtonCosta Linkedin: https://www.linkedin.com/in/wellingtoncosta128 Email: [email protected]

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

Sem mais delongas...

Slide 5

Slide 5 text

No content

Slide 6

Slide 6 text

Anotações?

Slide 7

Slide 7 text

Anotações Introduzida na versão 5 do Java, as anotações, ou Annotations, são uma forma de representar metadados que podem vir a serem interpretados por um compilador, visando realizar alguma ação a partir desses metadados. As annotations também podem servir como uma forma para substituição das tradicionais configurações baseadas em XML ou até mesmo para geração de arquivos, muitas vezes arquivos de código-fonte.

Slide 8

Slide 8 text

Lombok @ToString @EqualsAndHashCode public class Pessoa { @Getter @Setter private Long id; @Getter @Setter private String nome; @Getter @Setter private String email; @Getter @Setter private String telefone; }

Slide 9

Slide 9 text

JPA @Entity @Table(name = "tb_pessoa") public class Pessoa { @Id private Long id; @Column private String nome; @Column private String email; @Column private String telefone; }

Slide 10

Slide 10 text

Spring @RestController @RequestMapping("/api/pessoas") public class PessoaController { @GetMapping public List listarTodos() { // … } }

Slide 11

Slide 11 text

Butter Knife public class PessoaActivity extends Activity { @BindView(R.id.nome) TextView nome; @BindView(R.id.email) TextView email; @BindView(R.id.telefone) TextView telefone; @Override protected void onCreate(Bundle savedInstance) { // … ButterKnife.inject(this); } }

Slide 12

Slide 12 text

Java 5

Slide 13

Slide 13 text

Java 5

Slide 14

Slide 14 text

Java 5 ● JSR 14: Generics ● JSR 175: Annotations ● JSR 201: ○ Autoboxing / Unboxing ○ Enumerations ○ Static Imports ○ Enhanced For Loops ● apt command-line tool ● Dentre outras funcionalidades bacanas!

Slide 15

Slide 15 text

JSR 269 ● 6 meses após o lançamento do Java 5 ● “Pluggable Annotation Processing API” ● Google, Oracle, dentre outras organizações patrocinaram ● Simplificar e padronizar o processamento de anotações ● Agora o apt faz parte do javac

Slide 16

Slide 16 text

Componentes

Slide 17

Slide 17 text

Componentes ● Annotation ● Processor ● APT (Annotation Processing Tool) ● Annotated Elements

Slide 18

Slide 18 text

Annotation

Slide 19

Slide 19 text

@Target(ElementType.TYPE) @Retention(RetentionPolicy.SOURCE) public @interface HelloWorld { }

Slide 20

Slide 20 text

@Target(ElementType.TYPE) @Retention(RetentionPolicy.SOURCE) public @interface HelloWorld { }

Slide 21

Slide 21 text

@Target(ElementType.TYPE) @Retention(RetentionPolicy.SOURCE) public @interface HelloWorld { }

Slide 22

Slide 22 text

@Target(ElementType.TYPE) @Retention(RetentionPolicy.SOURCE) public @interface HelloWorld { }

Slide 23

Slide 23 text

Processor

Slide 24

Slide 24 text

interface Processor { Set getSupportedOptions(); Set getSupportedAnnotationTypes(); SourceVersion getSupportedSourceVersion(); void init(ProcesssingEnvironment processingEnv); boolean process(Set annotations, RoundEnvironment env); Iterable getCompletions(Element element, AnnotationMirror annotation, ExecutableElement member, String userText); }

Slide 25

Slide 25 text

interface Processor { Set getSupportedOptions(); Set getSupportedAnnotationTypes(); SourceVersion getSupportedSourceVersion(); void init(ProcesssingEnvironment processingEnv); boolean process(Set annotations, RoundEnvironment env); Iterable getCompletions(Element element, AnnotationMirror annotation, ExecutableElement member, String userText); }

Slide 26

Slide 26 text

Processing Environment

Slide 27

Slide 27 text

interface ProcessingEnvironment { Map getOptions(); SourceVersion getSourceVersion(); Locale getLocale(); Messager getMessager(); Filer getFiler(); Elements getElementUtils(); Types getTypeUtils(); }

Slide 28

Slide 28 text

interface ProcessingEnvironment { Map getOptions(); SourceVersion getSourceVersion(); Locale getLocale(); Messager getMessager(); Filer getFiler(); Elements getElementUtils(); Types getTypeUtils(); }

Slide 29

Slide 29 text

Elements? Types?

Slide 30

Slide 30 text

Elements public class HelloClass implements Runnable { private final String name; public HelloClass(String name) { this.name = name; } @Override public void run() { System.out.println(“Hello, ” + name); } }

Slide 31

Slide 31 text

public class HelloClass implements Runnable { TypeElement private final String name; public HelloClass(String name) { this.name = name; } @Override public void run() { System.out.println(“Hello, ” + name); } } Elements

Slide 32

Slide 32 text

public class HelloClass implements Runnable { TypeElement private final String name; VariableElement public HelloClass(String name) { this.name = name; } @Override public void run() { System.out.println(“Hello, ” + name); } } Elements

Slide 33

Slide 33 text

public class HelloClass implements Runnable { TypeElement private final String name; VariableElement public HelloClass(String name) { this.name = name; ExecutableElement } @Override public void run() { System.out.println(“Hello, ” + name); } } Elements

Slide 34

Slide 34 text

public class HelloClass implements Runnable { TypeElement private final String name; VariableElement public HelloClass(String name) { this.name = name; ExecutableElement } @Override public void run() { System.out.println(“Hello, ” + name); ExecutableElement } } Elements

Slide 35

Slide 35 text

public class HelloClass implements Runnable { private final String name; public HelloClass(String name) { this.name = name; } @Override public void run() { System.out.println(“Hello, ” + name); } } Types

Slide 36

Slide 36 text

public class HelloClass implements Runnable { private final String name; public HelloClass(String name) { this.name = name; } @Override public void run() { System.out.println(“Hello, ” + name); } } Types

Slide 37

Slide 37 text

public class HelloClass implements Runnable { private final String name; public HelloClass(String name) { this.name = name; } @Override public void run() { System.out.println(“Hello, ” + name); } } Types

Slide 38

Slide 38 text

public class HelloClass implements Runnable { private final String name; public HelloClass(String name) { this.name = name; } @Override public void run() { System.out.println(“Hello, ” + name); } } Types

Slide 39

Slide 39 text

public class HelloClass implements Runnable { private final String name; public HelloClass(String name) { this.name = name; } @Override public void run() { System.out.println(“Hello, ” + name); } } Types

Slide 40

Slide 40 text

public class HelloClass implements Runnable { private final String name; public HelloClass(String name) { this.name = name; } @Override public void run() { System.out.println(“Hello, ” + name); } } Types

Slide 41

Slide 41 text

Criando nosso Processor

Slide 42

Slide 42 text

public class HelloWorldProcessor extends AbstractProcessor { }

Slide 43

Slide 43 text

public class HelloWorldProcessor extends AbstractProcessor { @Override public SourceVersion getSupportedSourceVersion() { return SourceVersion.latestSupported(); } }

Slide 44

Slide 44 text

public class HelloWorldProcessor extends AbstractProcessor { @Override public SourceVersion getSupportedSourceVersion() { return SourceVersion.latestSupported(); } @Override public Set getSupportedAnnotationTypes() { return Collections.singleton(HelloWorld.class.getName()); } }

Slide 45

Slide 45 text

public class HelloWorldProcessor extends AbstractProcessor { @Override public SourceVersion getSupportedSourceVersion() { return SourceVersion.latestSupported(); } @Override public Set getSupportedAnnotationTypes() { return Collections.singleton(HelloWorld.class.getName()); } @Override public boolean process( Set annotations, RoundEnvironment env) { } }

Slide 46

Slide 46 text

public class HelloWorldProcessor extends AbstractProcessor { // . . . @Override public boolean process( Set annotations, RoundEnvironment env) { } }

Slide 47

Slide 47 text

public class HelloWorldProcessor extends AbstractProcessor { // . . . @Override public boolean process( Set annotations, RoundEnvironment env) { Set elements = env.getElementsAnnotatedWith(HelloWorld.class); } }

Slide 48

Slide 48 text

public class HelloWorldProcessor extends AbstractProcessor { // . . . @Override public boolean process( Set annotations, RoundEnvironment env) { Set elements = env.getElementsAnnotatedWith(HelloWorld.class); for(Element element : elements) { System.out.println(element); } } }

Slide 49

Slide 49 text

public class HelloWorldProcessor extends AbstractProcessor { // . . . @Override public boolean process( Set annotations, RoundEnvironment env) { Set elements = env.getElementsAnnotatedWith(HelloWorld.class); for(Element element : elements) { System.out.println(element); } return false; } }

Slide 50

Slide 50 text

public class HelloWorldProcessor extends AbstractProcessor { @Override public SourceVersion getSupportedSourceVersion() { return SourceVersion.latestSupported(); } @Override public Set getSupportedAnnotationTypes() { return Collections.singleton(HelloWorld.class.getName()); } @Override public boolean process( Set annotations, RoundEnvironment env) { Set elements = env.getElementsAnnotatedWith(HelloWorld.class); for(Element element : elements) { System.out.println(element); } return false; } }

Slide 51

Slide 51 text

Anotando um elemento

Slide 52

Slide 52 text

@HelloWorld public class HelloWorldClass { // . . . }

Slide 53

Slide 53 text

@HelloWorld public class HelloWorldClass { // . . . }

Slide 54

Slide 54 text

@HelloWorld public class HelloWorldClass { // . . . }

Slide 55

Slide 55 text

Execução

Slide 56

Slide 56 text

● Acontece automaticamente quando javac é executado ● ServiceLoader se encarrega de encontrar e instanciar os Processor Execução

Slide 57

Slide 57 text

● META-INF/services ● Nome do arquivo ○ javax.annotation.processing.Processor ● Cada linha do arquivo deve ter o nome completo de cada Processor ○ com.example.HelloWorldProcessor ServiceLoader

Slide 58

Slide 58 text

Processing Rounds

Slide 59

Slide 59 text

● Acontece em duas etapas ● A primeira etapa processa os elementos anotados ○ Novos arquivos de código fonte podem ser gerados ○ Os arquivos compilados tem como saída seus bytecodes ● A segunda etapa acontece para verificar se novos arquivos gerados ○ Os eventuais arquivos gerados são compilados e tem como saída os arquivos bytecode Processing Rounds

Slide 60

Slide 60 text

No content

Slide 61

Slide 61 text

No content

Slide 62

Slide 62 text

Gerando nosso código

Slide 63

Slide 63 text

public class HelloWorldProcessor extends AbstractProcessor { // . . . @Override public boolean process( Set annotations, RoundEnvironment env) { Set elements = env.getElementsAnnotatedWith(HelloWorld.class); for(Element element : elements) { // Analisar os atributos de ‘element’ // Gerar código a partir desses atributos } return false; } }

Slide 64

Slide 64 text

@Override public boolean process( Set annotations, RoundEnvironment env) { return false; }

Slide 65

Slide 65 text

@Override public boolean process( Set annotations, RoundEnvironment env) { List classesInfo = parseHelloWorldAnnotation(env); return false; }

Slide 66

Slide 66 text

@Override public boolean process( Set annotations, RoundEnvironment env) { List classesInfo = parseHelloWorldAnnotation(env); return false; } List parseHelloWorldAnnotation(RoundEnvironment env) { // . . . }

Slide 67

Slide 67 text

@Override public boolean process( Set annotations, RoundEnvironment env) { List classesInfo = parseHelloWorldAnnotation(env); for(ClassInfo classInfo : classesInfo) { generateHelloWorldCode(classInfo); } return false; } List parseHelloWorldAnnotation(RoundEnvironment env) { // . . . }

Slide 68

Slide 68 text

@Override public boolean process( Set annotations, RoundEnvironment env) { List classesInfo = parseHelloWorldAnnotation(env); for(ClassInfo classInfo : classesInfo) { generateHelloWorldCode(classInfo); } return false; } List parseHelloWorldAnnotation(RoundEnvironment env) { // . . . } void generateHelloWorldCode(ClassInfo classInfo) { // . . . }

Slide 69

Slide 69 text

Element

Slide 70

Slide 70 text

Element

Slide 71

Slide 71 text

Element ClassInfo package: “com.example” element: name: “FooHelloWorld”

Slide 72

Slide 72 text

Element ClassInfo package: “com.example” element: name: “FooHelloWorld” Generated Class

Slide 73

Slide 73 text

Usando algumas armas!

Slide 74

Slide 74 text

● Google Auto Common ● Google Auto Service ● JavaPoet Usando algumas armas

Slide 75

Slide 75 text

● Lembram? META-INF/services/javax.annotation.processing.Processor Google Auto Service

Slide 76

Slide 76 text

● Lembram? META-INF/services/javax.annotation.processing.Processor ● AutoService gera esses arquivos através de anotações! Google Auto Service

Slide 77

Slide 77 text

● Lembram? META-INF/services/javax.annotation.processing.Processor ● AutoService gera esses arquivos através de anotações! Google Auto Service public class HelloWorldProcessor extends AbstractProcessor { // . . . }

Slide 78

Slide 78 text

● Lembram? META-INF/services/javax.annotation.processing.Processor ● AutoService gera esses arquivos através de anotações! Google Auto Service @AutoService(Processor.class) public class HelloWorldProcessor extends AbstractProcessor { // . . . }

Slide 79

Slide 79 text

TypeSpec.classBuilder(“FooHelloWorld”) .addModifiers(PUBLIC) .addMethod( MethodSpec.constructorBuilder() .addStatement( “System.out.println($S)”, “Hello, world!” ).build(); ).build(); JavaPoet

Slide 80

Slide 80 text

TypeSpec.classBuilder(“FooHelloWorld”) .addModifiers(PUBLIC) .addMethod( MethodSpec.constructorBuilder() .addStatement( “System.out.println($S)”, “Hello, world!” ).build(); ).build(); public class FooHelloWorld { FooHelloWorld() { System.out.println(“Hello, world!”); } } JavaPoet

Slide 81

Slide 81 text

E agora?

Slide 82

Slide 82 text

Perguntas?

Slide 83

Slide 83 text

No content

Slide 84

Slide 84 text

Obrigado!