Avoid synthesizing annotations unnecessarily

Commit 31fa1569c5 introduced initial support for avoiding unnecessary
annotation synthesis in the MergedAnnotation API; however, it only
avoided synthesis for annotations that do not declare any attributes.

This commit reworks this support to avoid unnecessary annotation
synthesis for annotations that declare attributes.

Specifically, this commit introduces a new `isSynthesizable()` method
in AnnotationTypeMapping that allows the "synthesizable" flag to be
computed once and cached along with the other metadata already cached
in AnnotationTypeMapping instances. TypeMappedAnnotation now delegates
to this new method when determining whether it should synthesize an
annotation.

Closes gh-24861
This commit is contained in:
Sam Brannen
2020-04-23 18:51:45 +02:00
parent 0520ee0fb6
commit 8265db0ae1
4 changed files with 104 additions and 17 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -1380,14 +1380,22 @@ class MergedAnnotationsTests {
@Test
void synthesizeShouldNotSynthesizeNonsynthesizableAnnotations() throws Exception {
Method method = getClass().getDeclaredMethod("getId");
Id id = method.getAnnotation(Id.class);
assertThat(id).isNotNull();
Id synthesizedId = MergedAnnotation.from(id).synthesize();
assertThat(id).isEqualTo(synthesizedId);
// It doesn't make sense to synthesize {@code @Id} since it declares zero attributes.
// It doesn't make sense to synthesize @Id since it declares zero attributes.
assertThat(synthesizedId).isNotInstanceOf(SynthesizedAnnotation.class);
assertThat(id).isSameAs(synthesizedId);
GeneratedValue generatedValue = method.getAnnotation(GeneratedValue.class);
assertThat(generatedValue).isNotNull();
GeneratedValue synthesizedGeneratedValue = MergedAnnotation.from(generatedValue).synthesize();
assertThat(generatedValue).isEqualTo(synthesizedGeneratedValue);
// It doesn't make sense to synthesize @GeneratedValue since it declares zero attributes with aliases.
assertThat(synthesizedGeneratedValue).isNotInstanceOf(SynthesizedAnnotation.class);
assertThat(generatedValue).isSameAs(synthesizedGeneratedValue);
}
/**
@@ -2987,7 +2995,16 @@ class MergedAnnotationsTests {
@interface Id {
}
/**
* Mimics javax.persistence.GeneratedValue
*/
@Retention(RUNTIME)
@interface GeneratedValue {
String strategy();
}
@Id
@GeneratedValue(strategy = "AUTO")
private Long getId() {
return 42L;
}