@ -1,5 +1,5 @@
/ *
/ *
* Copyright 2012 - 201 6 the original author or authors .
* Copyright 2012 - 201 7 the original author or authors .
*
*
* Licensed under the Apache License , Version 2.0 ( the "License" ) ;
* Licensed under the Apache License , Version 2.0 ( the "License" ) ;
* you may not use this file except in compliance with the License .
* you may not use this file except in compliance with the License .
@ -35,8 +35,8 @@ import org.springframework.util.Assert;
/ * *
/ * *
* Sort { @link EnableAutoConfiguration auto - configuration } classes into priority order by
* Sort { @link EnableAutoConfiguration auto - configuration } classes into priority order by
* reading { @link Ordered } , { @link AutoConfigureBefore } and { @link AutoConfigureAfter }
* reading { @link AutoConfigure Order} , { @link AutoConfigureBefore } and
* annotations ( without loading classes ) .
* { @link AutoConfigureAfter } annotations ( without loading classes ) .
*
*
* @author Phillip Webb
* @author Phillip Webb
* /
* /
@ -44,26 +44,31 @@ class AutoConfigurationSorter {
private final MetadataReaderFactory metadataReaderFactory ;
private final MetadataReaderFactory metadataReaderFactory ;
AutoConfigurationSorter ( MetadataReaderFactory metadataReaderFactory ) {
private final AutoConfigurationMetadata autoConfigurationMetadata ;
AutoConfigurationSorter ( MetadataReaderFactory metadataReaderFactory ,
AutoConfigurationMetadata autoConfigurationMetadata ) {
Assert . notNull ( metadataReaderFactory , "MetadataReaderFactory must not be null" ) ;
Assert . notNull ( metadataReaderFactory , "MetadataReaderFactory must not be null" ) ;
this . metadataReaderFactory = metadataReaderFactory ;
this . metadataReaderFactory = metadataReaderFactory ;
this . autoConfigurationMetadata = autoConfigurationMetadata ;
}
}
public List < String > getInPriorityOrder ( Collection < String > classNames )
public List < String > getInPriorityOrder ( Collection < String > classNames ) {
throws IOException {
final AutoConfigurationClasses classes = new AutoConfigurationClasses (
final AutoConfigurationClasses classes = new AutoConfigurationClasses (
this . metadataReaderFactory , classNames ) ;
this . metadataReaderFactory , this . autoConfigurationMetadata , classNames ) ;
List < String > orderedClassNames = new ArrayList < String > ( classNames ) ;
List < String > orderedClassNames = new ArrayList < String > ( classNames ) ;
// Initially sort alphabetically
// Initially sort alphabetically
Collections . sort ( orderedClassNames ) ;
Collections . sort ( orderedClassNames ) ;
// Then sort by order
// Then sort by order
Collections . sort ( orderedClassNames , new Comparator < String > ( ) {
Collections . sort ( orderedClassNames , new Comparator < String > ( ) {
@Override
@Override
public int compare ( String o1 , String o2 ) {
public int compare ( String o1 , String o2 ) {
int i1 = classes . get ( o1 ) . getOrder ( ) ;
int i1 = classes . get ( o1 ) . getOrder ( ) ;
int i2 = classes . get ( o2 ) . getOrder ( ) ;
int i2 = classes . get ( o2 ) . getOrder ( ) ;
return ( i1 < i2 ) ? - 1 : ( i1 > i2 ) ? 1 : 0 ;
return ( i1 < i2 ) ? - 1 : ( i1 > i2 ) ? 1 : 0 ;
}
}
} ) ;
} ) ;
// Then respect @AutoConfigureBefore @AutoConfigureAfter
// Then respect @AutoConfigureBefore @AutoConfigureAfter
orderedClassNames = sortByAnnotation ( classes , orderedClassNames ) ;
orderedClassNames = sortByAnnotation ( classes , orderedClassNames ) ;
@ -104,11 +109,11 @@ class AutoConfigurationSorter {
private final Map < String , AutoConfigurationClass > classes = new HashMap < String , AutoConfigurationClass > ( ) ;
private final Map < String , AutoConfigurationClass > classes = new HashMap < String , AutoConfigurationClass > ( ) ;
AutoConfigurationClasses ( MetadataReaderFactory metadataReaderFactory ,
AutoConfigurationClasses ( MetadataReaderFactory metadataReaderFactory ,
Collection < String > classNames ) throws IOException {
AutoConfigurationMetadata autoConfigurationMetadata ,
Collection < String > classNames ) {
for ( String className : classNames ) {
for ( String className : classNames ) {
MetadataReader metadataReader = metadataReaderFactory
this . classes . put ( className , new AutoConfigurationClass ( className ,
. getMetadataReader ( className ) ;
metadataReaderFactory , autoConfigurationMetadata ) ) ;
this . classes . put ( className , new AutoConfigurationClass ( metadataReader ) ) ;
}
}
}
}
@ -132,29 +137,65 @@ class AutoConfigurationSorter {
private static class AutoConfigurationClass {
private static class AutoConfigurationClass {
private final AnnotationMetadata metadata ;
private final String className ;
private final MetadataReaderFactory metadataReaderFactory ;
private final AutoConfigurationMetadata autoConfigurationMetadata ;
private AnnotationMetadata annotationMetadata ;
private final Set < String > before ;
private final Set < String > after ;
AutoConfigurationClass ( String className ,
MetadataReaderFactory metadataReaderFactory ,
AutoConfigurationMetadata autoConfigurationMetadata ) {
this . className = className ;
this . metadataReaderFactory = metadataReaderFactory ;
this . autoConfigurationMetadata = autoConfigurationMetadata ;
this . before = readBefore ( ) ;
this . after = readAfter ( ) ;
}
public Set < String > getBefore ( ) {
return this . before ;
}
AutoConfigurationClass ( MetadataReader metadataReader ) {
public Set < String > getAfter ( ) {
this . metadata = metadataReader . getAnnotationMetadata ( ) ;
return this . after ;
}
}
public int getOrder ( ) {
private int getOrder ( ) {
Map < String , Object > orderedAnnotation = this . metadata
if ( this . autoConfigurationMetadata . wasProcessed ( this . className ) ) {
return this . autoConfigurationMetadata . getInteger ( this . className ,
"AutoConfigureOrder" , Ordered . LOWEST_PRECEDENCE ) ;
}
Map < String , Object > attributes = getAnnotationMetadata ( )
. getAnnotationAttributes ( AutoConfigureOrder . class . getName ( ) ) ;
. getAnnotationAttributes ( AutoConfigureOrder . class . getName ( ) ) ;
return ( orderedAnnotation = = null ? Ordered . LOWEST_PRECEDENCE
return ( attributes = = null ? Ordered . LOWEST_PRECEDENCE
: ( Integer ) orderedAnnotation . get ( "value" ) ) ;
: ( Integer ) attributes . get ( "value" ) ) ;
}
}
public Set < String > getBefore ( ) {
private Set < String > readBefore ( ) {
if ( this . autoConfigurationMetadata . wasProcessed ( this . className ) ) {
return this . autoConfigurationMetadata . getSet ( this . className ,
"AutoConfigureBefore" , Collections . < String > emptySet ( ) ) ;
}
return getAnnotationValue ( AutoConfigureBefore . class ) ;
return getAnnotationValue ( AutoConfigureBefore . class ) ;
}
}
public Set < String > getAfter ( ) {
private Set < String > readAfter ( ) {
if ( this . autoConfigurationMetadata . wasProcessed ( this . className ) ) {
return this . autoConfigurationMetadata . getSet ( this . className ,
"AutoConfigureAfter" , Collections . < String > emptySet ( ) ) ;
}
return getAnnotationValue ( AutoConfigureAfter . class ) ;
return getAnnotationValue ( AutoConfigureAfter . class ) ;
}
}
private Set < String > getAnnotationValue ( Class < ? > annotation ) {
private Set < String > getAnnotationValue ( Class < ? > annotation ) {
Map < String , Object > attributes = this . metadata
Map < String , Object > attributes = getAnnotationMetadata ( )
. getAnnotationAttributes ( annotation . getName ( ) , true ) ;
. getAnnotationAttributes ( annotation . getName ( ) , true ) ;
if ( attributes = = null ) {
if ( attributes = = null ) {
return Collections . emptySet ( ) ;
return Collections . emptySet ( ) ;
@ -165,6 +206,21 @@ class AutoConfigurationSorter {
return value ;
return value ;
}
}
private AnnotationMetadata getAnnotationMetadata ( ) {
if ( this . annotationMetadata = = null ) {
try {
MetadataReader metadataReader = this . metadataReaderFactory
. getMetadataReader ( this . className ) ;
this . annotationMetadata = metadataReader . getAnnotationMetadata ( ) ;
}
catch ( IOException ex ) {
throw new IllegalStateException (
"Unable to read meta-data for class " + this . className , ex ) ;
}
}
return this . annotationMetadata ;
}
}
}
}
}