Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in / Register
Toggle navigation
S
spring-boot
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
DEMO
spring-boot
Commits
33658c29
Commit
33658c29
authored
Aug 07, 2013
by
Dave Syer
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add @AutoConfigureBefore and simple implementation
[#54597932] [bs-273] Circular view reference for /error
parent
91a56f7b
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
183 additions
and
19 deletions
+183
-19
AutoConfigurationSorter.java
...framework/boot/autoconfigure/AutoConfigurationSorter.java
+63
-11
AutoConfigureBefore.java
...ringframework/boot/autoconfigure/AutoConfigureBefore.java
+34
-0
AutoConfigurationSorterTests.java
...work/boot/autoconfigure/AutoConfigurationSorterTests.java
+86
-8
No files found.
spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/AutoConfigurationSorter.java
View file @
33658c29
...
@@ -20,6 +20,7 @@ import java.io.IOException;
...
@@ -20,6 +20,7 @@ import java.io.IOException;
import
java.util.ArrayList
;
import
java.util.ArrayList
;
import
java.util.Collection
;
import
java.util.Collection
;
import
java.util.Collections
;
import
java.util.Collections
;
import
java.util.LinkedHashMap
;
import
java.util.LinkedHashSet
;
import
java.util.LinkedHashSet
;
import
java.util.List
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Map
;
...
@@ -52,6 +53,7 @@ class AutoConfigurationSorter {
...
@@ -52,6 +53,7 @@ class AutoConfigurationSorter {
public
List
<
String
>
getInPriorityOrder
(
Collection
<
String
>
classNames
)
public
List
<
String
>
getInPriorityOrder
(
Collection
<
String
>
classNames
)
throws
IOException
{
throws
IOException
{
List
<
AutoConfigurationClass
>
autoConfigurationClasses
=
new
ArrayList
<
AutoConfigurationClass
>();
List
<
AutoConfigurationClass
>
autoConfigurationClasses
=
new
ArrayList
<
AutoConfigurationClass
>();
for
(
String
className
:
classNames
)
{
for
(
String
className
:
classNames
)
{
autoConfigurationClasses
.
add
(
new
AutoConfigurationClass
(
className
));
autoConfigurationClasses
.
add
(
new
AutoConfigurationClass
(
className
));
...
@@ -65,30 +67,52 @@ class AutoConfigurationSorter {
...
@@ -65,30 +67,52 @@ class AutoConfigurationSorter {
List
<
String
>
orderedClassNames
=
new
ArrayList
<
String
>();
List
<
String
>
orderedClassNames
=
new
ArrayList
<
String
>();
for
(
AutoConfigurationClass
autoConfigurationClass
:
autoConfigurationClasses
)
{
for
(
AutoConfigurationClass
autoConfigurationClass
:
autoConfigurationClasses
)
{
orderedClassNames
.
add
(
autoConfigurationClass
.
toString
());
orderedClassNames
.
add
(
autoConfigurationClass
.
getClassName
());
}
}
return
orderedClassNames
;
return
orderedClassNames
;
}
}
private
List
<
AutoConfigurationClass
>
sortByAfterAnnotation
(
private
List
<
AutoConfigurationClass
>
sortByAfterAnnotation
(
Collection
<
AutoConfigurationClass
>
autoConfigurationClasses
)
Collection
<
AutoConfigurationClass
>
autoConfigurationClasses
)
throws
IOException
{
throws
IOException
{
List
<
AutoConfigurationClass
>
tosort
=
new
ArrayList
<
AutoConfigurationClass
>(
autoConfigurationClasses
);
// Create a look up table of actual autoconfigs
Map
<
AutoConfigurationClass
,
AutoConfigurationClass
>
tosort
=
new
LinkedHashMap
<
AutoConfigurationClass
,
AutoConfigurationClass
>();
for
(
AutoConfigurationClass
current
:
autoConfigurationClasses
)
{
tosort
.
put
(
current
,
current
);
}
addAftersFromBefores
(
tosort
);
Set
<
AutoConfigurationClass
>
sorted
=
new
LinkedHashSet
<
AutoConfigurationClass
>();
Set
<
AutoConfigurationClass
>
sorted
=
new
LinkedHashSet
<
AutoConfigurationClass
>();
Set
<
AutoConfigurationClass
>
processing
=
new
LinkedHashSet
<
AutoConfigurationClass
>();
Set
<
AutoConfigurationClass
>
processing
=
new
LinkedHashSet
<
AutoConfigurationClass
>();
while
(!
tosort
.
isEmpty
())
{
while
(!
tosort
.
isEmpty
())
{
doSortByAfterAnnotation
(
tosort
,
sorted
,
processing
,
null
);
doSortByAfterAnnotation
(
tosort
,
sorted
,
processing
,
null
);
}
}
return
new
ArrayList
<
AutoConfigurationClass
>(
sorted
);
return
new
ArrayList
<
AutoConfigurationClass
>(
sorted
);
}
}
private
void
doSortByAfterAnnotation
(
List
<
AutoConfigurationClass
>
tosort
,
private
void
addAftersFromBefores
(
Map
<
AutoConfigurationClass
,
AutoConfigurationClass
>
map
)
throws
IOException
{
// Pick up any befores and add them to the corresponding after
for
(
AutoConfigurationClass
current
:
map
.
keySet
())
{
for
(
AutoConfigurationClass
before
:
current
.
getBefore
())
{
if
(
map
.
containsKey
(
before
))
{
map
.
get
(
before
).
getAfter
().
add
(
current
);
}
}
}
}
private
void
doSortByAfterAnnotation
(
Map
<
AutoConfigurationClass
,
AutoConfigurationClass
>
tosort
,
Set
<
AutoConfigurationClass
>
sorted
,
Set
<
AutoConfigurationClass
>
processing
,
Set
<
AutoConfigurationClass
>
sorted
,
Set
<
AutoConfigurationClass
>
processing
,
AutoConfigurationClass
current
)
throws
IOException
{
AutoConfigurationClass
current
)
throws
IOException
{
if
(
current
==
null
)
{
if
(
current
==
null
)
{
current
=
tosort
.
remove
(
0
);
current
=
tosort
.
remove
(
tosort
.
keySet
().
iterator
().
next
()
);
}
}
processing
.
add
(
current
);
processing
.
add
(
current
);
...
@@ -97,8 +121,8 @@ class AutoConfigurationSorter {
...
@@ -97,8 +121,8 @@ class AutoConfigurationSorter {
Assert
.
state
(!
processing
.
contains
(
after
),
Assert
.
state
(!
processing
.
contains
(
after
),
"Cycle @AutoConfigureAfter detected between "
+
current
+
" and "
"Cycle @AutoConfigureAfter detected between "
+
current
+
" and "
+
after
);
+
after
);
if
(!
sorted
.
contains
(
after
)
&&
tosort
.
contains
(
after
))
{
if
(!
sorted
.
contains
(
after
)
&&
tosort
.
contains
Key
(
after
))
{
doSortByAfterAnnotation
(
tosort
,
sorted
,
processing
,
after
);
doSortByAfterAnnotation
(
tosort
,
sorted
,
processing
,
tosort
.
get
(
after
)
);
}
}
}
}
...
@@ -110,12 +134,16 @@ class AutoConfigurationSorter {
...
@@ -110,12 +134,16 @@ class AutoConfigurationSorter {
private
final
String
className
;
private
final
String
className
;
private
final
int
order
;
private
int
order
;
private
List
<
AutoConfigurationClass
>
after
;
private
List
<
AutoConfigurationClass
>
after
;
private
List
<
AutoConfigurationClass
>
before
;
private
Map
<
String
,
Object
>
afterAnnotation
;
private
Map
<
String
,
Object
>
afterAnnotation
;
private
Map
<
String
,
Object
>
beforeAnnotation
;
public
AutoConfigurationClass
(
String
className
)
throws
IOException
{
public
AutoConfigurationClass
(
String
className
)
throws
IOException
{
this
.
className
=
className
;
this
.
className
=
className
;
...
@@ -127,12 +155,15 @@ class AutoConfigurationSorter {
...
@@ -127,12 +155,15 @@ class AutoConfigurationSorter {
// Read @Order annotation
// Read @Order annotation
Map
<
String
,
Object
>
orderedAnnotation
=
metadata
Map
<
String
,
Object
>
orderedAnnotation
=
metadata
.
getAnnotationAttributes
(
Order
.
class
.
getName
());
.
getAnnotationAttributes
(
Order
.
class
.
getName
());
this
.
order
=
(
orderedAnnotation
==
null
?
Ordered
.
LOWEST_PRECEDENCE
this
.
order
=
(
orderedAnnotation
==
null
?
0
:
(
Integer
)
orderedAnnotation
:
(
Integer
)
orderedAnnotation
.
get
(
"value"
));
.
get
(
"value"
));
// Read @AutoConfigureAfter annotation
// Read @AutoConfigureAfter annotation
this
.
afterAnnotation
=
metadata
.
getAnnotationAttributes
(
this
.
afterAnnotation
=
metadata
.
getAnnotationAttributes
(
AutoConfigureAfter
.
class
.
getName
(),
true
);
AutoConfigureAfter
.
class
.
getName
(),
true
);
// Read @AutoConfigureBefore annotation
this
.
beforeAnnotation
=
metadata
.
getAnnotationAttributes
(
AutoConfigureBefore
.
class
.
getName
(),
true
);
}
}
@Override
@Override
...
@@ -140,10 +171,14 @@ class AutoConfigurationSorter {
...
@@ -140,10 +171,14 @@ class AutoConfigurationSorter {
return
this
.
order
;
return
this
.
order
;
}
}
public
String
getClassName
()
{
return
this
.
className
;
}
public
List
<
AutoConfigurationClass
>
getAfter
()
throws
IOException
{
public
List
<
AutoConfigurationClass
>
getAfter
()
throws
IOException
{
if
(
this
.
after
==
null
)
{
if
(
this
.
after
==
null
)
{
if
(
this
.
afterAnnotation
==
null
)
{
if
(
this
.
afterAnnotation
==
null
)
{
this
.
after
=
Collections
.
emptyList
();
this
.
after
=
new
ArrayList
<
AutoConfigurationClass
>
();
}
}
else
{
else
{
this
.
after
=
new
ArrayList
<
AutoConfigurationClass
>();
this
.
after
=
new
ArrayList
<
AutoConfigurationClass
>();
...
@@ -155,6 +190,22 @@ class AutoConfigurationSorter {
...
@@ -155,6 +190,22 @@ class AutoConfigurationSorter {
return
this
.
after
;
return
this
.
after
;
}
}
public
List
<
AutoConfigurationClass
>
getBefore
()
throws
IOException
{
if
(
this
.
before
==
null
)
{
if
(
this
.
beforeAnnotation
==
null
)
{
this
.
before
=
Collections
.
emptyList
();
}
else
{
this
.
before
=
new
ArrayList
<
AutoConfigurationClass
>();
for
(
String
beforeClass
:
(
String
[])
this
.
beforeAnnotation
.
get
(
"value"
))
{
this
.
before
.
add
(
new
AutoConfigurationClass
(
beforeClass
));
}
}
}
return
this
.
before
;
}
@Override
@Override
public
String
toString
()
{
public
String
toString
()
{
return
this
.
className
;
return
this
.
className
;
...
@@ -169,6 +220,7 @@ class AutoConfigurationSorter {
...
@@ -169,6 +220,7 @@ class AutoConfigurationSorter {
public
boolean
equals
(
Object
obj
)
{
public
boolean
equals
(
Object
obj
)
{
return
this
.
className
.
equals
(((
AutoConfigurationClass
)
obj
).
className
);
return
this
.
className
.
equals
(((
AutoConfigurationClass
)
obj
).
className
);
}
}
}
}
}
}
spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/AutoConfigureBefore.java
0 → 100644
View file @
33658c29
/*
* Copyright 2012-2013 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
.
autoconfigure
;
import
java.lang.annotation.ElementType
;
import
java.lang.annotation.Retention
;
import
java.lang.annotation.RetentionPolicy
;
import
java.lang.annotation.Target
;
/**
* Hint for that an {@link EnableAutoConfiguration auto-configuration} should be applied
* after the specified auto-configuration classes.
*
* @author Phillip Webb
*/
@Retention
(
RetentionPolicy
.
RUNTIME
)
@Target
({
ElementType
.
TYPE
})
public
@interface
AutoConfigureBefore
{
Class
<?>[]
value
();
}
spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/AutoConfigurationSorterTest.java
→
spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/AutoConfigurationSorterTest
s
.java
View file @
33658c29
...
@@ -16,20 +16,21 @@
...
@@ -16,20 +16,21 @@
package
org
.
springframework
.
boot
.
autoconfigure
;
package
org
.
springframework
.
boot
.
autoconfigure
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.Arrays
;
import
java.util.List
;
import
java.util.List
;
import
org.hamcrest.Description
;
import
org.hamcrest.Matcher
;
import
org.hamcrest.core.IsEqual
;
import
org.junit.Before
;
import
org.junit.Before
;
import
org.junit.Rule
;
import
org.junit.Rule
;
import
org.junit.Test
;
import
org.junit.Test
;
import
org.junit.rules.ExpectedException
;
import
org.junit.rules.ExpectedException
;
import
org.springframework.boot.autoconfigure.AutoConfigurationSorter
;
import
org.springframework.boot.autoconfigure.AutoConfigureAfter
;
import
org.springframework.core.Ordered
;
import
org.springframework.core.Ordered
;
import
org.springframework.core.annotation.Order
;
import
org.springframework.core.annotation.Order
;
import
org.springframework.core.io.DefaultResourceLoader
;
import
org.springframework.core.io.DefaultResourceLoader
;
import
static
org
.
hamcrest
.
Matchers
.
equalTo
;
import
static
org
.
junit
.
Assert
.
assertThat
;
import
static
org
.
junit
.
Assert
.
assertThat
;
/**
/**
...
@@ -37,7 +38,7 @@ import static org.junit.Assert.assertThat;
...
@@ -37,7 +38,7 @@ import static org.junit.Assert.assertThat;
*
*
* @author Phillip Webb
* @author Phillip Webb
*/
*/
public
class
AutoConfigurationSorterTest
{
public
class
AutoConfigurationSorterTest
s
{
private
static
final
String
LOWEST
=
OrderLowest
.
class
.
getName
();
private
static
final
String
LOWEST
=
OrderLowest
.
class
.
getName
();
private
static
final
String
HIGHEST
=
OrderHighest
.
class
.
getName
();
private
static
final
String
HIGHEST
=
OrderHighest
.
class
.
getName
();
...
@@ -45,6 +46,11 @@ public class AutoConfigurationSorterTest {
...
@@ -45,6 +46,11 @@ public class AutoConfigurationSorterTest {
private
static
final
String
B
=
AutoConfigureB
.
class
.
getName
();
private
static
final
String
B
=
AutoConfigureB
.
class
.
getName
();
private
static
final
String
C
=
AutoConfigureC
.
class
.
getName
();
private
static
final
String
C
=
AutoConfigureC
.
class
.
getName
();
private
static
final
String
D
=
AutoConfigureD
.
class
.
getName
();
private
static
final
String
D
=
AutoConfigureD
.
class
.
getName
();
private
static
final
String
E
=
AutoConfigureE
.
class
.
getName
();
private
static
final
String
W
=
AutoConfigureW
.
class
.
getName
();
private
static
final
String
X
=
AutoConfigureX
.
class
.
getName
();
private
static
final
String
Y
=
AutoConfigureY
.
class
.
getName
();
private
static
final
String
Z
=
AutoConfigureZ
.
class
.
getName
();
@Rule
@Rule
public
ExpectedException
thrown
=
ExpectedException
.
none
();
public
ExpectedException
thrown
=
ExpectedException
.
none
();
...
@@ -60,19 +66,38 @@ public class AutoConfigurationSorterTest {
...
@@ -60,19 +66,38 @@ public class AutoConfigurationSorterTest {
public
void
byOrderAnnotation
()
throws
Exception
{
public
void
byOrderAnnotation
()
throws
Exception
{
List
<
String
>
actual
=
this
.
sorter
.
getInPriorityOrder
(
Arrays
.
asList
(
LOWEST
,
List
<
String
>
actual
=
this
.
sorter
.
getInPriorityOrder
(
Arrays
.
asList
(
LOWEST
,
HIGHEST
));
HIGHEST
));
assertThat
(
actual
,
equalTo
(
Arrays
.
asList
(
HIGHEST
,
LOWEST
)
));
assertThat
(
actual
,
nameMatcher
(
HIGHEST
,
LOWEST
));
}
}
@Test
@Test
public
void
byAutoConfigureAfter
()
throws
Exception
{
public
void
byAutoConfigureAfter
()
throws
Exception
{
List
<
String
>
actual
=
this
.
sorter
.
getInPriorityOrder
(
Arrays
.
asList
(
A
,
B
,
C
));
List
<
String
>
actual
=
this
.
sorter
.
getInPriorityOrder
(
Arrays
.
asList
(
A
,
B
,
C
));
assertThat
(
actual
,
equalTo
(
Arrays
.
asList
(
C
,
B
,
A
)));
assertThat
(
actual
,
nameMatcher
(
C
,
B
,
A
));
}
@Test
public
void
byAutoConfigureBefore
()
throws
Exception
{
List
<
String
>
actual
=
this
.
sorter
.
getInPriorityOrder
(
Arrays
.
asList
(
X
,
Y
,
Z
));
assertThat
(
actual
,
nameMatcher
(
Z
,
Y
,
X
));
}
@Test
public
void
byAutoConfigureAfterDoubles
()
throws
Exception
{
List
<
String
>
actual
=
this
.
sorter
.
getInPriorityOrder
(
Arrays
.
asList
(
A
,
B
,
C
,
E
));
assertThat
(
actual
,
nameMatcher
(
C
,
E
,
B
,
A
));
}
@Test
public
void
byAutoConfigureMixedBeforeAndAfter
()
throws
Exception
{
List
<
String
>
actual
=
this
.
sorter
.
getInPriorityOrder
(
Arrays
.
asList
(
A
,
B
,
C
,
W
,
X
));
assertThat
(
actual
,
nameMatcher
(
C
,
W
,
B
,
A
,
X
));
}
}
@Test
@Test
public
void
byAutoConfigureAfterWithMissing
()
throws
Exception
{
public
void
byAutoConfigureAfterWithMissing
()
throws
Exception
{
List
<
String
>
actual
=
this
.
sorter
.
getInPriorityOrder
(
Arrays
.
asList
(
A
,
B
));
List
<
String
>
actual
=
this
.
sorter
.
getInPriorityOrder
(
Arrays
.
asList
(
A
,
B
));
assertThat
(
actual
,
equalTo
(
Arrays
.
asList
(
B
,
A
)
));
assertThat
(
actual
,
nameMatcher
(
B
,
A
));
}
}
@Test
@Test
...
@@ -82,6 +107,39 @@ public class AutoConfigurationSorterTest {
...
@@ -82,6 +107,39 @@ public class AutoConfigurationSorterTest {
this
.
sorter
.
getInPriorityOrder
(
Arrays
.
asList
(
A
,
B
,
C
,
D
));
this
.
sorter
.
getInPriorityOrder
(
Arrays
.
asList
(
A
,
B
,
C
,
D
));
}
}
private
Matcher
<?
super
List
<
String
>>
nameMatcher
(
String
...
names
)
{
final
List
<
String
>
list
=
Arrays
.
asList
(
names
);
return
new
IsEqual
<
List
<
String
>>(
list
)
{
@Override
public
void
describeMismatch
(
Object
item
,
Description
description
)
{
@SuppressWarnings
(
"unchecked"
)
List
<
String
>
items
=
(
List
<
String
>)
item
;
description
.
appendText
(
"was "
).
appendValue
(
prettify
(
items
));
}
@Override
public
void
describeTo
(
Description
description
)
{
description
.
appendValue
(
prettify
(
list
));
}
private
String
prettify
(
List
<
String
>
items
)
{
List
<
String
>
pretty
=
new
ArrayList
<
String
>();
for
(
String
item
:
items
)
{
if
(
item
.
contains
(
"$AutoConfigure"
))
{
item
=
item
.
substring
(
item
.
indexOf
(
"$AutoConfigure"
)
+
"$AutoConfigure"
.
length
());
}
pretty
.
add
(
item
);
}
return
pretty
.
toString
();
}
};
}
@Order
(
Ordered
.
LOWEST_PRECEDENCE
)
@Order
(
Ordered
.
LOWEST_PRECEDENCE
)
public
static
class
OrderLowest
{
public
static
class
OrderLowest
{
}
}
...
@@ -94,7 +152,8 @@ public class AutoConfigurationSorterTest {
...
@@ -94,7 +152,8 @@ public class AutoConfigurationSorterTest {
public
static
class
AutoConfigureA
{
public
static
class
AutoConfigureA
{
}
}
@AutoConfigureAfter
({
AutoConfigureC
.
class
,
AutoConfigureD
.
class
})
@AutoConfigureAfter
({
AutoConfigureC
.
class
,
AutoConfigureD
.
class
,
AutoConfigureE
.
class
})
public
static
class
AutoConfigureB
{
public
static
class
AutoConfigureB
{
}
}
...
@@ -104,4 +163,23 @@ public class AutoConfigurationSorterTest {
...
@@ -104,4 +163,23 @@ public class AutoConfigurationSorterTest {
@AutoConfigureAfter
(
AutoConfigureA
.
class
)
@AutoConfigureAfter
(
AutoConfigureA
.
class
)
public
static
class
AutoConfigureD
{
public
static
class
AutoConfigureD
{
}
}
public
static
class
AutoConfigureE
{
}
@AutoConfigureBefore
(
AutoConfigureB
.
class
)
public
static
class
AutoConfigureW
{
}
public
static
class
AutoConfigureX
{
}
@AutoConfigureBefore
(
AutoConfigureX
.
class
)
public
static
class
AutoConfigureY
{
}
@AutoConfigureBefore
(
AutoConfigureY
.
class
)
public
static
class
AutoConfigureZ
{
}
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment