Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Annotation Processing Tools - Droidcon Madrid 2015
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
Rubén Serrano
April 25, 2015
Programming
180
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Annotation Processing Tools - Droidcon Madrid 2015
Rubén Serrano
April 25, 2015
More Decks by Rubén Serrano
See All by Rubén Serrano
Clean Architecture the Right Way. Or almost...
akelael
3
230
Flutter, the road to Fuchsia (DevFest Tarragona 2018)
akelael
0
87
Architecting the Redbooth Android App - GDG Barcelona Android Community Day
akelael
2
180
Unclean Architecture in Android - Droidcon Madrid 2016
akelael
0
110
From Legacy to Hexagonal (Codemotion Madrid 2014)
akelael
5
380
Evolución Android (v3.0, DevFest Tarragona 2014)
akelael
0
59
From Legacy to Hexagonal Android (Droidcon London 2014)
akelael
1
180
Evolución Android
akelael
0
140
Other Decks in Programming
See All in Programming
SREは、MCPとSRE Agentをこう使え!
kazumax55
0
130
Oxlintのカスタムルールの現況
syumai
6
1.2k
ランチタイムLT会3周年!ランチタイムLT会を3年間続けられたお話
y0hgi
1
120
才能?センス?知らん、 続けたもん勝ちだ。-- 結婚・出産・癌を越えてなお、私がプロダクトを創り続ける理由
16bitidol
1
570
OSもどきOS
arkw
0
600
代数的データ型って何が嬉しいの? #frontend_phpcon_do
kajitack
8
3.8k
1B+ /day規模のログを管理する技術
broadleaf
0
120
Creating Composable Callables in Contemporary C++
rollbear
0
170
Lessons from Spec-Driven Development
simas
PRO
0
230
LLM本来の能力を解き放つサンドボックス技術とAI民主化への適用
yukukotani
3
4.6k
Javaの型とAI時代に型が大事な理由 / java types and type in AI era
kishida
2
150
JavaDoc 再入門
nagise
1
430
Featured
See All Featured
Building the Perfect Custom Keyboard
takai
2
800
Unsuck your backbone
ammeep
672
58k
The Myth of the Modular Monolith - Day 2 Keynote - Rails World 2024
eileencodes
28
3.5k
Art, The Web, and Tiny UX
lynnandtonic
304
22k
Collaborative Software Design: How to facilitate domain modelling decisions
baasie
1
260
GraphQLの誤解/rethinking-graphql
sonatard
75
12k
Raft: Consensus for Rubyists
vanstee
141
7.6k
Test your architecture with Archunit
thirion
1
2.3k
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
659
62k
No one is an island. Learnings from fostering a developers community.
thoeni
21
3.8k
Ethics towards AI in product and experience design
skipperchong
2
320
Breaking role norms: Why Content Design is so much more than writing copy - Taylor Woolridge
uxyall
0
330
Transcript
Annotation Processing Tools 101
Txus Ballesteros @txusballesteros Rubén Serrano @akelael
Agenda 1. Annotation Processing Tool 2. Discusión 3. Caso práctico
¿Qué es eso de APT?
public @interface DummyAnnotiation {} Anotación
Retención • Constructor • Atributo • Variable • Método •
Parámetro • Etc. • Source • Class • Runtime Objetivo
Anotación @Retention(CLASS) @Target(FIELD) public @interface InjectView { int value(); }
Runtime Class tiene la magia: • getAnnotation(Class<T> annotationType) • getAnnotations()
• getDeclaredAnnotations() • isAnnotationPresent(Class<T> annotationType)
Mirror API http://docs.oracle.com/javase/1.5.0/docs/guide/apt/mirror/overview-summary.html
Discusión
Caso Práctico
Android Transformer https://github.com/txusballesteros/android-transformer
Creando Anotaciones @Retention(RetentionPolicy.SOURCE) @Target(ElementType.TYPE) public @interface Mappable { Class<?>
with(); }
Creando Anotaciones @Retention(RetentionPolicy.SOURCE) @Target(ElementType.TYPE) public @interface Mappable { Class<?>
with(); }
Configurando las Anotaciones @Retention(RetentionPolicy.SOURCE) @Target(ElementType.TYPE) public @interface Mappable {
Class<?> with(); }
Configurando las Anotaciones @Retention(RetentionPolicy.SOURCE) @Target(ElementType.TYPE) public @interface Mappable {
Class<?> with(); }
@SupportedSourceVersion(SourceVersion.RELEASE_7) @SupportedAnnotationTypes({ "com.mobandme.android.transformer.compiler.Mapping", "com.mobandme.android.transformer.compiler.Mappable", "com.mobandme.android.transformer.compiler.Parse" }) public class AnnotationsProcessor extends
AbstractProcessor { RoundEnvironment roundEnvironment; Map<String, MapperInfo> mappersList; @Override public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { return true; } Creando el Procesador
@SupportedSourceVersion(SourceVersion.RELEASE_7) @SupportedAnnotationTypes({ "com.mobandme.android.transformer.compiler.Mapping", "com.mobandme.android.transformer.compiler.Mappable", "com.mobandme.android.transformer.compiler.Parse" }) public class AnnotationsProcessor extends
AbstractProcessor { RoundEnvironment roundEnvironment; Map<String, MapperInfo> mappersList; @Override public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { return true; } Creando el Procesador
@SupportedSourceVersion(SourceVersion.RELEASE_7) @SupportedAnnotationTypes({ "com.mobandme.android.transformer.compiler.Mapping", "com.mobandme.android.transformer.compiler.Mappable", "com.mobandme.android.transformer.compiler.Parse" }) public class AnnotationsProcessor extends
AbstractProcessor { RoundEnvironment roundEnvironment; Map<String, MapperInfo> mappersList; @Override public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { return true; } Configurando el Procesador
Implementando el Procesador @SupportedSourceVersion(SourceVersion.RELEASE_7) @SupportedAnnotationTypes({ "com.mobandme.android.transformer.compiler.Mapping", "com.mobandme.android.transformer.compiler.Mappable", "com.mobandme.android.transformer.compiler.Parse" }) public
class AnnotationsProcessor extends AbstractProcessor { RoundEnvironment roundEnvironment; Map<String, MapperInfo> mappersList; @Override public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { return true; }
Implementando el Procesador private void processMappedAnnotationElements() { Set<? extends Element>
elements = roundEnvironment.getElementsAnnotatedWith(Mapped.class); for (Element mappedElement : elements) { if (mappedElement.getKind() == ElementKind.FIELD) { Mapped mappedAnnotation = mappedElement.getAnnotation(Mapped.class); String toFieldName = mappedAnnotation.toField(); } } }
Implementando el Procesador private void processMappedAnnotationElements() { Set<? extends Element>
elements = roundEnvironment.getElementsAnnotatedWith(Mapped.class); for (Element mappedElement : elements) { if (mappedElement.getKind() == ElementKind.FIELD) { Mapped mappedAnnotation = mappedElement.getAnnotation(Mapped.class); String toFieldName = mappedAnnotation.toField(); } } }
Implementando el Procesador private void processMappedAnnotationElements() { Set<? extends Element>
elements = roundEnvironment.getElementsAnnotatedWith(Mapped.class); for (Element mappedElement : elements) { if (mappedElement.getKind() == ElementKind.FIELD) { Mapped mappedAnnotation = mappedElement.getAnnotation(Mapped.class); String toFieldName = mappedAnnotation.toField(); } } }
Implementando el Procesador private void processMappedAnnotationElements() { Set<? extends Element>
elements = roundEnvironment.getElementsAnnotatedWith(Mapped.class); for (Element mappedElement : elements) { if (mappedElement.getKind() == ElementKind.FIELD) { Mapped mappedAnnotation = mappedElement.getAnnotation(Mapped.class); String toFieldName = mappedAnnotation.toField(); } } }
Generando el Código JavaFileObject file = processingEnv.getFiler().createSourceFile(name); BufferedWriter buffer =
new BufferedWriter(file.openWriter()); //… buffer.close();
Configurando el Entorno com.mobandme.android.transformer.compiler.internal.AnnotationsProcessor
Configuración de Gradle para el Compilador buildscript { repositories {
maven { url "https://oss.sonatype.org/content/repositories/snapshots/" } jcenter() } dependencies { classpath 'com.jimdo.gradle:gradle-apt-plugin:0.5-SNAPSHOT' } } apply plugin: 'java' apply plugin: 'apt'
El resultado final
¿Preguntas?