forked from spring-projects/spring-boot
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Introduce spring-boot-autoconfigure-processor
Add an annotation processor that generates properties files for certain auto-configuration class annotations. Currently attribute values from @AutoConfigureOrder, @AutoConfigureBefore, @AutoConfigureAfter and @ConditionalOnClass annotations are stored. The properties file will allow optimizations to be added in the `spring-boot-autoconfigure` project. Primarily by removing the need to ASM parse as many `.class` files. See spring-projectsgh-7573
- Loading branch information
Showing
25 changed files
with
799 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
20 changes: 20 additions & 0 deletions
20
...boot-test-support/src/main/java/org/springframework/boot/junit/compiler/package-info.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
/* | ||
* Copyright 2012-2017 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. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
/** | ||
* Utilities to work with the Java compiler at test time. | ||
*/ | ||
package org.springframework.boot.junit.compiler; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
40 changes: 40 additions & 0 deletions
40
spring-boot-tools/spring-boot-autoconfigure-processor/pom.xml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
<modelVersion>4.0.0</modelVersion> | ||
<parent> | ||
<groupId>org.springframework.boot</groupId> | ||
<artifactId>spring-boot-tools</artifactId> | ||
<version>1.5.0.BUILD-SNAPSHOT</version> | ||
</parent> | ||
<artifactId>spring-boot-autoconfigure-processor</artifactId> | ||
<name>Spring Boot Auto-Configure Annotation Processor</name> | ||
<description>Spring Auto-Configure Annotation Processor</description> | ||
<url>http://projects.spring.io/spring-boot/</url> | ||
<organization> | ||
<name>Pivotal Software, Inc.</name> | ||
<url>http://www.spring.io</url> | ||
</organization> | ||
<properties> | ||
<main.basedir>${basedir}/../..</main.basedir> | ||
</properties> | ||
<dependencies> | ||
<dependency> | ||
<groupId>org.springframework.boot</groupId> | ||
<artifactId>spring-boot-test-support</artifactId> | ||
<scope>test</scope> | ||
</dependency> | ||
</dependencies> | ||
<build> | ||
<plugins> | ||
<plugin> | ||
<groupId>org.apache.maven.plugins</groupId> | ||
<artifactId>maven-compiler-plugin</artifactId> | ||
<configuration> | ||
<!-- Ensure own annotation processor doesn't kick in --> | ||
<proc>none</proc> | ||
</configuration> | ||
</plugin> | ||
</plugins> | ||
</build> | ||
</project> |
214 changes: 214 additions & 0 deletions
214
...ava/org/springframework/boot/autoconfigureprocessor/AutoConfigureAnnotationProcessor.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,214 @@ | ||
/* | ||
* Copyright 2012-2017 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. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package org.springframework.boot.autoconfigureprocessor; | ||
|
||
import java.io.IOException; | ||
import java.io.OutputStream; | ||
import java.util.ArrayList; | ||
import java.util.Collections; | ||
import java.util.LinkedHashMap; | ||
import java.util.List; | ||
import java.util.Map; | ||
import java.util.Properties; | ||
import java.util.Set; | ||
|
||
import javax.annotation.processing.AbstractProcessor; | ||
import javax.annotation.processing.RoundEnvironment; | ||
import javax.annotation.processing.SupportedAnnotationTypes; | ||
import javax.lang.model.element.AnnotationMirror; | ||
import javax.lang.model.element.AnnotationValue; | ||
import javax.lang.model.element.Element; | ||
import javax.lang.model.element.ElementKind; | ||
import javax.lang.model.element.ExecutableElement; | ||
import javax.lang.model.element.TypeElement; | ||
import javax.lang.model.type.DeclaredType; | ||
import javax.lang.model.type.TypeMirror; | ||
import javax.tools.FileObject; | ||
import javax.tools.StandardLocation; | ||
|
||
/** | ||
* Annotation processor to store certain annotations from auto-configuration classes in a | ||
* property file. | ||
* | ||
* @author Madhura Bhave | ||
* @author Phillip Webb | ||
*/ | ||
@SupportedAnnotationTypes({ "org.springframework.context.annotation.Configuration", | ||
"org.springframework.boot.autoconfigure.condition.ConditionalOnClass", | ||
"org.springframework.boot.autoconfigure.AutoConfigureBefore", | ||
"org.springframework.boot.autoconfigure.AutoConfigureAfter", | ||
"org.springframework.boot.autoconfigure.AutoConfigureOrder" }) | ||
public class AutoConfigureAnnotationProcessor extends AbstractProcessor { | ||
|
||
protected static final String PROPERTIES_PATH = "META-INF/" | ||
+ "spring-autoconfigure-metadata.properties"; | ||
|
||
private Map<String, String> annotations; | ||
|
||
private final Properties properties = new Properties(); | ||
|
||
public AutoConfigureAnnotationProcessor() { | ||
Map<String, String> annotations = new LinkedHashMap<String, String>(); | ||
addAnnotations(annotations); | ||
this.annotations = Collections.unmodifiableMap(annotations); | ||
} | ||
|
||
protected void addAnnotations(Map<String, String> annotations) { | ||
annotations.put("Configuration", | ||
"org.springframework.context.annotation.Configuration"); | ||
annotations.put("ConditionalOnClass", | ||
"org.springframework.boot.autoconfigure.condition.ConditionalOnClass"); | ||
annotations.put("AutoConfigureBefore", | ||
"org.springframework.boot.autoconfigure.AutoConfigureBefore"); | ||
annotations.put("AutoConfigureAfter", | ||
"org.springframework.boot.autoconfigure.AutoConfigureAfter"); | ||
annotations.put("AutoConfigureOrder", | ||
"org.springframework.boot.autoconfigure.AutoConfigureOrder"); | ||
} | ||
|
||
@Override | ||
public boolean process(Set<? extends TypeElement> annotations, | ||
RoundEnvironment roundEnv) { | ||
for (Map.Entry<String, String> entry : this.annotations.entrySet()) { | ||
process(roundEnv, entry.getKey(), entry.getValue()); | ||
} | ||
if (roundEnv.processingOver()) { | ||
try { | ||
writeProperties(); | ||
} | ||
catch (Exception ex) { | ||
throw new IllegalStateException("Failed to write metadata", ex); | ||
} | ||
} | ||
return false; | ||
} | ||
|
||
private void process(RoundEnvironment roundEnv, String propertyKey, | ||
String annotationName) { | ||
TypeElement annotationType = this.processingEnv.getElementUtils() | ||
.getTypeElement(annotationName); | ||
if (annotationType != null) { | ||
for (Element element : roundEnv.getElementsAnnotatedWith(annotationType)) { | ||
Element enclosingElement = element.getEnclosingElement(); | ||
if (enclosingElement != null | ||
&& enclosingElement.getKind() == ElementKind.PACKAGE) { | ||
processElement(element, propertyKey, annotationName); | ||
} | ||
} | ||
} | ||
} | ||
|
||
private void processElement(Element element, String propertyKey, | ||
String annotationName) { | ||
try { | ||
String qualifiedName = getQualifiedName(element); | ||
AnnotationMirror annotation = getAnnotation(element, annotationName); | ||
if (qualifiedName != null && annotation != null) { | ||
List<Object> values = getValues(annotation); | ||
this.properties.put(qualifiedName + "." + propertyKey, | ||
toCommaDelimitedString(values)); | ||
this.properties.put(qualifiedName, ""); | ||
} | ||
} | ||
catch (Exception ex) { | ||
throw new IllegalStateException( | ||
"Error processing configuration meta-data on " + element, ex); | ||
} | ||
} | ||
|
||
private AnnotationMirror getAnnotation(Element element, String type) { | ||
if (element != null) { | ||
for (AnnotationMirror annotation : element.getAnnotationMirrors()) { | ||
if (type.equals(annotation.getAnnotationType().toString())) { | ||
return annotation; | ||
} | ||
} | ||
} | ||
return null; | ||
} | ||
|
||
private String toCommaDelimitedString(List<Object> list) { | ||
StringBuilder result = new StringBuilder(); | ||
for (Object item : list) { | ||
result.append(result.length() != 0 ? "," : ""); | ||
result.append(item); | ||
} | ||
return result.toString(); | ||
} | ||
|
||
@SuppressWarnings("unchecked") | ||
private List<Object> getValues(AnnotationMirror annotation) { | ||
List<Object> result = new ArrayList<Object>(); | ||
for (Map.Entry<? extends ExecutableElement, ? extends AnnotationValue> entry : annotation | ||
.getElementValues().entrySet()) { | ||
String attributeName = entry.getKey().getSimpleName().toString(); | ||
if ("name".equals(attributeName) || "value".equals(attributeName)) { | ||
Object value = entry.getValue().getValue(); | ||
if (value instanceof List) { | ||
for (AnnotationValue annotationValue : (List<AnnotationValue>) value) { | ||
result.add(annotationValue.getValue()); | ||
} | ||
} | ||
else { | ||
result.add(value); | ||
} | ||
} | ||
} | ||
return result; | ||
} | ||
|
||
private String getQualifiedName(Element element) { | ||
if (element != null) { | ||
TypeElement enclosingElement = getEnclosingTypeElement(element.asType()); | ||
if (enclosingElement != null) { | ||
return getQualifiedName(enclosingElement) + "$" | ||
+ ((DeclaredType) element.asType()).asElement().getSimpleName() | ||
.toString(); | ||
} | ||
if (element instanceof TypeElement) { | ||
return ((TypeElement) element).getQualifiedName().toString(); | ||
} | ||
} | ||
return null; | ||
} | ||
|
||
private TypeElement getEnclosingTypeElement(TypeMirror type) { | ||
if (type instanceof DeclaredType) { | ||
DeclaredType declaredType = (DeclaredType) type; | ||
Element enclosingElement = declaredType.asElement().getEnclosingElement(); | ||
if (enclosingElement != null && enclosingElement instanceof TypeElement) { | ||
return (TypeElement) enclosingElement; | ||
} | ||
} | ||
return null; | ||
} | ||
|
||
private void writeProperties() throws IOException { | ||
if (!this.properties.isEmpty()) { | ||
FileObject file = this.processingEnv.getFiler() | ||
.createResource(StandardLocation.CLASS_OUTPUT, "", PROPERTIES_PATH); | ||
OutputStream outputStream = file.openOutputStream(); | ||
try { | ||
this.properties.store(outputStream, null); | ||
} | ||
finally { | ||
outputStream.close(); | ||
} | ||
} | ||
} | ||
|
||
} |
1 change: 1 addition & 0 deletions
1
...gure-processor/src/main/resources/META-INF/services/javax.annotation.processing.Processor
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
org.springframework.boot.autoconfigureprocessor.AutoConfigureAnnotationProcessor |
Oops, something went wrong.