24
24
import java .util .Set ;
25
25
import java .util .concurrent .ConcurrentHashMap ;
26
26
27
+ import org .springframework .aot .AotDetector ;
27
28
import org .springframework .beans .BeansException ;
28
29
import org .springframework .beans .factory .BeanFactoryUtils ;
29
30
import org .springframework .beans .factory .DisposableBean ;
35
36
import org .springframework .context .ApplicationContextAware ;
36
37
import org .springframework .context .ConfigurableApplicationContext ;
37
38
import org .springframework .context .annotation .AnnotationConfigApplicationContext ;
39
+ import org .springframework .context .annotation .AnnotationConfigRegistry ;
40
+ import org .springframework .context .support .GenericApplicationContext ;
38
41
import org .springframework .core .ResolvableType ;
39
42
import org .springframework .core .env .MapPropertySource ;
43
+ import org .springframework .util .Assert ;
40
44
41
45
/**
42
46
* Creates a set of child contexts that allows a set of Specifications to define the beans
48
52
* @author Spencer Gibb
49
53
* @author Dave Syer
50
54
* @author Tommy Karlsson
55
+ * @author Olga Maciaszek-Sharma
51
56
*/
52
- // TODO: add javadoc
53
57
public abstract class NamedContextFactory <C extends NamedContextFactory .Specification >
54
58
implements DisposableBean , ApplicationContextAware {
55
59
56
60
private final String propertySourceName ;
57
61
58
62
private final String propertyName ;
59
63
60
- private Map <String , AnnotationConfigApplicationContext > contexts = new ConcurrentHashMap <>();
64
+ private final Map <String , GenericApplicationContext > contexts = new ConcurrentHashMap <>();
61
65
62
66
private Map <String , C > configurations = new ConcurrentHashMap <>();
63
67
@@ -92,16 +96,16 @@ public Set<String> getContextNames() {
92
96
93
97
@ Override
94
98
public void destroy () {
95
- Collection <AnnotationConfigApplicationContext > values = this .contexts .values ();
96
- for (AnnotationConfigApplicationContext context : values ) {
99
+ Collection <GenericApplicationContext > values = this .contexts .values ();
100
+ for (GenericApplicationContext context : values ) {
97
101
// This can fail, but it never throws an exception (you see stack traces
98
102
// logged as WARN).
99
103
context .close ();
100
104
}
101
105
this .contexts .clear ();
102
106
}
103
107
104
- protected AnnotationConfigApplicationContext getContext (String name ) {
108
+ protected GenericApplicationContext getContext (String name ) {
105
109
if (!this .contexts .containsKey (name )) {
106
110
synchronized (this .contexts ) {
107
111
if (!this .contexts .containsKey (name )) {
@@ -112,8 +116,39 @@ protected AnnotationConfigApplicationContext getContext(String name) {
112
116
return this .contexts .get (name );
113
117
}
114
118
115
- protected AnnotationConfigApplicationContext createContext (String name ) {
116
- AnnotationConfigApplicationContext context ;
119
+ public void addContext (String contextId , GenericApplicationContext context ) {
120
+ Assert .notNull (contextId , "contextId cannot be null." );
121
+ Assert .notNull (context , "context cannot be null." );
122
+ contexts .put (contextId , context );
123
+ }
124
+
125
+ public GenericApplicationContext createContext (String name ) {
126
+ GenericApplicationContext context = buildContext (name );
127
+ registerBeans (name , context );
128
+ context .refresh ();
129
+ return context ;
130
+ }
131
+
132
+ public void registerBeans (String name , GenericApplicationContext context ) {
133
+ Assert .isInstanceOf (AnnotationConfigRegistry .class , context );
134
+ AnnotationConfigRegistry registry = (AnnotationConfigRegistry ) context ;
135
+ if (this .configurations .containsKey (name )) {
136
+ for (Class <?> configuration : this .configurations .get (name ).getConfiguration ()) {
137
+ registry .register (configuration );
138
+ }
139
+ }
140
+ for (Map .Entry <String , C > entry : this .configurations .entrySet ()) {
141
+ if (entry .getKey ().startsWith ("default." )) {
142
+ for (Class <?> configuration : entry .getValue ().getConfiguration ()) {
143
+ registry .register (configuration );
144
+ }
145
+ }
146
+ }
147
+ registry .register (PropertyPlaceholderAutoConfiguration .class , this .defaultConfigType );
148
+ }
149
+
150
+ public GenericApplicationContext buildContext (String name ) {
151
+ GenericApplicationContext context ;
117
152
if (this .parent != null ) {
118
153
// jdk11 issue
119
154
// https://github.com/spring-cloud/spring-cloud-netflix/issues/3101
@@ -126,33 +161,21 @@ protected AnnotationConfigApplicationContext createContext(String name) {
126
161
else {
127
162
beanFactory .setBeanClassLoader (parent .getClassLoader ());
128
163
}
129
- context = new AnnotationConfigApplicationContext (beanFactory );
130
- context .setClassLoader (this .parent .getClassLoader ());
164
+ context = AotDetector .useGeneratedArtifacts () ? new GenericApplicationContext (beanFactory )
165
+ : new AnnotationConfigApplicationContext (beanFactory );
166
+ context .setClassLoader (parent .getClassLoader ());
131
167
}
132
168
else {
133
- context = new AnnotationConfigApplicationContext ();
134
- }
135
- if (this .configurations .containsKey (name )) {
136
- for (Class <?> configuration : this .configurations .get (name ).getConfiguration ()) {
137
- context .register (configuration );
138
- }
169
+ context = AotDetector .useGeneratedArtifacts () ? new GenericApplicationContext ()
170
+ : new AnnotationConfigApplicationContext ();
139
171
}
140
- for (Map .Entry <String , C > entry : this .configurations .entrySet ()) {
141
- if (entry .getKey ().startsWith ("default." )) {
142
- for (Class <?> configuration : entry .getValue ().getConfiguration ()) {
143
- context .register (configuration );
144
- }
145
- }
146
- }
147
- context .register (PropertyPlaceholderAutoConfiguration .class , this .defaultConfigType );
148
- context .getEnvironment ().getPropertySources ().addFirst (new MapPropertySource (this .propertySourceName ,
149
- Collections .<String , Object >singletonMap (this .propertyName , name )));
172
+ context .getEnvironment ().getPropertySources ().addFirst (
173
+ new MapPropertySource (this .propertySourceName , Collections .singletonMap (this .propertyName , name )));
150
174
if (this .parent != null ) {
151
175
// Uses Environment from parent as well as beans
152
176
context .setParent (this .parent );
153
177
}
154
178
context .setDisplayName (generateDisplayName (name ));
155
- context .refresh ();
156
179
return context ;
157
180
}
158
181
@@ -161,7 +184,7 @@ protected String generateDisplayName(String name) {
161
184
}
162
185
163
186
public <T > T getInstance (String name , Class <T > type ) {
164
- AnnotationConfigApplicationContext context = getContext (name );
187
+ GenericApplicationContext context = getContext (name );
165
188
try {
166
189
return context .getBean (type );
167
190
}
@@ -176,7 +199,7 @@ public <T> ObjectProvider<T> getLazyProvider(String name, Class<T> type) {
176
199
}
177
200
178
201
public <T > ObjectProvider <T > getProvider (String name , Class <T > type ) {
179
- AnnotationConfigApplicationContext context = getContext (name );
202
+ GenericApplicationContext context = getContext (name );
180
203
return context .getBeanProvider (type );
181
204
}
182
205
@@ -187,7 +210,7 @@ public <T> T getInstance(String name, Class<?> clazz, Class<?>... generics) {
187
210
188
211
@ SuppressWarnings ("unchecked" )
189
212
public <T > T getInstance (String name , ResolvableType type ) {
190
- AnnotationConfigApplicationContext context = getContext (name );
213
+ GenericApplicationContext context = getContext (name );
191
214
String [] beanNames = BeanFactoryUtils .beanNamesForTypeIncludingAncestors (context , type );
192
215
if (beanNames .length > 0 ) {
193
216
for (String beanName : beanNames ) {
@@ -200,11 +223,15 @@ public <T> T getInstance(String name, ResolvableType type) {
200
223
}
201
224
202
225
public <T > Map <String , T > getInstances (String name , Class <T > type ) {
203
- AnnotationConfigApplicationContext context = getContext (name );
226
+ GenericApplicationContext context = getContext (name );
204
227
205
228
return BeanFactoryUtils .beansOfTypeIncludingAncestors (context , type );
206
229
}
207
230
231
+ public Map <String , C > getConfigurations () {
232
+ return configurations ;
233
+ }
234
+
208
235
/**
209
236
* Specification with name and configuration.
210
237
*/
0 commit comments