Spring-IoC容器源码导读

1.几个重要类/接口

阅读前的准备

1.1 BeanFactory 顶级接口(低配版的IoC容器)

BeanFactory接口定义说明

  • BeanFactory是低配版的IoC容器,定义了Ioc容器基本的功能

完整版源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
/*
* Copyright 2002-2019 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
*
* https://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.beans.factory;

import org.springframework.beans.BeansException;
import org.springframework.core.ResolvableType;
import org.springframework.lang.Nullable;

/**
* The root interface for accessing a Spring bean container.
* This is the basic client view of a bean container;
* further interfaces such as {@link ListableBeanFactory} and
* {@link org.springframework.beans.factory.config.ConfigurableBeanFactory}
* are available for specific purposes.
*
* <p>This interface is implemented by objects that hold a number of bean definitions,
* each uniquely identified by a String name. Depending on the bean definition,
* the factory will return either an independent instance of a contained object
* (the Prototype design pattern), or a single shared instance (a superior
* alternative to the Singleton design pattern, in which the instance is a
* singleton in the scope of the factory). Which type of instance will be returned
* depends on the bean factory configuration: the API is the same. Since Spring
* 2.0, further scopes are available depending on the concrete application
* context (e.g. "request" and "session" scopes in a web environment).
*
* <p>The point of this approach is that the BeanFactory is a central registry
* of application components, and centralizes configuration of application
* components (no more do individual objects need to read properties files,
* for example). See chapters 4 and 11 of "Expert One-on-One J2EE Design and
* Development" for a discussion of the benefits of this approach.
*
* <p>Note that it is generally better to rely on Dependency Injection
* ("push" configuration) to configure application objects through setters
* or constructors, rather than use any form of "pull" configuration like a
* BeanFactory lookup. Spring's Dependency Injection functionality is
* implemented using this BeanFactory interface and its subinterfaces.
*
* <p>Normally a BeanFactory will load bean definitions stored in a configuration
* source (such as an XML document), and use the {@code org.springframework.beans}
* package to configure the beans. However, an implementation could simply return
* Java objects it creates as necessary directly in Java code. There are no
* constraints on how the definitions could be stored: LDAP, RDBMS, XML,
* properties file, etc. Implementations are encouraged to support references
* amongst beans (Dependency Injection).
*
* <p>In contrast to the methods in {@link ListableBeanFactory}, all of the
* operations in this interface will also check parent factories if this is a
* {@link HierarchicalBeanFactory}. If a bean is not found in this factory instance,
* the immediate parent factory will be asked. Beans in this factory instance
* are supposed to override beans of the same name in any parent factory.
*
* <p>Bean factory implementations should support the standard bean lifecycle interfaces
* as far as possible. The full set of initialization methods and their standard order is:
* <ol>
* <li>BeanNameAware's {@code setBeanName}
* <li>BeanClassLoaderAware's {@code setBeanClassLoader}
* <li>BeanFactoryAware's {@code setBeanFactory}
* <li>EnvironmentAware's {@code setEnvironment}
* <li>EmbeddedValueResolverAware's {@code setEmbeddedValueResolver}
* <li>ResourceLoaderAware's {@code setResourceLoader}
* (only applicable when running in an application context)
* <li>ApplicationEventPublisherAware's {@code setApplicationEventPublisher}
* (only applicable when running in an application context)
* <li>MessageSourceAware's {@code setMessageSource}
* (only applicable when running in an application context)
* <li>ApplicationContextAware's {@code setApplicationContext}
* (only applicable when running in an application context)
* <li>ServletContextAware's {@code setServletContext}
* (only applicable when running in a web application context)
* <li>{@code postProcessBeforeInitialization} methods of BeanPostProcessors
* <li>InitializingBean's {@code afterPropertiesSet}
* <li>a custom init-method definition
* <li>{@code postProcessAfterInitialization} methods of BeanPostProcessors
* </ol>
*
* <p>On shutdown of a bean factory, the following lifecycle methods apply:
* <ol>
* <li>{@code postProcessBeforeDestruction} methods of DestructionAwareBeanPostProcessors
* <li>DisposableBean's {@code destroy}
* <li>a custom destroy-method definition
* </ol>
*
* @author Rod Johnson
* @author Juergen Hoeller
* @author Chris Beams
* @since 13 April 2001
* @see BeanNameAware#setBeanName
* @see BeanClassLoaderAware#setBeanClassLoader
* @see BeanFactoryAware#setBeanFactory
* @see org.springframework.context.ResourceLoaderAware#setResourceLoader
* @see org.springframework.context.ApplicationEventPublisherAware#setApplicationEventPublisher
* @see org.springframework.context.MessageSourceAware#setMessageSource
* @see org.springframework.context.ApplicationContextAware#setApplicationContext
* @see org.springframework.web.context.ServletContextAware#setServletContext
* @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessBeforeInitialization
* @see InitializingBean#afterPropertiesSet
* @see org.springframework.beans.factory.support.RootBeanDefinition#getInitMethodName
* @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessAfterInitialization
* @see DisposableBean#destroy
* @see org.springframework.beans.factory.support.RootBeanDefinition#getDestroyMethodName
*/
public interface BeanFactory {

/**
* Used to dereference a {@link FactoryBean} instance and distinguish it from
* beans <i>created</i> by the FactoryBean. For example, if the bean named
* {@code myJndiObject} is a FactoryBean, getting {@code &myJndiObject}
* will return the factory, not the instance returned by the factory.
*/
String FACTORY_BEAN_PREFIX = "&";


/**
* Return an instance, which may be shared or independent, of the specified bean.
* <p>This method allows a Spring BeanFactory to be used as a replacement for the
* Singleton or Prototype design pattern. Callers may retain references to
* returned objects in the case of Singleton beans.
* <p>Translates aliases back to the corresponding canonical bean name.
* Will ask the parent factory if the bean cannot be found in this factory instance.
* @param name the name of the bean to retrieve
* @return an instance of the bean
* @throws NoSuchBeanDefinitionException if there is no bean with the specified name
* @throws BeansException if the bean could not be obtained
*/
Object getBean(String name) throws BeansException;

/**
* Return an instance, which may be shared or independent, of the specified bean.
* <p>Behaves the same as {@link #getBean(String)}, but provides a measure of type
* safety by throwing a BeanNotOfRequiredTypeException if the bean is not of the
* required type. This means that ClassCastException can't be thrown on casting
* the result correctly, as can happen with {@link #getBean(String)}.
* <p>Translates aliases back to the corresponding canonical bean name.
* Will ask the parent factory if the bean cannot be found in this factory instance.
* @param name the name of the bean to retrieve
* @param requiredType type the bean must match; can be an interface or superclass
* @return an instance of the bean
* @throws NoSuchBeanDefinitionException if there is no such bean definition
* @throws BeanNotOfRequiredTypeException if the bean is not of the required type
* @throws BeansException if the bean could not be created
*/
<T> T getBean(String name, Class<T> requiredType) throws BeansException;

/**
* Return an instance, which may be shared or independent, of the specified bean.
* <p>Allows for specifying explicit constructor arguments / factory method arguments,
* overriding the specified default arguments (if any) in the bean definition.
* @param name the name of the bean to retrieve
* @param args arguments to use when creating a bean instance using explicit arguments
* (only applied when creating a new instance as opposed to retrieving an existing one)
* @return an instance of the bean
* @throws NoSuchBeanDefinitionException if there is no such bean definition
* @throws BeanDefinitionStoreException if arguments have been given but
* the affected bean isn't a prototype
* @throws BeansException if the bean could not be created
* @since 2.5
*/
Object getBean(String name, Object... args) throws BeansException;

/**
* Return the bean instance that uniquely matches the given object type, if any.
* <p>This method goes into {@link ListableBeanFactory} by-type lookup territory
* but may also be translated into a conventional by-name lookup based on the name
* of the given type. For more extensive retrieval operations across sets of beans,
* use {@link ListableBeanFactory} and/or {@link BeanFactoryUtils}.
* @param requiredType type the bean must match; can be an interface or superclass
* @return an instance of the single bean matching the required type
* @throws NoSuchBeanDefinitionException if no bean of the given type was found
* @throws NoUniqueBeanDefinitionException if more than one bean of the given type was found
* @throws BeansException if the bean could not be created
* @since 3.0
* @see ListableBeanFactory
*/
<T> T getBean(Class<T> requiredType) throws BeansException;

/**
* Return an instance, which may be shared or independent, of the specified bean.
* <p>Allows for specifying explicit constructor arguments / factory method arguments,
* overriding the specified default arguments (if any) in the bean definition.
* <p>This method goes into {@link ListableBeanFactory} by-type lookup territory
* but may also be translated into a conventional by-name lookup based on the name
* of the given type. For more extensive retrieval operations across sets of beans,
* use {@link ListableBeanFactory} and/or {@link BeanFactoryUtils}.
* @param requiredType type the bean must match; can be an interface or superclass
* @param args arguments to use when creating a bean instance using explicit arguments
* (only applied when creating a new instance as opposed to retrieving an existing one)
* @return an instance of the bean
* @throws NoSuchBeanDefinitionException if there is no such bean definition
* @throws BeanDefinitionStoreException if arguments have been given but
* the affected bean isn't a prototype
* @throws BeansException if the bean could not be created
* @since 4.1
*/
<T> T getBean(Class<T> requiredType, Object... args) throws BeansException;

/**
* Return a provider for the specified bean, allowing for lazy on-demand retrieval
* of instances, including availability and uniqueness options.
* @param requiredType type the bean must match; can be an interface or superclass
* @return a corresponding provider handle
* @since 5.1
* @see #getBeanProvider(ResolvableType)
*/
<T> ObjectProvider<T> getBeanProvider(Class<T> requiredType);

/**
* Return a provider for the specified bean, allowing for lazy on-demand retrieval
* of instances, including availability and uniqueness options.
* @param requiredType type the bean must match; can be a generic type declaration.
* Note that collection types are not supported here, in contrast to reflective
* injection points. For programmatically retrieving a list of beans matching a
* specific type, specify the actual bean type as an argument here and subsequently
* use {@link ObjectProvider#orderedStream()} or its lazy streaming/iteration options.
* @return a corresponding provider handle
* @since 5.1
* @see ObjectProvider#iterator()
* @see ObjectProvider#stream()
* @see ObjectProvider#orderedStream()
*/
<T> ObjectProvider<T> getBeanProvider(ResolvableType requiredType);

/**
* Does this bean factory contain a bean definition or externally registered singleton
* instance with the given name?
* <p>If the given name is an alias, it will be translated back to the corresponding
* canonical bean name.
* <p>If this factory is hierarchical, will ask any parent factory if the bean cannot
* be found in this factory instance.
* <p>If a bean definition or singleton instance matching the given name is found,
* this method will return {@code true} whether the named bean definition is concrete
* or abstract, lazy or eager, in scope or not. Therefore, note that a {@code true}
* return value from this method does not necessarily indicate that {@link #getBean}
* will be able to obtain an instance for the same name.
* @param name the name of the bean to query
* @return whether a bean with the given name is present
*/
boolean containsBean(String name);

/**
* Is this bean a shared singleton? That is, will {@link #getBean} always
* return the same instance?
* <p>Note: This method returning {@code false} does not clearly indicate
* independent instances. It indicates non-singleton instances, which may correspond
* to a scoped bean as well. Use the {@link #isPrototype} operation to explicitly
* check for independent instances.
* <p>Translates aliases back to the corresponding canonical bean name.
* Will ask the parent factory if the bean cannot be found in this factory instance.
* @param name the name of the bean to query
* @return whether this bean corresponds to a singleton instance
* @throws NoSuchBeanDefinitionException if there is no bean with the given name
* @see #getBean
* @see #isPrototype
*/
boolean isSingleton(String name) throws NoSuchBeanDefinitionException;

/**
* Is this bean a prototype? That is, will {@link #getBean} always return
* independent instances?
* <p>Note: This method returning {@code false} does not clearly indicate
* a singleton object. It indicates non-independent instances, which may correspond
* to a scoped bean as well. Use the {@link #isSingleton} operation to explicitly
* check for a shared singleton instance.
* <p>Translates aliases back to the corresponding canonical bean name.
* Will ask the parent factory if the bean cannot be found in this factory instance.
* @param name the name of the bean to query
* @return whether this bean will always deliver independent instances
* @throws NoSuchBeanDefinitionException if there is no bean with the given name
* @since 2.0.3
* @see #getBean
* @see #isSingleton
*/
boolean isPrototype(String name) throws NoSuchBeanDefinitionException;

/**
* Check whether the bean with the given name matches the specified type.
* More specifically, check whether a {@link #getBean} call for the given name
* would return an object that is assignable to the specified target type.
* <p>Translates aliases back to the corresponding canonical bean name.
* Will ask the parent factory if the bean cannot be found in this factory instance.
* @param name the name of the bean to query
* @param typeToMatch the type to match against (as a {@code ResolvableType})
* @return {@code true} if the bean type matches,
* {@code false} if it doesn't match or cannot be determined yet
* @throws NoSuchBeanDefinitionException if there is no bean with the given name
* @since 4.2
* @see #getBean
* @see #getType
*/
boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException;

/**
* Check whether the bean with the given name matches the specified type.
* More specifically, check whether a {@link #getBean} call for the given name
* would return an object that is assignable to the specified target type.
* <p>Translates aliases back to the corresponding canonical bean name.
* Will ask the parent factory if the bean cannot be found in this factory instance.
* @param name the name of the bean to query
* @param typeToMatch the type to match against (as a {@code Class})
* @return {@code true} if the bean type matches,
* {@code false} if it doesn't match or cannot be determined yet
* @throws NoSuchBeanDefinitionException if there is no bean with the given name
* @since 2.0.1
* @see #getBean
* @see #getType
*/
boolean isTypeMatch(String name, Class<?> typeToMatch) throws NoSuchBeanDefinitionException;

/**
* Determine the type of the bean with the given name. More specifically,
* determine the type of object that {@link #getBean} would return for the given name.
* <p>For a {@link FactoryBean}, return the type of object that the FactoryBean creates,
* as exposed by {@link FactoryBean#getObjectType()}. This may lead to the initialization
* of a previously uninitialized {@code FactoryBean} (see {@link #getType(String, boolean)}).
* <p>Translates aliases back to the corresponding canonical bean name.
* Will ask the parent factory if the bean cannot be found in this factory instance.
* @param name the name of the bean to query
* @return the type of the bean, or {@code null} if not determinable
* @throws NoSuchBeanDefinitionException if there is no bean with the given name
* @since 1.1.2
* @see #getBean
* @see #isTypeMatch
*/
@Nullable
Class<?> getType(String name) throws NoSuchBeanDefinitionException;

/**
* Determine the type of the bean with the given name. More specifically,
* determine the type of object that {@link #getBean} would return for the given name.
* <p>For a {@link FactoryBean}, return the type of object that the FactoryBean creates,
* as exposed by {@link FactoryBean#getObjectType()}. Depending on the
* {@code allowFactoryBeanInit} flag, this may lead to the initialization of a previously
* uninitialized {@code FactoryBean} if no early type information is available.
* <p>Translates aliases back to the corresponding canonical bean name.
* Will ask the parent factory if the bean cannot be found in this factory instance.
* @param name the name of the bean to query
* @param allowFactoryBeanInit whether a {@code FactoryBean} may get initialized
* just for the purpose of determining its object type
* @return the type of the bean, or {@code null} if not determinable
* @throws NoSuchBeanDefinitionException if there is no bean with the given name
* @since 5.2
* @see #getBean
* @see #isTypeMatch
*/
@Nullable
Class<?> getType(String name, boolean allowFactoryBeanInit) throws NoSuchBeanDefinitionException;

/**
* Return the aliases for the given bean name, if any.
* All of those aliases point to the same bean when used in a {@link #getBean} call.
* <p>If the given name is an alias, the corresponding original bean name
* and other aliases (if any) will be returned, with the original bean name
* being the first element in the array.
* <p>Will ask the parent factory if the bean cannot be found in this factory instance.
* @param name the bean name to check for aliases
* @return the aliases, or an empty array if none
* @see #getBean
*/
String[] getAliases(String name);

}

BeanFactory方法属性摘要

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
public interface BeanFactory {

/**
*/
String FACTORY_BEAN_PREFIX = "&";


/**
*/
Object getBean(String name) throws BeansException;

/**
*/
<T> T getBean(String name, Class<T> requiredType) throws BeansException;

/**
*/
Object getBean(String name, Object... args) throws BeansException;

/**
*/
<T> T getBean(Class<T> requiredType) throws BeansException;

/**
*/
<T> T getBean(Class<T> requiredType, Object... args) throws BeansException;

/**
*/
<T> ObjectProvider<T> getBeanProvider(Class<T> requiredType);

/**
*/
<T> ObjectProvider<T> getBeanProvider(ResolvableType requiredType);

/**
*/
boolean containsBean(String name);

/**
*/
boolean isSingleton(String name) throws NoSuchBeanDefinitionException;

/**
*/
boolean isPrototype(String name) throws NoSuchBeanDefinitionException;

/**
*/
boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException;

/**
*/
boolean isTypeMatch(String name, Class<?> typeToMatch) throws NoSuchBeanDefinitionException;

/**
*/
@Nullable
Class<?> getType(String name) throws NoSuchBeanDefinitionException;

/**
*/
@Nullable
Class<?> getType(String name, boolean allowFactoryBeanInit) throws NoSuchBeanDefinitionException;

/**
*/
String[] getAliases(String name);

}

1.2 HierarchicalBeanFactory接口

完整版源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
/*
* Copyright 2002-2012 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
*
* https://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.beans.factory;

import org.springframework.lang.Nullable;

/**
* Sub-interface implemented by bean factories that can be part
* of a hierarchy.
*
* <p>The corresponding {@code setParentBeanFactory} method for bean
* factories that allow setting the parent in a configurable
* fashion can be found in the ConfigurableBeanFactory interface.
*
* @author Rod Johnson
* @author Juergen Hoeller
* @since 07.07.2003
* @see org.springframework.beans.factory.config.ConfigurableBeanFactory#setParentBeanFactory
*/
public interface HierarchicalBeanFactory extends BeanFactory {

/**
* Return the parent bean factory, or {@code null} if there is none.
*/
@Nullable
BeanFactory getParentBeanFactory();

/**
* Return whether the local bean factory contains a bean of the given name,
* ignoring beans defined in ancestor contexts.
* <p>This is an alternative to {@code containsBean}, ignoring a bean
* of the given name from an ancestor bean factory.
* @param name the name of the bean to query
* @return whether a bean with the given name is defined in the local factory
* @see BeanFactory#containsBean
*/
boolean containsLocalBean(String name);

}

HierarchicalBeanFactory方法属性摘要

1
2
3
4
5
6
7
8
9
10
11
12
public interface HierarchicalBeanFactory extends BeanFactory {

/**
*/
@Nullable
BeanFactory getParentBeanFactory();

/**
*/
boolean containsLocalBean(String name);

}

1.3 ListableBeanFactory接口

完整版源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
/*
* Copyright 2002-2019 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
*
* https://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.beans.factory;

import java.lang.annotation.Annotation;
import java.util.Map;

import org.springframework.beans.BeansException;
import org.springframework.core.ResolvableType;
import org.springframework.lang.Nullable;

/**
* Extension of the {@link BeanFactory} interface to be implemented by bean factories
* that can enumerate all their bean instances, rather than attempting bean lookup
* by name one by one as requested by clients. BeanFactory implementations that
* preload all their bean definitions (such as XML-based factories) may implement
* this interface.
*
* <p>If this is a {@link HierarchicalBeanFactory}, the return values will <i>not</i>
* take any BeanFactory hierarchy into account, but will relate only to the beans
* defined in the current factory. Use the {@link BeanFactoryUtils} helper class
* to consider beans in ancestor factories too.
*
* <p>The methods in this interface will just respect bean definitions of this factory.
* They will ignore any singleton beans that have been registered by other means like
* {@link org.springframework.beans.factory.config.ConfigurableBeanFactory}'s
* {@code registerSingleton} method, with the exception of
* {@code getBeanNamesOfType} and {@code getBeansOfType} which will check
* such manually registered singletons too. Of course, BeanFactory's {@code getBean}
* does allow transparent access to such special beans as well. However, in typical
* scenarios, all beans will be defined by external bean definitions anyway, so most
* applications don't need to worry about this differentiation.
*
* <p><b>NOTE:</b> With the exception of {@code getBeanDefinitionCount}
* and {@code containsBeanDefinition}, the methods in this interface
* are not designed for frequent invocation. Implementations may be slow.
*
* @author Rod Johnson
* @author Juergen Hoeller
* @since 16 April 2001
* @see HierarchicalBeanFactory
* @see BeanFactoryUtils
*/
public interface ListableBeanFactory extends BeanFactory {

/**
* Check if this bean factory contains a bean definition with the given name.
* <p>Does not consider any hierarchy this factory may participate in,
* and ignores any singleton beans that have been registered by
* other means than bean definitions.
* @param beanName the name of the bean to look for
* @return if this bean factory contains a bean definition with the given name
* @see #containsBean
*/
boolean containsBeanDefinition(String beanName);

/**
* Return the number of beans defined in the factory.
* <p>Does not consider any hierarchy this factory may participate in,
* and ignores any singleton beans that have been registered by
* other means than bean definitions.
* @return the number of beans defined in the factory
*/
int getBeanDefinitionCount();

/**
* Return the names of all beans defined in this factory.
* <p>Does not consider any hierarchy this factory may participate in,
* and ignores any singleton beans that have been registered by
* other means than bean definitions.
* @return the names of all beans defined in this factory,
* or an empty array if none defined
*/
String[] getBeanDefinitionNames();

/**
* Return the names of beans matching the given type (including subclasses),
* judging from either bean definitions or the value of {@code getObjectType}
* in the case of FactoryBeans.
* <p><b>NOTE: This method introspects top-level beans only.</b> It does <i>not</i>
* check nested beans which might match the specified type as well.
* <p>Does consider objects created by FactoryBeans, which means that FactoryBeans
* will get initialized. If the object created by the FactoryBean doesn't match,
* the raw FactoryBean itself will be matched against the type.
* <p>Does not consider any hierarchy this factory may participate in.
* Use BeanFactoryUtils' {@code beanNamesForTypeIncludingAncestors}
* to include beans in ancestor factories too.
* <p>Note: Does <i>not</i> ignore singleton beans that have been registered
* by other means than bean definitions.
* <p>This version of {@code getBeanNamesForType} matches all kinds of beans,
* be it singletons, prototypes, or FactoryBeans. In most implementations, the
* result will be the same as for {@code getBeanNamesForType(type, true, true)}.
* <p>Bean names returned by this method should always return bean names <i>in the
* order of definition</i> in the backend configuration, as far as possible.
* @param type the generically typed class or interface to match
* @return the names of beans (or objects created by FactoryBeans) matching
* the given object type (including subclasses), or an empty array if none
* @since 4.2
* @see #isTypeMatch(String, ResolvableType)
* @see FactoryBean#getObjectType
* @see BeanFactoryUtils#beanNamesForTypeIncludingAncestors(ListableBeanFactory, ResolvableType)
*/
String[] getBeanNamesForType(ResolvableType type);

/**
* Return the names of beans matching the given type (including subclasses),
* judging from either bean definitions or the value of {@code getObjectType}
* in the case of FactoryBeans.
* <p><b>NOTE: This method introspects top-level beans only.</b> It does <i>not</i>
* check nested beans which might match the specified type as well.
* <p>Does consider objects created by FactoryBeans if the "allowEagerInit" flag is set,
* which means that FactoryBeans will get initialized. If the object created by the
* FactoryBean doesn't match, the raw FactoryBean itself will be matched against the
* type. If "allowEagerInit" is not set, only raw FactoryBeans will be checked
* (which doesn't require initialization of each FactoryBean).
* <p>Does not consider any hierarchy this factory may participate in.
* Use BeanFactoryUtils' {@code beanNamesForTypeIncludingAncestors}
* to include beans in ancestor factories too.
* <p>Note: Does <i>not</i> ignore singleton beans that have been registered
* by other means than bean definitions.
* <p>Bean names returned by this method should always return bean names <i>in the
* order of definition</i> in the backend configuration, as far as possible.
* @param type the generically typed class or interface to match
* @param includeNonSingletons whether to include prototype or scoped beans too
* or just singletons (also applies to FactoryBeans)
* @param allowEagerInit whether to initialize <i>lazy-init singletons</i> and
* <i>objects created by FactoryBeans</i> (or by factory methods with a
* "factory-bean" reference) for the type check. Note that FactoryBeans need to be
* eagerly initialized to determine their type: So be aware that passing in "true"
* for this flag will initialize FactoryBeans and "factory-bean" references.
* @return the names of beans (or objects created by FactoryBeans) matching
* the given object type (including subclasses), or an empty array if none
* @since 5.2
* @see FactoryBean#getObjectType
* @see BeanFactoryUtils#beanNamesForTypeIncludingAncestors(ListableBeanFactory, ResolvableType, boolean, boolean)
*/
String[] getBeanNamesForType(ResolvableType type, boolean includeNonSingletons, boolean allowEagerInit);

/**
* Return the names of beans matching the given type (including subclasses),
* judging from either bean definitions or the value of {@code getObjectType}
* in the case of FactoryBeans.
* <p><b>NOTE: This method introspects top-level beans only.</b> It does <i>not</i>
* check nested beans which might match the specified type as well.
* <p>Does consider objects created by FactoryBeans, which means that FactoryBeans
* will get initialized. If the object created by the FactoryBean doesn't match,
* the raw FactoryBean itself will be matched against the type.
* <p>Does not consider any hierarchy this factory may participate in.
* Use BeanFactoryUtils' {@code beanNamesForTypeIncludingAncestors}
* to include beans in ancestor factories too.
* <p>Note: Does <i>not</i> ignore singleton beans that have been registered
* by other means than bean definitions.
* <p>This version of {@code getBeanNamesForType} matches all kinds of beans,
* be it singletons, prototypes, or FactoryBeans. In most implementations, the
* result will be the same as for {@code getBeanNamesForType(type, true, true)}.
* <p>Bean names returned by this method should always return bean names <i>in the
* order of definition</i> in the backend configuration, as far as possible.
* @param type the class or interface to match, or {@code null} for all bean names
* @return the names of beans (or objects created by FactoryBeans) matching
* the given object type (including subclasses), or an empty array if none
* @see FactoryBean#getObjectType
* @see BeanFactoryUtils#beanNamesForTypeIncludingAncestors(ListableBeanFactory, Class)
*/
String[] getBeanNamesForType(@Nullable Class<?> type);

/**
* Return the names of beans matching the given type (including subclasses),
* judging from either bean definitions or the value of {@code getObjectType}
* in the case of FactoryBeans.
* <p><b>NOTE: This method introspects top-level beans only.</b> It does <i>not</i>
* check nested beans which might match the specified type as well.
* <p>Does consider objects created by FactoryBeans if the "allowEagerInit" flag is set,
* which means that FactoryBeans will get initialized. If the object created by the
* FactoryBean doesn't match, the raw FactoryBean itself will be matched against the
* type. If "allowEagerInit" is not set, only raw FactoryBeans will be checked
* (which doesn't require initialization of each FactoryBean).
* <p>Does not consider any hierarchy this factory may participate in.
* Use BeanFactoryUtils' {@code beanNamesForTypeIncludingAncestors}
* to include beans in ancestor factories too.
* <p>Note: Does <i>not</i> ignore singleton beans that have been registered
* by other means than bean definitions.
* <p>Bean names returned by this method should always return bean names <i>in the
* order of definition</i> in the backend configuration, as far as possible.
* @param type the class or interface to match, or {@code null} for all bean names
* @param includeNonSingletons whether to include prototype or scoped beans too
* or just singletons (also applies to FactoryBeans)
* @param allowEagerInit whether to initialize <i>lazy-init singletons</i> and
* <i>objects created by FactoryBeans</i> (or by factory methods with a
* "factory-bean" reference) for the type check. Note that FactoryBeans need to be
* eagerly initialized to determine their type: So be aware that passing in "true"
* for this flag will initialize FactoryBeans and "factory-bean" references.
* @return the names of beans (or objects created by FactoryBeans) matching
* the given object type (including subclasses), or an empty array if none
* @see FactoryBean#getObjectType
* @see BeanFactoryUtils#beanNamesForTypeIncludingAncestors(ListableBeanFactory, Class, boolean, boolean)
*/
String[] getBeanNamesForType(@Nullable Class<?> type, boolean includeNonSingletons, boolean allowEagerInit);

/**
* Return the bean instances that match the given object type (including
* subclasses), judging from either bean definitions or the value of
* {@code getObjectType} in the case of FactoryBeans.
* <p><b>NOTE: This method introspects top-level beans only.</b> It does <i>not</i>
* check nested beans which might match the specified type as well.
* <p>Does consider objects created by FactoryBeans, which means that FactoryBeans
* will get initialized. If the object created by the FactoryBean doesn't match,
* the raw FactoryBean itself will be matched against the type.
* <p>Does not consider any hierarchy this factory may participate in.
* Use BeanFactoryUtils' {@code beansOfTypeIncludingAncestors}
* to include beans in ancestor factories too.
* <p>Note: Does <i>not</i> ignore singleton beans that have been registered
* by other means than bean definitions.
* <p>This version of getBeansOfType matches all kinds of beans, be it
* singletons, prototypes, or FactoryBeans. In most implementations, the
* result will be the same as for {@code getBeansOfType(type, true, true)}.
* <p>The Map returned by this method should always return bean names and
* corresponding bean instances <i>in the order of definition</i> in the
* backend configuration, as far as possible.
* @param type the class or interface to match, or {@code null} for all concrete beans
* @return a Map with the matching beans, containing the bean names as
* keys and the corresponding bean instances as values
* @throws BeansException if a bean could not be created
* @since 1.1.2
* @see FactoryBean#getObjectType
* @see BeanFactoryUtils#beansOfTypeIncludingAncestors(ListableBeanFactory, Class)
*/
<T> Map<String, T> getBeansOfType(@Nullable Class<T> type) throws BeansException;

/**
* Return the bean instances that match the given object type (including
* subclasses), judging from either bean definitions or the value of
* {@code getObjectType} in the case of FactoryBeans.
* <p><b>NOTE: This method introspects top-level beans only.</b> It does <i>not</i>
* check nested beans which might match the specified type as well.
* <p>Does consider objects created by FactoryBeans if the "allowEagerInit" flag is set,
* which means that FactoryBeans will get initialized. If the object created by the
* FactoryBean doesn't match, the raw FactoryBean itself will be matched against the
* type. If "allowEagerInit" is not set, only raw FactoryBeans will be checked
* (which doesn't require initialization of each FactoryBean).
* <p>Does not consider any hierarchy this factory may participate in.
* Use BeanFactoryUtils' {@code beansOfTypeIncludingAncestors}
* to include beans in ancestor factories too.
* <p>Note: Does <i>not</i> ignore singleton beans that have been registered
* by other means than bean definitions.
* <p>The Map returned by this method should always return bean names and
* corresponding bean instances <i>in the order of definition</i> in the
* backend configuration, as far as possible.
* @param type the class or interface to match, or {@code null} for all concrete beans
* @param includeNonSingletons whether to include prototype or scoped beans too
* or just singletons (also applies to FactoryBeans)
* @param allowEagerInit whether to initialize <i>lazy-init singletons</i> and
* <i>objects created by FactoryBeans</i> (or by factory methods with a
* "factory-bean" reference) for the type check. Note that FactoryBeans need to be
* eagerly initialized to determine their type: So be aware that passing in "true"
* for this flag will initialize FactoryBeans and "factory-bean" references.
* @return a Map with the matching beans, containing the bean names as
* keys and the corresponding bean instances as values
* @throws BeansException if a bean could not be created
* @see FactoryBean#getObjectType
* @see BeanFactoryUtils#beansOfTypeIncludingAncestors(ListableBeanFactory, Class, boolean, boolean)
*/
<T> Map<String, T> getBeansOfType(@Nullable Class<T> type, boolean includeNonSingletons, boolean allowEagerInit)
throws BeansException;

/**
* Find all names of beans which are annotated with the supplied {@link Annotation}
* type, without creating corresponding bean instances yet.
* <p>Note that this method considers objects created by FactoryBeans, which means
* that FactoryBeans will get initialized in order to determine their object type.
* @param annotationType the type of annotation to look for
* (at class, interface or factory method level of the specified bean)
* @return the names of all matching beans
* @since 4.0
* @see #findAnnotationOnBean
*/
String[] getBeanNamesForAnnotation(Class<? extends Annotation> annotationType);

/**
* Find all beans which are annotated with the supplied {@link Annotation} type,
* returning a Map of bean names with corresponding bean instances.
* <p>Note that this method considers objects created by FactoryBeans, which means
* that FactoryBeans will get initialized in order to determine their object type.
* @param annotationType the type of annotation to look for
* (at class, interface or factory method level of the specified bean)
* @return a Map with the matching beans, containing the bean names as
* keys and the corresponding bean instances as values
* @throws BeansException if a bean could not be created
* @since 3.0
* @see #findAnnotationOnBean
*/
Map<String, Object> getBeansWithAnnotation(Class<? extends Annotation> annotationType) throws BeansException;

/**
* Find an {@link Annotation} of {@code annotationType} on the specified bean,
* traversing its interfaces and super classes if no annotation can be found on
* the given class itself, as well as checking the bean's factory method (if any).
* @param beanName the name of the bean to look for annotations on
* @param annotationType the type of annotation to look for
* (at class, interface or factory method level of the specified bean)
* @return the annotation of the given type if found, or {@code null} otherwise
* @throws NoSuchBeanDefinitionException if there is no bean with the given name
* @since 3.0
* @see #getBeanNamesForAnnotation
* @see #getBeansWithAnnotation
*/
@Nullable
<A extends Annotation> A findAnnotationOnBean(String beanName, Class<A> annotationType)
throws NoSuchBeanDefinitionException;

}

ListableBeanFactory方法属性摘要

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
public interface ListableBeanFactory extends BeanFactory {

/**
*/
boolean containsBeanDefinition(String beanName);

/**
*/
int getBeanDefinitionCount();

/**
*/
String[] getBeanDefinitionNames();

/**
*/
String[] getBeanNamesForType(ResolvableType type);

/**
*/
String[] getBeanNamesForType(ResolvableType type, boolean includeNonSingletons, boolean allowEagerInit);

/**
*/
String[] getBeanNamesForType(@Nullable Class<?> type);

/**
*/
String[] getBeanNamesForType(@Nullable Class<?> type, boolean includeNonSingletons, boolean allowEagerInit);


<T> Map<String, T> getBeansOfType(@Nullable Class<T> type) throws BeansException;


<T> Map<String, T> getBeansOfType(@Nullable Class<T> type, boolean includeNonSingletons, boolean allowEagerInit)
throws BeansException;


String[] getBeanNamesForAnnotation(Class<? extends Annotation> annotationType);


Map<String, Object> getBeansWithAnnotation(Class<? extends Annotation> annotationType) throws BeansException;


@Nullable
<A extends Annotation> A findAnnotationOnBean(String beanName, Class<A> annotationType)
throws NoSuchBeanDefinitionException;

}

1.4 ApplicationContext接口

ApplicationContext接口解析

  • 相比于BeanFactory,ApplicationContext是高配版的Ioc容器,其在BeanFactory的基础上实现了更加复杂的扩展功能
  • ListableBeanFactory, HierarchicalBeanFactory都是BeanFactory的子接口,ApplicationContext继承了这两个接口,ApplicationContext进一步扩展了BeanFactory接口的功能
  • . . .

完整版源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
/*
* Copyright 2002-2014 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
*
* https://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.context;

import org.springframework.beans.factory.HierarchicalBeanFactory;
import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.core.env.EnvironmentCapable;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.lang.Nullable;

/**
* Central interface to provide configuration for an application.
* This is read-only while the application is running, but may be
* reloaded if the implementation supports this.
*
* <p>An ApplicationContext provides:
* <ul>
* <li>Bean factory methods for accessing application components.
* Inherited from {@link org.springframework.beans.factory.ListableBeanFactory}.
* <li>The ability to load file resources in a generic fashion.
* Inherited from the {@link org.springframework.core.io.ResourceLoader} interface.
* <li>The ability to publish events to registered listeners.
* Inherited from the {@link ApplicationEventPublisher} interface.
* <li>The ability to resolve messages, supporting internationalization.
* Inherited from the {@link MessageSource} interface.
* <li>Inheritance from a parent context. Definitions in a descendant context
* will always take priority. This means, for example, that a single parent
* context can be used by an entire web application, while each servlet has
* its own child context that is independent of that of any other servlet.
* </ul>
*
* <p>In addition to standard {@link org.springframework.beans.factory.BeanFactory}
* lifecycle capabilities, ApplicationContext implementations detect and invoke
* {@link ApplicationContextAware} beans as well as {@link ResourceLoaderAware},
* {@link ApplicationEventPublisherAware} and {@link MessageSourceAware} beans.
*
* @author Rod Johnson
* @author Juergen Hoeller
* @see ConfigurableApplicationContext
* @see org.springframework.beans.factory.BeanFactory
* @see org.springframework.core.io.ResourceLoader
*/
public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory,
MessageSource, ApplicationEventPublisher, ResourcePatternResolver {

/**
* Return the unique id of this application context.
* @return the unique id of the context, or {@code null} if none
*/
@Nullable
String getId();

/**
* Return a name for the deployed application that this context belongs to.
* @return a name for the deployed application, or the empty String by default
*/
String getApplicationName();

/**
* Return a friendly name for this context.
* @return a display name for this context (never {@code null})
*/
String getDisplayName();

/**
* Return the timestamp when this context was first loaded.
* @return the timestamp (ms) when this context was first loaded
*/
long getStartupDate();

/**
* Return the parent context, or {@code null} if there is no parent
* and this is the root of the context hierarchy.
* @return the parent context, or {@code null} if there is no parent
*/
@Nullable
ApplicationContext getParent();

/**
* Expose AutowireCapableBeanFactory functionality for this context.
* <p>This is not typically used by application code, except for the purpose of
* initializing bean instances that live outside of the application context,
* applying the Spring bean lifecycle (fully or partly) to them.
* <p>Alternatively, the internal BeanFactory exposed by the
* {@link ConfigurableApplicationContext} interface offers access to the
* {@link AutowireCapableBeanFactory} interface too. The present method mainly
* serves as a convenient, specific facility on the ApplicationContext interface.
* <p><b>NOTE: As of 4.2, this method will consistently throw IllegalStateException
* after the application context has been closed.</b> In current Spring Framework
* versions, only refreshable application contexts behave that way; as of 4.2,
* all application context implementations will be required to comply.
* @return the AutowireCapableBeanFactory for this context
* @throws IllegalStateException if the context does not support the
* {@link AutowireCapableBeanFactory} interface, or does not hold an
* autowire-capable bean factory yet (e.g. if {@code refresh()} has
* never been called), or if the context has been closed already
* @see ConfigurableApplicationContext#refresh()
* @see ConfigurableApplicationContext#getBeanFactory()
*/
AutowireCapableBeanFactory getAutowireCapableBeanFactory() throws IllegalStateException;

}

ApplicationContext方法属性摘要

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory,
MessageSource, ApplicationEventPublisher, ResourcePatternResolver {

@Nullable
String getId();


String getApplicationName();


String getDisplayName();


long getStartupDate();


@Nullable
ApplicationContext getParent();

AutowireCapableBeanFactory getAutowireCapableBeanFactory() throws IllegalStateException;

}

1.5 BeanDefination接口

BeanDefination接口定义解析

  • BeanDefination用于管理Ioc容器中JavaBean与JavaBean之间的依赖关系,其抽象了Java开发人员对于JavaBean的定义
  • Spring将开发人员定义的JavaBean的数据结构转化为内存中的BeanDefination数据结构进行维护

完整版源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
/*
* Copyright 2002-2019 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
*
* https://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.beans.factory.config;

import org.springframework.beans.BeanMetadataElement;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.core.AttributeAccessor;
import org.springframework.core.ResolvableType;
import org.springframework.lang.Nullable;

/**
* A BeanDefinition describes a bean instance, which has property values,
* constructor argument values, and further information supplied by
* concrete implementations.
*
* <p>This is just a minimal interface: The main intention is to allow a
* {@link BeanFactoryPostProcessor} to introspect and modify property values
* and other bean metadata.
*
* @author Juergen Hoeller
* @author Rob Harrop
* @since 19.03.2004
* @see ConfigurableListableBeanFactory#getBeanDefinition
* @see org.springframework.beans.factory.support.RootBeanDefinition
* @see org.springframework.beans.factory.support.ChildBeanDefinition
*/
public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {

/**
* Scope identifier for the standard singleton scope: "singleton".
* <p>Note that extended bean factories might support further scopes.
* @see #setScope
*/
String SCOPE_SINGLETON = ConfigurableBeanFactory.SCOPE_SINGLETON;

/**
* Scope identifier for the standard prototype scope: "prototype".
* <p>Note that extended bean factories might support further scopes.
* @see #setScope
*/
String SCOPE_PROTOTYPE = ConfigurableBeanFactory.SCOPE_PROTOTYPE;


/**
* Role hint indicating that a {@code BeanDefinition} is a major part
* of the application. Typically corresponds to a user-defined bean.
*/
int ROLE_APPLICATION = 0;

/**
* Role hint indicating that a {@code BeanDefinition} is a supporting
* part of some larger configuration, typically an outer
* {@link org.springframework.beans.factory.parsing.ComponentDefinition}.
* {@code SUPPORT} beans are considered important enough to be aware
* of when looking more closely at a particular
* {@link org.springframework.beans.factory.parsing.ComponentDefinition},
* but not when looking at the overall configuration of an application.
*/
int ROLE_SUPPORT = 1;

/**
* Role hint indicating that a {@code BeanDefinition} is providing an
* entirely background role and has no relevance to the end-user. This hint is
* used when registering beans that are completely part of the internal workings
* of a {@link org.springframework.beans.factory.parsing.ComponentDefinition}.
*/
int ROLE_INFRASTRUCTURE = 2;


// Modifiable attributes

/**
* Set the name of the parent definition of this bean definition, if any.
*/
void setParentName(@Nullable String parentName);

/**
* Return the name of the parent definition of this bean definition, if any.
*/
@Nullable
String getParentName();

/**
* Specify the bean class name of this bean definition.
* <p>The class name can be modified during bean factory post-processing,
* typically replacing the original class name with a parsed variant of it.
* @see #setParentName
* @see #setFactoryBeanName
* @see #setFactoryMethodName
*/
void setBeanClassName(@Nullable String beanClassName);

/**
* Return the current bean class name of this bean definition.
* <p>Note that this does not have to be the actual class name used at runtime, in
* case of a child definition overriding/inheriting the class name from its parent.
* Also, this may just be the class that a factory method is called on, or it may
* even be empty in case of a factory bean reference that a method is called on.
* Hence, do <i>not</i> consider this to be the definitive bean type at runtime but
* rather only use it for parsing purposes at the individual bean definition level.
* @see #getParentName()
* @see #getFactoryBeanName()
* @see #getFactoryMethodName()
*/
@Nullable
String getBeanClassName();

/**
* Override the target scope of this bean, specifying a new scope name.
* @see #SCOPE_SINGLETON
* @see #SCOPE_PROTOTYPE
*/
void setScope(@Nullable String scope);

/**
* Return the name of the current target scope for this bean,
* or {@code null} if not known yet.
*/
@Nullable
String getScope();

/**
* Set whether this bean should be lazily initialized.
* <p>If {@code false}, the bean will get instantiated on startup by bean
* factories that perform eager initialization of singletons.
*/
void setLazyInit(boolean lazyInit);

/**
* Return whether this bean should be lazily initialized, i.e. not
* eagerly instantiated on startup. Only applicable to a singleton bean.
*/
boolean isLazyInit();

/**
* Set the names of the beans that this bean depends on being initialized.
* The bean factory will guarantee that these beans get initialized first.
*/
void setDependsOn(@Nullable String... dependsOn);

/**
* Return the bean names that this bean depends on.
*/
@Nullable
String[] getDependsOn();

/**
* Set whether this bean is a candidate for getting autowired into some other bean.
* <p>Note that this flag is designed to only affect type-based autowiring.
* It does not affect explicit references by name, which will get resolved even
* if the specified bean is not marked as an autowire candidate. As a consequence,
* autowiring by name will nevertheless inject a bean if the name matches.
*/
void setAutowireCandidate(boolean autowireCandidate);

/**
* Return whether this bean is a candidate for getting autowired into some other bean.
*/
boolean isAutowireCandidate();

/**
* Set whether this bean is a primary autowire candidate.
* <p>If this value is {@code true} for exactly one bean among multiple
* matching candidates, it will serve as a tie-breaker.
*/
void setPrimary(boolean primary);

/**
* Return whether this bean is a primary autowire candidate.
*/
boolean isPrimary();

/**
* Specify the factory bean to use, if any.
* This the name of the bean to call the specified factory method on.
* @see #setFactoryMethodName
*/
void setFactoryBeanName(@Nullable String factoryBeanName);

/**
* Return the factory bean name, if any.
*/
@Nullable
String getFactoryBeanName();

/**
* Specify a factory method, if any. This method will be invoked with
* constructor arguments, or with no arguments if none are specified.
* The method will be invoked on the specified factory bean, if any,
* or otherwise as a static method on the local bean class.
* @see #setFactoryBeanName
* @see #setBeanClassName
*/
void setFactoryMethodName(@Nullable String factoryMethodName);

/**
* Return a factory method, if any.
*/
@Nullable
String getFactoryMethodName();

/**
* Return the constructor argument values for this bean.
* <p>The returned instance can be modified during bean factory post-processing.
* @return the ConstructorArgumentValues object (never {@code null})
*/
ConstructorArgumentValues getConstructorArgumentValues();

/**
* Return if there are constructor argument values defined for this bean.
* @since 5.0.2
*/
default boolean hasConstructorArgumentValues() {
return !getConstructorArgumentValues().isEmpty();
}

/**
* Return the property values to be applied to a new instance of the bean.
* <p>The returned instance can be modified during bean factory post-processing.
* @return the MutablePropertyValues object (never {@code null})
*/
MutablePropertyValues getPropertyValues();

/**
* Return if there are property values values defined for this bean.
* @since 5.0.2
*/
default boolean hasPropertyValues() {
return !getPropertyValues().isEmpty();
}

/**
* Set the name of the initializer method.
* @since 5.1
*/
void setInitMethodName(@Nullable String initMethodName);

/**
* Return the name of the initializer method.
* @since 5.1
*/
@Nullable
String getInitMethodName();

/**
* Set the name of the destroy method.
* @since 5.1
*/
void setDestroyMethodName(@Nullable String destroyMethodName);

/**
* Return the name of the destroy method.
* @since 5.1
*/
@Nullable
String getDestroyMethodName();

/**
* Set the role hint for this {@code BeanDefinition}. The role hint
* provides the frameworks as well as tools with an indication of
* the role and importance of a particular {@code BeanDefinition}.
* @since 5.1
* @see #ROLE_APPLICATION
* @see #ROLE_SUPPORT
* @see #ROLE_INFRASTRUCTURE
*/
void setRole(int role);

/**
* Get the role hint for this {@code BeanDefinition}. The role hint
* provides the frameworks as well as tools with an indication of
* the role and importance of a particular {@code BeanDefinition}.
* @see #ROLE_APPLICATION
* @see #ROLE_SUPPORT
* @see #ROLE_INFRASTRUCTURE
*/
int getRole();

/**
* Set a human-readable description of this bean definition.
* @since 5.1
*/
void setDescription(@Nullable String description);

/**
* Return a human-readable description of this bean definition.
*/
@Nullable
String getDescription();


// Read-only attributes

/**
* Return a resolvable type for this bean definition,
* based on the bean class or other specific metadata.
* <p>This is typically fully resolved on a runtime-merged bean definition
* but not necessarily on a configuration-time definition instance.
* @return the resolvable type (potentially {@link ResolvableType#NONE})
* @since 5.2
* @see ConfigurableBeanFactory#getMergedBeanDefinition
*/
ResolvableType getResolvableType();

/**
* Return whether this a <b>Singleton</b>, with a single, shared instance
* returned on all calls.
* @see #SCOPE_SINGLETON
*/
boolean isSingleton();

/**
* Return whether this a <b>Prototype</b>, with an independent instance
* returned for each call.
* @since 3.0
* @see #SCOPE_PROTOTYPE
*/
boolean isPrototype();

/**
* Return whether this bean is "abstract", that is, not meant to be instantiated.
*/
boolean isAbstract();

/**
* Return a description of the resource that this bean definition
* came from (for the purpose of showing context in case of errors).
*/
@Nullable
String getResourceDescription();

/**
* Return the originating BeanDefinition, or {@code null} if none.
* Allows for retrieving the decorated bean definition, if any.
* <p>Note that this method returns the immediate originator. Iterate through the
* originator chain to find the original BeanDefinition as defined by the user.
*/
@Nullable
BeanDefinition getOriginatingBeanDefinition();

}

BeanDefination方法属性摘要

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {

String SCOPE_SINGLETON = ConfigurableBeanFactory.SCOPE_SINGLETON;

String SCOPE_PROTOTYPE = ConfigurableBeanFactory.SCOPE_PROTOTYPE;

int ROLE_APPLICATION = 0;


int ROLE_SUPPORT = 1;

// infrastructure
int ROLE_INFRASTRUCTURE = 2;


// Modifiable attributes

void setParentName(@Nullable String parentName);


@Nullable
String getParentName();


void setBeanClassName(@Nullable String beanClassName);


@Nullable
String getBeanClassName();


void setScope(@Nullable String scope);


@Nullable
String getScope();


void setLazyInit(boolean lazyInit);


boolean isLazyInit();


void setDependsOn(@Nullable String... dependsOn);


@Nullable
String[] getDependsOn();


void setAutowireCandidate(boolean autowireCandidate);


boolean isAutowireCandidate();


void setPrimary(boolean primary);


boolean isPrimary();


void setFactoryBeanName(@Nullable String factoryBeanName);


@Nullable
String getFactoryBeanName();


void setFactoryMethodName(@Nullable String factoryMethodName);


@Nullable
String getFactoryMethodName();


ConstructorArgumentValues getConstructorArgumentValues();


default boolean hasConstructorArgumentValues() {
return !getConstructorArgumentValues().isEmpty();
}


MutablePropertyValues getPropertyValues();


default boolean hasPropertyValues() {
return !getPropertyValues().isEmpty();
}


void setInitMethodName(@Nullable String initMethodName);

@Nullable
String getInitMethodName();


void setDestroyMethodName(@Nullable String destroyMethodName);


@Nullable
String getDestroyMethodName();


void setRole(int role);


int getRole();


void setDescription(@Nullable String description);

@Nullable
String getDescription();


// Read-only attributes


ResolvableType getResolvableType();


boolean isSingleton();


boolean isPrototype();


boolean isAbstract();


@Nullable
String getResourceDescription();


@Nullable
BeanDefinition getOriginatingBeanDefinition();

}



// org.springframework.core.AttributeAccessor
package org.springframework.core;
public interface AttributeAccessor {

void setAttribute(String name, @Nullable Object value);


@Nullable
Object getAttribute(String name);


@Nullable
Object removeAttribute(String name);


boolean hasAttribute(String name);


String[] attributeNames();

}



// org.springframework.beans.BeanMetadataElemen
package org.springframework.beans;
public interface BeanMetadataElement {

@Nullable
default Object getSource() {
return null;
}

}


2.从一个Demo程序开始

2.1 Demo项目配置

maven的pom.xml配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
<?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>com.acanx</groupId>-->
<!-- <artifactId>ACANX-JavaEE-Dependencies</artifactId>-->
<!-- <version>0.0.1</version>-->
<!-- </parent>-->

<groupId>com.acanx</groupId>
<artifactId>JavaWeb-Spring</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>

<name>JavaWeb-Spring</name>
<description>JavaWeb-Spring project</description>


<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>11</java.version>
<spring.version>5.2.1.RELEASE</spring.version>
<!-- log4j日志文件管理包版本 -->
<slf4j.version>2.0.0-alpha1</slf4j.version>
<logback.version>1.3.0-alpha5</logback.version>
<!-- log4j日志包版本号 -->
<log4j2.version>2.8.2</log4j2.version>
<log4j.version>1.2.17</log4j.version>
<junit.version>4.12</junit.version>
<fastjson.version>1.2.62</fastjson.version>
<maven-compiler-plugin.version>3.8.1</maven-compiler-plugin.version>
</properties>

<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${logback.version}</version>
</dependency>
<!-- 添加fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>${fastjson.version}</version>
</dependency>
<!-- 单元测试-->
<!-- https://mvnrepository.com/artifact/junit/junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>

</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven-compiler-plugin.version}</version>
<configuration>
<target>11</target>
<source>11</source>
</configuration>
</plugin>
</plugins>
</build>
</project>

2.2 Demo程序

2.2.1启动类

  • 代码位置:com.acanx.spring.xml.CspringIocConfigByFileSystemXmlApplicationContext.java
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41

    package com.acanx.spring.xml;

    import com.acanx.spring.bean.Car;
    import org.apache.commons.logging.Log;
    import org.apache.commons.logging.LogFactory;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.FileSystemXmlApplicationContext;

    /**
    * ACANX-JavaWeb / com.acanx.spring.xml / SpringIocConfigByXmlFileInClassPath.java
    * 文件由 ACANX 创建于 2019/7/30 - 13:39
    * Description SpringIocConfigByXmlFileInClassPath:
    * 补充说明: 使用FileSystemXmlApplicationContext加载文件系统下的配置文件
    *
    * @author ACANX
    * @version 0.0.1.0
    * @date 2019/7/30 13:39
    * @since 0.0.1-SNAPSHOT
    */
    public class CspringIocConfigByFileSystemXmlApplicationContext {
    private static final Logger logger= LoggerFactory.getLogger(CspringIocConfigByFileSystemXmlApplicationContext.class);
    public static void main(String[] args) {
    logger.info("-------------------");
    logger.info(System.getProperty("org.apache.commons.logging.LogFactory"));
    logger.info(System.getProperty("org.apache.commons.logging.Log"));
    logger.info("-------------------");
    String location="D:\\ProgramCode\\JavaCode\\ACANX-JavaWeb\\JavaWeb-Spring\\ApplicationContextC.xml";
    ApplicationContext applicationContext = new FileSystemXmlApplicationContext(location);
    Car car = (Car) applicationContext.getBean("myCar");
    logger.info(car.toString());
    logger.info("Info :{}",logger.isInfoEnabled());
    String[] beanNames=applicationContext.getBeanDefinitionNames();
    for (String beanName:beanNames) {
    logger.info(beanName+"::::: "+applicationContext.getBean(beanName).toString());
    }
    }
    }

2.2.2使用到的Bena对象

1
2
3
4
5
6
7
8
9
10
11
package com.acanx.spring.bean;

public class Car {

private String name;

private String price;

// get set 默认构造方法已省略

}

2.2.3 springContext的xml文件ApplicationContextC.xml

1
2
3
4
5
6
7
8
9
10
11
12
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

<bean name="myCar" class="com.acanx.spring.bean.Car" >
<property name="name" value="QQAI"/>
<property name="price" value="2222"/>
</bean>

</beans>

2.2.4 配置日志 logback.xml(resources文件夹下)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="60 seconds" debug="false">

<property name="LOG_PATH" value=".log"/>
<property name="APP_NAME" value="IOCDemo"/>
<!--设置系统日志目录-->
<property name="APP_DIR" value="app-IOCDemo"/>

<property name="CONSOLE_LOG_PATTERN" value="[CLP]${CONSOLE_LOG_PATTERN:-%clr(%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(%-15.15method){cyan} %clr([%4.4line{4}]){magenta} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>
<property name="FILE_LOG_PATTERN" value="${FILE_LOG_PATTERN:-%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}} ${LOG_LEVEL_PATTERN:-%5p} ${PID:- } --- [%t] %-40.40logger{39} : %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>
<property name="CONSOLE_LOGBACK_PATTERN" value="[控制台] %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level | %-80logger # %-40M [%4line] : %msg%n"/>


<contextName>logback</contextName>
<!--输出到控制台-->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>TRACE</level>
</filter>
<layout class="ch.qos.logback.classic.PatternLayout">
<Pattern>${CONSOLE_LOGBACK_PATTERN}</Pattern>
</layout>
<encoder>
<!-- 文件名 [%file]-->
<pattern>${CONSOLE_LOGBACK_PATTERN}</pattern>
</encoder>
</appender>

<appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<File>.log/ACANX-JavaWeb/LOG-ERROR.log</File>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>.log/server-error-%d{yyyyMMdd}.log.%i
</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>5MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<maxHistory>2</maxHistory>
</rollingPolicy>
<layout class="ch.qos.logback.classic.PatternLayout">
<Pattern>${CONSOLE_LOGBACK_PATTERN}</Pattern>
</layout>
</appender>


<appender name="WARN_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>WARN</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<File>.log/ACANX-JavaWeb/LOG-WARN.log</File>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>.log/ACANX-JavaWeb/server-WARN-%d{yyyyMMdd}.log.%i
</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>5MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<maxHistory>2</maxHistory>
</rollingPolicy>
<layout class="ch.qos.logback.classic.PatternLayout">
<Pattern>${CONSOLE_LOGBACK_PATTERN}</Pattern>
</layout>
</appender>

<appender name="INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<File>.log/ACANX-JavaWeb/LOG-INFO.log</File>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>INFO</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>.log/ACANX-JavaWeb/server-info-%d{yyyyMMdd}.log.%i</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>5MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<maxHistory>2</maxHistory>
</rollingPolicy>
<layout class="ch.qos.logback.classic.PatternLayout">
<Pattern>${CONSOLE_LOGBACK_PATTERN}</Pattern>
</layout>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
<pattern>${CONSOLE_LOGBACK_PATTERN}</pattern>
</encoder>
</appender>

<appender name="TRACE_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>TRACE</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<File>.log/ACANX-JavaWeb/LOG-TRACE.log</File>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>.log/ACANX-JavaWeb/server-TRACE-%d{yyyyMMdd}.log.%i
</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>5MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<maxHistory>2</maxHistory>
</rollingPolicy>
<layout class="ch.qos.logback.classic.PatternLayout">
<Pattern>${CONSOLE_LOGBACK_PATTERN}</Pattern>
</layout>
</appender>

<appender name="FULL_LEVEL_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<File>.log/ACANX-JavaWeb/LOG-FULL.log</File>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>TRACE</level>
</filter>
<encoder>
<!-- 文件名 [%file] -->
<pattern>${CONSOLE_LOGBACK_PATTERN}</pattern>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>.log/ACANX-JavaWeb/LOG-FULL-%d{yyyyMMdd}.log.%i</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>5MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<maxHistory>2</maxHistory>
</rollingPolicy>
<layout class="ch.qos.logback.classic.PatternLayout">
<Pattern>${CONSOLE_LOGBACK_PATTERN}</Pattern>
</layout>
</appender>

<root level="TRACE" additivity="true">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="WARN_FILE"/>
<appender-ref ref="ERROR_FILE"/>
<appender-ref ref="INFO_FILE"/>
<appender-ref ref="TRACE_FILE"/>
<appender-ref ref="FULL_LEVEL_FILE"/>
</root>

<!-- TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF -->
<logger name="org" level="TRACE" additivity="true"></logger>
<logger name="org.springframework.context" level="TRACE" additivity="false"></logger>
<logger name="org.apache" level="TRACE"/>
<logger name="com.alibaba" level="TRACE"/>
<!-- 如果这里设置了additivity=true 代码打印信息向上传递,将打印信息传递到root ,并且自己的appender-ref 也会打印,这样就是打印了俩次日志-->
</configuration>

3.Spring IOC容器的创建

3.1 进入FileSystemXmlApplicationContext(AbstractXmlApplicationContext抽象类的具体实现类)

  • 代码位置: org.springframework.context.support.FileSystemXmlApplicationContext.java
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    public FileSystemXmlApplicationContext(String configLocation) throws BeansException {
    this(new String[] {configLocation}, true, null);
    }


    // 上面的this 来到下面的重载构造方法
    public FileSystemXmlApplicationContext(
    String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
    throws BeansException {

    super(parent); // 初始化父容器AbstractApplicationContext
    setConfigLocations(configLocations); // 设置资源文件的位置
    if (refresh) {
    refresh();// 核心方法,具体定义在超类AbstractApplicationContext(抽象类)中,是一个模板方法
    }
    }

3.2 初始化父容器AbstractApplicationContext

3.2.1 AbstractXmlApplicationContext抽象类(FileSystemXmlApplicationContext的父类)

  • 代码位置: org.springframework.context.support.AbstractXmlApplicationContext.java
    1
    2
    3
    4
    public AbstractXmlApplicationContext(@Nullable ApplicationContext parent) {
    super(parent);
    }

3.2.2 AbstractRefreshableConfigApplicationContext抽象类( AbstractXmlApplicationContext的父类)

  • 代码位置:org.springframework.context.support.AbstractRefreshableConfigApplicationContext.java
    1
    2
    3
    4
    public AbstractRefreshableConfigApplicationContext(@Nullable ApplicationContext parent) {
    super(parent);
    }

3.2.3 AbstractRefreshableApplicationContext抽象类

  • 代码位置:org.springframework.context.support.AbstractRefreshableApplicationContext.java
    1
    2
    3
    4
    public AbstractRefreshableApplicationContext(@Nullable ApplicationContext parent) {
    super(parent);
    }

3.2.4 AbstractApplicationContext抽象类

  • 代码位置:org.springframework.context.support.AbstractApplicationContext.java
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    public AbstractApplicationContext(@Nullable ApplicationContext parent) {
    this();
    setParent(parent);
    }

    //上面对应的this()方法
    public AbstractApplicationContext() {
    this.resourcePatternResolver = getResourcePatternResolver();
    }

    //上面对应的 getResourcePatternResolver()方法
    protected ResourcePatternResolver getResourcePatternResolver() {
    return new PathMatchingResourcePatternResolver(this);
    }

    // this()之后的setParent(parent);方法
    @Override
    public void setParent(@Nullable ApplicationContext parent) {
    this.parent = parent;
    if (parent != null) {
    Environment parentEnvironment = parent.getEnvironment();
    if (parentEnvironment instanceof ConfigurableEnvironment) {
    getEnvironment().merge((ConfigurableEnvironment) parentEnvironment);
    }
    }
    }

3.5 PathMatchingResourcePatternResolver类

  • PathMatchingResourcePatternResolver(this)对应的构造方法
  • 代码位置:org.springframework.core.io.support.PathMatchingResourcePatternResolver.java
    1
    2
    3
    4
    5
    public PathMatchingResourcePatternResolver(ResourceLoader resourceLoader) {
    Assert.notNull(resourceLoader, "ResourceLoader must not be null");
    this.resourceLoader = resourceLoader;
    }

4.setConfigLocations(String… locations) 方法

  • 设置资源文件的位置

4.1 AbstractRefreshableConfigApplicationContext.setConfigLocations(@Nullable String… locations) 方法

  • 代码位置:org.springframework.context.support.AbstractRefreshableConfigApplicationContext.java
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    public void setConfigLocations(@Nullable String... locations) {
    if (locations != null) {
    Assert.noNullElements(locations, "Config locations must not be null");
    this.configLocations = new String[locations.length];
    for (int i = 0; i < locations.length; i++) {
    this.configLocations[i] = resolvePath(locations[i]).trim();
    }
    }
    else {
    this.configLocations = null;
    }
    }


5. refresh()方法

  • AbstractApplicationContext抽象类中定义的refresh()模板方法
  • 定义了需要执行刷新操作的一些步骤,只是一个模板,个性化的逻辑由其子类来具体实现

    5.1 refresh()方法定义

  • 代码位置:org.springframework.context.support.AbstractApplicationContext.java
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    @Override
    public void refresh() throws BeansException, IllegalStateException {
    synchronized (this.startupShutdownMonitor) {
    // Prepare this context for refreshing.
    prepareRefresh();

    // Tell the subclass to refresh the internal bean factory.
    // 创建BeanFactory
    ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

    // Prepare the bean factory for use in this context.
    prepareBeanFactory(beanFactory);

    try {
    // Allows post-processing of the bean factory in context subclasses.
    postProcessBeanFactory(beanFactory);

    // Invoke factory processors registered as beans in the context.
    invokeBeanFactoryPostProcessors(beanFactory);

    // Register bean processors that intercept bean creation.
    registerBeanPostProcessors(beanFactory);

    // Initialize message source for this context.
    initMessageSource();

    // Initialize event multicaster for this context.
    initApplicationEventMulticaster();

    // Initialize other special beans in specific context subclasses.
    onRefresh();

    // Check for listener beans and register them.
    registerListeners();

    // Instantiate all remaining (non-lazy-init) singletons.
    // 实例化Bean
    finishBeanFactoryInitialization(beanFactory);

    // Last step: publish corresponding event.
    finishRefresh();
    }

    catch (BeansException ex) {
    if (logger.isWarnEnabled()) {
    logger.warn("Exception encountered during context initialization - " +
    "cancelling refresh attempt: " + ex);
    }

    // Destroy already created singletons to avoid dangling resources.
    destroyBeans();

    // Reset 'active' flag.
    cancelRefresh(ex);

    // Propagate exception to caller.
    throw ex;
    }

    finally {
    // Reset common introspection caches in Spring's core, since we
    // might not ever need metadata for singleton beans anymore...
    resetCommonCaches();
    }
    }
    }

5.2 prepareRefresh()方法

  • 正式Refresh()操作前的准备工作
  • 代码位置:org.springframework.context.support.AbstractApplicationContext.java
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    protected void prepareRefresh() {
    // Switch to active.
    this.startupDate = System.currentTimeMillis();
    this.closed.set(false);
    this.active.set(true);

    if (logger.isDebugEnabled()) {
    if (logger.isTraceEnabled()) {
    logger.trace("Refreshing " + this);
    }
    else {
    logger.debug("Refreshing " + getDisplayName());
    }
    }

    // Initialize any placeholder property sources in the context environment.
    initPropertySources();

    // Validate that all properties marked as required are resolvable:
    // see ConfigurablePropertyResolver#setRequiredProperties
    getEnvironment().validateRequiredProperties();

    // Store pre-refresh ApplicationListeners...
    if (this.earlyApplicationListeners == null) {
    this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
    }
    else {
    // Reset local application listeners to pre-refresh state.
    this.applicationListeners.clear();
    this.applicationListeners.addAll(this.earlyApplicationListeners);
    }

    // Allow for the collection of early ApplicationEvents,
    // to be published once the multicaster is available...
    this.earlyApplicationEvents = new LinkedHashSet<>();
    }

    // 上述定义的initPropertySources()方法,具体由子类实现
    protected void initPropertySources() {
    // For subclasses: do nothing by default.
    }

5.3 obtainFreshBeanFactory()方法

  • 创建BeanFactory的核心方法
  • 代码位置:org.springframework.context.support.AbstractApplicationContext.java
    1
    2
    3
    4
    5
    6
    7
    8
    9
    protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
    refreshBeanFactory();// 刷新BeanFactory,抽象方法由其子类实现,5.3.1中有说明
    return getBeanFactory();// 获取BeanFactory,父类的抽象方法继承并由其子类实现
    }

    protected abstract void refreshBeanFactory() throws BeansException, IllegalStateException;

    @Override // 该方法在ConfigurableApplicationContext接口中定义
    public abstract ConfigurableListableBeanFactory getBeanFactory() throws IllegalStateException;

5.3.1 refreshBeanFactory()方法的一种实现

  • org.springframework.context.support.AbstractRefreshableApplicationContext中的具体实现如下
  • refreshBeanFactory()方法是AbstractApplicationContext中定义的抽象方法
  • AbstractRefreshableApplicationContext中的refreshBeanFactory()方法是该抽象方法的一个具体实现
  • 主要作用:刷新BeanFactory
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    // AbstractRefreshableApplicationContext中refreshBeanFactory()方法的一种实现
    @Override
    protected final void refreshBeanFactory() throws BeansException {
    // 检查上下文中是否已存在BeanFactory
    if (hasBeanFactory()) {
    // 存在BeanFactory时先销毁已存在的BeanFactory
    destroyBeans();//调用AbstractApplicationContext中的实现
    /**
    * 以下是AbstractApplicationContext中destroyBeans()方法的实现
    * protected void destroyBeans() {
    * getBeanFactory().destroySingletons();
    * }
    */
    closeBeanFactory();// 调用本抽象类中的closeBeanFactory()方法,具体代码在下面列出
    }
    try {
    // 创建新的BeanFactory
    // 下面这行代码只会创建一个空的BeanFactory,并未有任何Bean
    DefaultListableBeanFactory beanFactory = createBeanFactory();
    beanFactory.setSerializationId(getId());
    customizeBeanFactory(beanFactory);
    loadBeanDefinitions(beanFactory);// refreshBeanFactory()方法实现的核心
    synchronized (this.beanFactoryMonitor) {
    this.beanFactory = beanFactory;
    }
    }
    catch (IOException ex) {
    throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
    }
    }

    // AbstractRefreshableApplicationContext抽象类中refreshBeanFactory()方法内调用的closeBeanFactory()方法
    @Override
    protected final void closeBeanFactory() {
    synchronized (this.beanFactoryMonitor) {
    if (this.beanFactory != null) {
    //销毁已存在的BeanFactory
    this.beanFactory.setSerializationId(null);
    this.beanFactory = null;
    }
    }
    }

    //AbstractRefreshableApplicationContext抽象类中refreshBeanFactory()方法内调用createBeanFactory()方法
    protected DefaultListableBeanFactory createBeanFactory() {
    // 调用下面 AbstractApplicationContext中的getInternalParentBeanFactory()方法
    return new DefaultListableBeanFactory(getInternalParentBeanFactory());
    }

AbstractApplicationContext中的getInternalParentBeanFactory()方法

1
2
3
4
5
@Nullable
protected BeanFactory getInternalParentBeanFactory() {
return (getParent() instanceof ConfigurableApplicationContext ?
((ConfigurableApplicationContext) getParent()).getBeanFactory() : getParent());
}

DefaultListableBeanFactory的构造方法

1
2
3
public DefaultListableBeanFactory(@Nullable BeanFactory parentBeanFactory) {
super(parentBeanFactory);// 调用AbstractAutowireCapableBeanFactory(抽象类)的构造方法
}

DefaultListableBeanFactory父类AbstractAutowireCapableBeanFactory(抽象类)的构造方法

1
2
3
4
public AbstractAutowireCapableBeanFactory(@Nullable BeanFactory parentBeanFactory) {
this();
setParentBeanFactory(parentBeanFactory);
}

AbstractRefreshableApplicationContext中的customizeBeanFactory(beanFactory)方法

1
2
3
4
5
6
7
8
protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
if (this.allowBeanDefinitionOverriding != null) {
beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
}
if (this.allowCircularReferences != null) {
beanFactory.setAllowCircularReferences(this.allowCircularReferences);
}
}

AbstractRefreshableApplicationContext中的loadBeanDefinitions(beanFactory)方法

  • 是实现refreshBeanFactory()方法的核心
  • org.springframework.context.support.AbstractRefreshableApplicationContext中定义的抽象方法
    1
    2
    protected abstract void loadBeanDefinitions(DefaultListableBeanFactory beanFactory)
    throws BeansException, IOException;
  • 该抽象方法的一个具体实现在org.springframework.context.support.AbstractXmlApplicationContext中

org.springframework.context.support.AbstractXmlApplicationContext中的loadBeanDefinitions(DefaultListableBeanFactory beanFactory)方法

  • org.springframework.context.support.AbstractRefreshableApplicationContext中定义的抽象方法loadBeanDefinitions(DefaultListableBeanFactory beanFactory)的一个实现
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    @Override
    protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
    // Create a new XmlBeanDefinitionReader for the given BeanFactory.
    // 通过上一步创建的空BeanFactory来创建新的XmlBeanDefinitionReader对象
    // XmlBeanDefinitionReader用于解析xml文件中定义的bean
    XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory); //

    // Configure the bean definition reader with this context's
    // resource loading environment.
    beanDefinitionReader.setEnvironment(this.getEnvironment());
    beanDefinitionReader.setResourceLoader(this);
    beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));

    // Allow a subclass to provide custom initialization of the reader,
    // then proceed with actually loading the bean definitions.
    initBeanDefinitionReader(beanDefinitionReader);
    loadBeanDefinitions(beanDefinitionReader); //这是一个重载方法,入参是上面生成的beanDefinitionReader
    }

new XmlBeanDefinitionReader(beanFactory)

  • XmlBeanDefinitionReader(beanFactory)构造方法调用其父类AbstractBeanDefinitionReader的构造方法,具体如下
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    protected AbstractBeanDefinitionReader(BeanDefinitionRegistry registry) {
    Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
    this.registry = registry;

    // Determine ResourceLoader to use.
    if (this.registry instanceof ResourceLoader) {
    this.resourceLoader = (ResourceLoader) this.registry;
    }
    else {
    this.resourceLoader = new PathMatchingResourcePatternResolver();
    }

    // Inherit Environment if possible
    if (this.registry instanceof EnvironmentCapable) {
    this.environment = ((EnvironmentCapable) this.registry).getEnvironment();
    }
    else {
    this.environment = new StandardEnvironment();
    }
    }

AbstractXmlApplicationContext抽象类中的initBeanDefinitionReader(beanDefinitionReader)方法

1
2
3
protected void initBeanDefinitionReader(XmlBeanDefinitionReader reader) {
reader.setValidating(this.validating);
}

AbstractXmlApplicationContext抽象类中的loadBeanDefinitions(XmlBeanDefinitionReader reader)方法

  • 主要功能是解析资源文件的位置
  • 调用XmlBeanDefinitionReader对象的loadBeanDefinitions方法解析bean的定义
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
    Resource[] configResources = getConfigResources();
    if (configResources != null) {
    reader.loadBeanDefinitions(configResources); //具体调用AbstractBeanDefinitionReader中实现的loadBeanDefinitions(Resource... resources)方法
    }
    String[] configLocations = getConfigLocations();
    if (configLocations != null) {
    reader.loadBeanDefinitions(configLocations);//具体调用AbstractBeanDefinitionReader中实现的loadBeanDefinitions(String... locations)
    }
    }
reader.loadBeanDefinitions(configResources)方法与reader.loadBeanDefinitions(configLocations)方法
  • XmlBeanDefinitionReader对象的loadBeanDefinitions方法用于解析bean的定义
  • reader是XmlBeanDefinitionReader类型的对象,loadBeanDefinitions方法定义在BeanDefinitionReader接口中,
  • loadBeanDefinitions方法具体是在AbstractBeanDefinitionReader抽象类中实现的,具体代码如下:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    @Override
    public int loadBeanDefinitions(Resource... resources) throws BeanDefinitionStoreException {
    Assert.notNull(resources, "Resource array must not be null");
    int count = 0;
    // 遍历每一个资源并依次调用重载方法loadBeanDefinitions(Resource resource),定义在XmlBeanDefinitionReader中,具体实现在XmlBeanDefinitionReader中
    for (Resource resource : resources) {
    count += loadBeanDefinitions(resource);//
    }
    return count;
    }

    @Override
    public int loadBeanDefinitions(String... locations) throws BeanDefinitionStoreException {
    Assert.notNull(locations, "Location array must not be null");
    int count = 0;
    //遍历资源数组,调用重载方法loadBeanDefinitions(String location)
    for (String location : locations) {
    count += loadBeanDefinitions(location);//
    }
    return count;
    }

count += loadBeanDefinitions(resource)中的loadBeanDefinitions(resource)方法

  • loadBeanDefinitions(resource)方法在BeanDefinitionReader接口中定义,具体实现是在XmlBeanDefinitionReader中
  • XmlBeanDefinitionReader中的实现代码如下:
    1
    2
    3
    4
    @Override
    public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException {
    return loadBeanDefinitions(new EncodedResource(resource));
    }
  • 可以看到,上面的方法又调用了loadBeanDefinitions(new EncodedResource(resource))方法,该方法在BeanDefinitionReader接口中定义,具体实现在XmlBeanDefinitionReader中,具体实现,详细代码如下:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
    Assert.notNull(encodedResource, "EncodedResource must not be null");
    if (logger.isTraceEnabled()) {
    logger.trace("Loading XML bean definitions from " + encodedResource);
    }

    Set<EncodedResource> currentResources = this.resourcesCurrentlyBeingLoaded.get();
    if (currentResources == null) {
    currentResources = new HashSet<>(4);
    this.resourcesCurrentlyBeingLoaded.set(currentResources);
    }
    if (!currentResources.add(encodedResource)) {
    throw new BeanDefinitionStoreException("Detected cyclic loading of " + encodedResource + " - check your import definitions!");
    }
    try {
    //以流的形式读取资源文件
    InputStream inputStream = encodedResource.getResource().getInputStream();
    try {
    InputSource inputSource = new InputSource(inputStream);
    if (encodedResource.getEncoding() != null) {
    inputSource.setEncoding(encodedResource.getEncoding());
    }
    // 调用doLoadBeanDefinitions解析载入文件中的bean定义
    return doLoadBeanDefinitions(inputSource, encodedResource.getResource());
    }
    finally {
    inputStream.close();
    }
    }
    catch (IOException ex) {
    throw new BeanDefinitionStoreException(
    "IOException parsing XML document from " + encodedResource.getResource(), ex);
    }
    finally {
    currentResources.remove(encodedResource);
    if (currentResources.isEmpty()) {
    this.resourcesCurrentlyBeingLoaded.remove();
    }
    }
    }

count += loadBeanDefinitions(location)中的loadBeanDefinitions(location)方法

  • loadBeanDefinitions(location)方法的具体实现AbstractBeanDefinitionReader中;
    1
    2
    3
    4
    5
    @Override
    public int loadBeanDefinitions(String location) throws BeanDefinitionStoreException {
    return loadBeanDefinitions(location, null);
    }

  • 解析资源文件的路径,得到Resource[]资源数组
  • 上面AbstractBeanDefinitionReader中的loadBeanDefinitions(String location)方法又调用了同类里面的一个重载方法loadBeanDefinitions(String location, @Nullable Set actualResources) 具体实现如下:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    public int loadBeanDefinitions(String location, @Nullable Set<Resource> actualResources) throws BeanDefinitionStoreException {
    ResourceLoader resourceLoader = getResourceLoader();
    if (resourceLoader == null) {
    throw new BeanDefinitionStoreException(
    "Cannot load bean definitions from location [" + location + "]: no ResourceLoader available");
    }

    if (resourceLoader instanceof ResourcePatternResolver) {
    // Resource pattern matching available.
    try {
    Resource[] resources = ((ResourcePatternResolver) resourceLoader).getResources(location);
    //下一行的核心逻辑 调用上面提到的重载方法loadBeanDefinitions(Resource resource)
    int count = loadBeanDefinitions(resources);
    if (actualResources != null) {
    Collections.addAll(actualResources, resources);
    }
    if (logger.isTraceEnabled()) {
    logger.trace("Loaded " + count + " bean definitions from location pattern [" + location + "]");
    }
    return count;
    }
    catch (IOException ex) {
    throw new BeanDefinitionStoreException(
    "Could not resolve bean definition resource pattern [" + location + "]", ex);
    }
    }
    else {
    // Can only load single resources by absolute URL.
    Resource resource = resourceLoader.getResource(location);
    int count = loadBeanDefinitions(resource);
    if (actualResources != null) {
    actualResources.add(resource);
    }
    if (logger.isTraceEnabled()) {
    logger.trace("Loaded " + count + " bean definitions from location [" + location + "]");
    }
    return count;
    }
    }

XmlBeanDefinitionReader类中的doLoadBeanDefinitions(InputSource inputSource, Resource resource)方法

  • 该方法是载入定义bean的核心方法
  • 代码位置:org.springframework.beans.factory.xml.XmlBeanDefinitionReader
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
    throws BeanDefinitionStoreException {

    try {
    // 解析XML文档
    Document doc = doLoadDocument(inputSource, resource);
    // 下面一行代码 注册Bean
    int count = registerBeanDefinitions(doc, resource);
    if (logger.isDebugEnabled()) {
    logger.debug("Loaded " + count + " bean definitions from " + resource);
    }
    return count;
    }
    catch (BeanDefinitionStoreException ex) {
    throw ex;
    }
    catch (SAXParseException ex) {
    throw new XmlBeanDefinitionStoreException(resource.getDescription(),
    "Line " + ex.getLineNumber() + " in XML document from " + resource + " is invalid", ex);
    }
    catch (SAXException ex) {
    throw new XmlBeanDefinitionStoreException(resource.getDescription(),
    "XML document from " + resource + " is invalid", ex);
    }
    catch (ParserConfigurationException ex) {
    throw new BeanDefinitionStoreException(resource.getDescription(),
    "Parser configuration exception parsing XML from " + resource, ex);
    }
    catch (IOException ex) {
    throw new BeanDefinitionStoreException(resource.getDescription(),
    "IOException parsing XML document from " + resource, ex);
    }
    catch (Throwable ex) {
    throw new BeanDefinitionStoreException(resource.getDescription(),
    "Unexpected exception parsing XML document from " + resource, ex);
    }
    }

    // 注册Bean的方法
    public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
    BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
    int countBefore = getRegistry().getBeanDefinitionCount();
    // 注册bean的核心逻辑
    documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
    return getRegistry().getBeanDefinitionCount() - countBefore;
    }

DefaultBeanDefinitionDocumentReader.registerBeanDefinitions(Document doc, XmlReaderContext readerContext)

  • 功能:
  • 代码位置:org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    @Override
    public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
    this.readerContext = readerContext;
    // 核心逻辑
    doRegisterBeanDefinitions(doc.getDocumentElement());
    }

    // registerBeanDefinitions方法中调用的doRegisterBeanDefinitions方法
    @SuppressWarnings("deprecation") // for Environment.acceptsProfiles(String...)
    protected void doRegisterBeanDefinitions(Element root) {
    // Any nested <beans> elements will cause recursion in this method. In
    // order to propagate and preserve <beans> default-* attributes correctly,
    // keep track of the current (parent) delegate, which may be null. Create
    // the new (child) delegate with a reference to the parent for fallback purposes,
    // then ultimately reset this.delegate back to its original (parent) reference.
    // this behavior emulates a stack of delegates without actually necessitating one.
    BeanDefinitionParserDelegate parent = this.delegate;
    this.delegate = createDelegate(getReaderContext(), root, parent);

    if (this.delegate.isDefaultNamespace(root)) {
    String profileSpec = root.getAttribute(PROFILE_ATTRIBUTE);
    if (StringUtils.hasText(profileSpec)) {
    String[] specifiedProfiles = StringUtils.tokenizeToStringArray(
    profileSpec, BeanDefinitionParserDelegate.MULTI_VALUE_ATTRIBUTE_DELIMITERS);
    // We cannot use Profiles.of(...) since profile expressions are not supported
    // in XML config. See SPR-12458 for details.
    if (!getReaderContext().getEnvironment().acceptsProfiles(specifiedProfiles)) {
    if (logger.isDebugEnabled()) {
    logger.debug("Skipped XML bean definition file due to specified profiles [" + profileSpec +
    "] not matching: " + getReaderContext().getResource());
    }
    return;
    }
    }
    }

    preProcessXml(root);
    // 核心逻辑
    parseBeanDefinitions(root, this.delegate);
    postProcessXml(root);

    this.delegate = parent;
    }

    // 上面方法中调用的parseBeanDefinitions(root, this.delegate)对应的方法实现
    protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
    if (delegate.isDefaultNamespace(root)) {
    NodeList nl = root.getChildNodes();
    for (int i = 0; i < nl.getLength(); i++) {
    Node node = nl.item(i);
    if (node instanceof Element) {
    Element ele = (Element) node;
    if (delegate.isDefaultNamespace(ele)) {
    // 本方法的核心逻辑
    parseDefaultElement(ele, delegate);
    }
    else {
    delegate.parseCustomElement(ele);
    }
    }
    }
    }
    else {
    delegate.parseCustomElement(root);
    }
    }


    // 上述方法调用的parseDefaultElement(ele, delegate);的具体实现
    // 根据bean配置的不同,进入不同分支
    private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
    if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {
    importBeanDefinitionResource(ele);
    }
    else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) {
    processAliasRegistration(ele);
    }
    else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {
    // 本文示例会进入该方法
    processBeanDefinition(ele, delegate);
    }
    else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {
    // recurse
    doRegisterBeanDefinitions(ele);
    }
    }

    // 上述方法最后进入processBeanDefinition(ele, delegate)后的处理过程:
    protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
    BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
    if (bdHolder != null) {
    bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
    try {
    // Register the final decorated instance.
    // 注册Bean的关键代码
    BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
    }
    catch (BeanDefinitionStoreException ex) {
    getReaderContext().error("Failed to register bean definition with name '" +
    bdHolder.getBeanName() + "'", ele, ex);
    }
    // Send registration event.
    getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
    }
    }

BeanDefinitionReaderUtils的registerBeanDefinition(bdHolder, getReaderContext().getRegistry())方法

  • 主要作用:
  • 代码位置:org.springframework.beans.factory.support.BeanDefinitionReaderUtils
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    public static void registerBeanDefinition(
    BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
    throws BeanDefinitionStoreException {

    // Register bean definition under primary name.
    String beanName = definitionHolder.getBeanName();
    // 将Bean的名字和BeanDefinition对象进行注册
    // registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());方法定义在BeanDefinitionRegistry接口中:
    // 具体实现在中实现
    registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());

    // Register aliases for bean name, if any.
    String[] aliases = definitionHolder.getAliases();
    if (aliases != null) {
    for (String alias : aliases) {
    registry.registerAlias(beanName, alias);
    }
    }
    }

DefaultListableBeanFactory中registerBeanDefinition(String beanName, BeanDefinition beanDefinition)

  • 作用:
  • DefaultListableBeanFactory的字段beanDefinitionMap是一个ConcurrentHashMap<String, BeanDefinition>,用于存储bean的定义信息
  • DefaultListableBeanFactory的字段beanDefinitionNames是一个ArrayList类型数据,用于存储Bean的名称
  • 代码位置:org.springframework.beans.factory.support.DefaultListableBeanFactory
  • 1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    @Override
    public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
    throws BeanDefinitionStoreException {

    Assert.hasText(beanName, "Bean name must not be empty");
    Assert.notNull(beanDefinition, "BeanDefinition must not be null");

    if (beanDefinition instanceof AbstractBeanDefinition) {
    try {
    ((AbstractBeanDefinition) beanDefinition).validate();
    }
    catch (BeanDefinitionValidationException ex) {
    throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
    "Validation of bean definition failed", ex);
    }
    }

    BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
    // 查找是否存在同名的bean
    if (existingDefinition != null) {
    // 有同名的bean存在时
    if (!isAllowBeanDefinitionOverriding()) {
    throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);
    }
    else if (existingDefinition.getRole() < beanDefinition.getRole()) {
    // e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE
    if (logger.isInfoEnabled()) {
    logger.info("Overriding user-defined bean definition for bean '" + beanName +
    "' with a framework-generated bean definition: replacing [" +
    existingDefinition + "] with [" + beanDefinition + "]");
    }
    }
    else if (!beanDefinition.equals(existingDefinition)) {
    if (logger.isDebugEnabled()) {
    logger.debug("Overriding bean definition for bean '" + beanName +
    "' with a different definition: replacing [" + existingDefinition +
    "] with [" + beanDefinition + "]");
    }
    }
    else {
    if (logger.isTraceEnabled()) {
    logger.trace("Overriding bean definition for bean '" + beanName +
    "' with an equivalent definition: replacing [" + existingDefinition +
    "] with [" + beanDefinition + "]");
    }
    }
    this.beanDefinitionMap.put(beanName, beanDefinition);
    }
    else {
    // 没有同名的bean存在时
    if (hasBeanCreationStarted()) {
    // Cannot modify startup-time collection elements anymore (for stable iteration)
    synchronized (this.beanDefinitionMap) {
    // beanDefinitionMap存储beanName:BeanDefinition一一对应的K:V信息
    // beanName作为key, beanDefinition作为value存入DefaultListableBeanFactory对象的beanDefinitionMap字段中
    // 完成Bean的注册,将Bean注册到BeanFactory中
    this.beanDefinitionMap.put(beanName, beanDefinition);
    List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);
    updatedDefinitions.addAll(this.beanDefinitionNames);
    updatedDefinitions.add(beanName);
    // 将所有的beanName保存到beanDefinitionNames字段中,数据类型为
    this.beanDefinitionNames = updatedDefinitions;
    removeManualSingletonName(beanName);
    }
    }
    else {
    // Still in startup registration phase
    this.beanDefinitionMap.put(beanName, beanDefinition);
    this.beanDefinitionNames.add(beanName);
    removeManualSingletonName(beanName);
    }
    this.frozenBeanDefinitionNames = null;
    }

    if (existingDefinition != null || containsSingleton(beanName)) {
    resetBeanDefinition(beanName);
    }
    }


  • 到此上面的 loadBeanDefinitions(XmlBeanDefinitionReader reader)方法基本执行完成
  • 上一级的loadBeanDefinitions(DefaultListableBeanFactory beanFactory)方法也执行到loadBeanDefinitions(XmlBeanDefinitionReader reader)方法后结束
  • 在上述创建BeanFactory的过程中,BeanDefination注册到BeanFactory(DefaultListableBeanFactory)中的类型为ConcurrentHashMap<String, BeanDefinition>,字段名beanDefinitionMap的为对象中
  • 向beanDefinitionMap中注册时beanName为key,beanDefination为value;
  • DefaultListableBeanFactory对象的字段beanDefinitionNames是一个ArrayList类型数据,用于存储所有已经注册的Bean的名称
  • refreshBeanFactory()方法执行完成,接下来进入其下一行的getBeanFactory()方法

getBeanFactory()方法的一种实现

  • AbstractRefreshableApplicationContext中getBeanFactory()方法的一种实现
  • 获取BeanFactory
    1
    2
    3
    4
    5
    6
    7
    8
    9
    @Override
    public final ConfigurableListableBeanFactory getBeanFactory() {
    synchronized (this.beanFactoryMonitor) {
    if (this.beanFactory == null) {
    throw new IllegalStateException("BeanFactory not initialized or already closed - call 'refresh' before accessing beans via the ApplicationContext");
    }
    return this.beanFactory;
    }
    }
  • getBeanFactory()方法执行完,标志上一级的方法obtainFreshBeanFactory()执行完成,接下来将进入AbstractApplicationContext抽象类中定义的refresh()模板方法中的第三步定义的prepareBeanFactory(beanFactory)方法

6 prepareBeanFactory(beanFactory)方法

  • 代码位置: org.springframework.context.support.AbstractApplicationContext.java
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    // Tell the internal bean factory to use the context's class loader etc.
    beanFactory.setBeanClassLoader(getClassLoader());
    beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
    beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

    // Configure the bean factory with context callbacks.
    beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
    beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
    beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
    beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
    beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
    beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
    beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);

    // BeanFactory interface not registered as resolvable type in a plain factory.
    // MessageSource registered (and found for autowiring) as a bean.
    beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
    beanFactory.registerResolvableDependency(ResourceLoader.class, this);
    beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
    beanFactory.registerResolvableDependency(ApplicationContext.class, this);

    // Register early post-processor for detecting inner beans as ApplicationListeners.
    beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

    // Detect a LoadTimeWeaver and prepare for weaving, if found.
    if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
    beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
    // Set a temporary ClassLoader for type matching.
    beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
    }

    // Register default environment beans.
    if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
    beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
    }
    if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
    beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
    }
    if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
    beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
    }
    }

7 postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)

  • 代码位置:org.springframework.context.support.AbstractApplicationContext.java
    1
    2
    3
    4
    5
    protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    // 该方法是一个空方法,具体的实现依据具体的情况在其子类中继承或进行重写
    // 观察AbstractApplicationContext到FileSystemXmlApplicationContext(location)的继承路径,其子类中并未实现具体的逻辑;
    }

  • postProcessBeanFactory(beanFactory)执行完后进入 invokeBeanFactoryPostProcessors(beanFactory)方法

8. invokeBeanFactoryPostProcessors(beanFactory)方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());

// Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
// (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
}

public List<BeanFactoryPostProcessor> getBeanFactoryPostProcessors() {
return this.beanFactoryPostProcessors;
}

  • PostProcessorRegistrationDelegate的invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List beanFactoryPostProcessors)静态方法
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    public static void invokeBeanFactoryPostProcessors(
    ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {

    // Invoke BeanDefinitionRegistryPostProcessors first, if any.
    Set<String> processedBeans = new HashSet<>();

    if (beanFactory instanceof BeanDefinitionRegistry) {
    BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
    List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
    List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();

    for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
    if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
    BeanDefinitionRegistryPostProcessor registryProcessor =
    (BeanDefinitionRegistryPostProcessor) postProcessor;
    registryProcessor.postProcessBeanDefinitionRegistry(registry);
    registryProcessors.add(registryProcessor);
    }
    else {
    regularPostProcessors.add(postProcessor);
    }
    }

    // Do not initialize FactoryBeans here: We need to leave all regular beans
    // uninitialized to let the bean factory post-processors apply to them!
    // Separate between BeanDefinitionRegistryPostProcessors that implement
    // PriorityOrdered, Ordered, and the rest.
    List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

    // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
    String[] postProcessorNames =
    beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
    for (String ppName : postProcessorNames) {
    if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
    currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
    processedBeans.add(ppName);
    }
    }
    sortPostProcessors(currentRegistryProcessors, beanFactory);
    registryProcessors.addAll(currentRegistryProcessors);
    invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
    currentRegistryProcessors.clear();

    // Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
    postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
    for (String ppName : postProcessorNames) {
    if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
    currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
    processedBeans.add(ppName);
    }
    }
    sortPostProcessors(currentRegistryProcessors, beanFactory);
    registryProcessors.addAll(currentRegistryProcessors);
    invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
    currentRegistryProcessors.clear();

    // Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
    boolean reiterate = true;
    while (reiterate) {
    reiterate = false;
    postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
    for (String ppName : postProcessorNames) {
    if (!processedBeans.contains(ppName)) {
    currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
    processedBeans.add(ppName);
    reiterate = true;
    }
    }
    sortPostProcessors(currentRegistryProcessors, beanFactory);
    registryProcessors.addAll(currentRegistryProcessors);
    invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
    currentRegistryProcessors.clear();
    }

    // Now, invoke the postProcessBeanFactory callback of all processors handled so far.
    invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
    invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
    }

    else {
    // Invoke factory processors registered with the context instance.
    invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
    }

    // Do not initialize FactoryBeans here: We need to leave all regular beans
    // uninitialized to let the bean factory post-processors apply to them!
    String[] postProcessorNames =
    beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

    // Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
    // Ordered, and the rest.
    List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
    List<String> orderedPostProcessorNames = new ArrayList<>();
    List<String> nonOrderedPostProcessorNames = new ArrayList<>();
    for (String ppName : postProcessorNames) {
    if (processedBeans.contains(ppName)) {
    // skip - already processed in first phase above
    }
    else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
    priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
    }
    else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
    orderedPostProcessorNames.add(ppName);
    }
    else {
    nonOrderedPostProcessorNames.add(ppName);
    }
    }

    // First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
    sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
    invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

    // Next, invoke the BeanFactoryPostProcessors that implement Ordered.
    List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
    for (String postProcessorName : orderedPostProcessorNames) {
    orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
    }
    sortPostProcessors(orderedPostProcessors, beanFactory);
    invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

    // Finally, invoke all other BeanFactoryPostProcessors.
    List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
    for (String postProcessorName : nonOrderedPostProcessorNames) {
    nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
    }
    invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);

    // Clear cached merged bean definitions since the post-processors might have
    // modified the original metadata, e.g. replacing placeholders in values...
    beanFactory.clearMetadataCache();
    }

    // 上面的方法内部有调用该重载方法
    private static void invokeBeanDefinitionRegistryPostProcessors(
    Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry) {

    for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {
    postProcessor.postProcessBeanDefinitionRegistry(registry);
    }
    }

    // 上面的方法内部有调用该方法
    private static void sortPostProcessors(List<?> postProcessors, ConfigurableListableBeanFactory beanFactory) {
    Comparator<Object> comparatorToUse = null;
    if (beanFactory instanceof DefaultListableBeanFactory) {
    comparatorToUse = ((DefaultListableBeanFactory) beanFactory).getDependencyComparator();
    }
    if (comparatorToUse == null) {
    comparatorToUse = OrderComparator.INSTANCE;
    }
    postProcessors.sort(comparatorToUse);
    }

9. registerBeanPostProcessors(beanFactory);方法

1
2
3
4
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}

  • PostProcessorRegistrationDelegate的registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContexs)静态方法,具体代码如下:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    public static void registerBeanPostProcessors(
    ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {

    String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

    // Register BeanPostProcessorChecker that logs an info message when
    // a bean is created during BeanPostProcessor instantiation, i.e. when
    // a bean is not eligible for getting processed by all BeanPostProcessors.
    int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
    beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

    // Separate between BeanPostProcessors that implement PriorityOrdered,
    // Ordered, and the rest.
    List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
    List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
    List<String> orderedPostProcessorNames = new ArrayList<>();
    List<String> nonOrderedPostProcessorNames = new ArrayList<>();
    for (String ppName : postProcessorNames) {
    if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
    BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
    priorityOrderedPostProcessors.add(pp);
    if (pp instanceof MergedBeanDefinitionPostProcessor) {
    internalPostProcessors.add(pp);
    }
    }
    else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
    orderedPostProcessorNames.add(ppName);
    }
    else {
    nonOrderedPostProcessorNames.add(ppName);
    }
    }

    // First, register the BeanPostProcessors that implement PriorityOrdered.
    sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
    registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

    // Next, register the BeanPostProcessors that implement Ordered.
    List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
    for (String ppName : orderedPostProcessorNames) {
    BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
    orderedPostProcessors.add(pp);
    if (pp instanceof MergedBeanDefinitionPostProcessor) {
    internalPostProcessors.add(pp);
    }
    }
    sortPostProcessors(orderedPostProcessors, beanFactory);
    registerBeanPostProcessors(beanFactory, orderedPostProcessors);

    // Now, register all regular BeanPostProcessors.
    List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
    for (String ppName : nonOrderedPostProcessorNames) {
    BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
    nonOrderedPostProcessors.add(pp);
    if (pp instanceof MergedBeanDefinitionPostProcessor) {
    internalPostProcessors.add(pp);
    }
    }
    registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

    // Finally, re-register all internal BeanPostProcessors.
    sortPostProcessors(internalPostProcessors, beanFactory);
    registerBeanPostProcessors(beanFactory, internalPostProcessors);

    // Re-register post-processor for detecting inner beans as ApplicationListeners,
    // moving it to the end of the processor chain (for picking up proxies etc).
    beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
    }


    //上面的方法内部有调用该重载方法
    private static void registerBeanPostProcessors(
    ConfigurableListableBeanFactory beanFactory, List<BeanPostProcessor> postProcessors) {

    for (BeanPostProcessor postProcessor : postProcessors) {
    beanFactory.addBeanPostProcessor(postProcessor);
    }
    }

10. initMessageSource();方法

  • org.springframework.context.support.AbstractApplicationContext中的initMessageSource()方法
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    protected void initMessageSource() {
    ConfigurableListableBeanFactory beanFactory = getBeanFactory();
    if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
    this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
    // Make MessageSource aware of parent MessageSource.
    if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
    HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;
    if (hms.getParentMessageSource() == null) {
    // Only set parent context as parent MessageSource if no parent MessageSource
    // registered already.
    hms.setParentMessageSource(getInternalParentMessageSource());
    }
    }
    if (logger.isTraceEnabled()) {
    logger.trace("Using MessageSource [" + this.messageSource + "]");
    }
    }
    else {
    // Use empty MessageSource to be able to accept getMessage calls.
    DelegatingMessageSource dms = new DelegatingMessageSource();
    dms.setParentMessageSource(getInternalParentMessageSource());
    this.messageSource = dms;
    beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
    if (logger.isTraceEnabled()) {
    logger.trace("No '" + MESSAGE_SOURCE_BEAN_NAME + "' bean, using [" + this.messageSource + "]");
    }
    }
    }

11. initApplicationEventMulticaster();方法

  • org.springframework.context.support.AbstractApplicationContext中的initApplicationEventMulticaster()方法
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    protected void initApplicationEventMulticaster() {
    ConfigurableListableBeanFactory beanFactory = getBeanFactory();
    if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
    this.applicationEventMulticaster =
    beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
    if (logger.isTraceEnabled()) {
    logger.trace("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
    }
    }
    else {
    this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
    beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
    if (logger.isTraceEnabled()) {
    logger.trace("No '" + APPLICATION_EVENT_MULTICASTER_BEAN_NAME + "' bean, using " +
    "[" + this.applicationEventMulticaster.getClass().getSimpleName() + "]");
    }
    }
    }

12. onRefresh();方法

  • org.springframework.context.support.AbstractApplicationContext中的onRefresh()方法
    1
    2
    3
    4
    5
    protected void onRefresh() throws BeansException {
    // 该方法是一个空方法,具体的实现依据具体的情况在其子类中继承或进行重写
    // For subclasses: do nothing by default.
    }

13. registerListeners();方法

  • org.springframework.context.support.AbstractApplicationContext中的registerListeners()方法
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    protected void registerListeners() {
    // Register statically specified listeners first.
    for (ApplicationListener<?> listener : getApplicationListeners()) {
    getApplicationEventMulticaster().addApplicationListener(listener);
    }

    // Do not initialize FactoryBeans here: We need to leave all regular beans
    // uninitialized to let post-processors apply to them!
    String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
    for (String listenerBeanName : listenerBeanNames) {
    getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
    }

    // Publish early application events now that we finally have a multicaster...
    Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
    this.earlyApplicationEvents = null;
    if (earlyEventsToProcess != null) {
    for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
    getApplicationEventMulticaster().multicastEvent(earlyEvent);
    }
    }
    }

14. finishBeanFactoryInitialization(beanFactory);方法

  • org.springframework.context.support.AbstractApplicationContext中的finishBeanFactoryInitialization(beanFactory)方法
  • 实例化Bean的核心方法
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
    // Initialize conversion service for this context.
    if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
    beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
    beanFactory.setConversionService(
    beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
    }

    // Register a default embedded value resolver if no bean post-processor
    // (such as a PropertyPlaceholderConfigurer bean) registered any before:
    // at this point, primarily for resolution in annotation attribute values.
    if (!beanFactory.hasEmbeddedValueResolver()) {
    beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
    }

    // Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
    String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
    for (String weaverAwareName : weaverAwareNames) {
    getBean(weaverAwareName);
    }

    // Stop using the temporary ClassLoader for type matching.
    beanFactory.setTempClassLoader(null);

    // Allow for caching all bean definition metadata, not expecting further changes.
    beanFactory.freezeConfiguration();

    // Instantiate all remaining (non-lazy-init) singletons.
    // 实例化bean的核心代码
    beanFactory.preInstantiateSingletons();
    // 上一行的preInstantiateSingletons()方法定义在ConfigurableListableBeanFactory接口中,
    // 具体实现是在DefaultListableBeanFactory中preInstantiateSingletons()方法
    }

DefaultListableBeanFactory中preInstantiateSingletons()方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
@Override
public void preInstantiateSingletons() throws BeansException {
if (logger.isTraceEnabled()) {
logger.trace("Pre-instantiating singletons in " + this);
}

// Iterate over a copy to allow for init methods which in turn register new bean definitions.
// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

// Trigger initialization of all non-lazy singleton beans...
// 遍历beanDefinitionNames这个ArrayList对象中的beanName,
for (String beanName : beanNames) {
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
if (isFactoryBean(beanName)) {
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
if (bean instanceof FactoryBean) {
final FactoryBean<?> factory = (FactoryBean<?>) bean;
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
((SmartFactoryBean<?>) factory)::isEagerInit,
getAccessControlContext());
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
if (isEagerInit) {
// 创建bean并递归构建Bean之间的依赖关系
getBean(beanName);
}
}
}
else {
// 创建bean并递归构建Bean之间的依赖关系
getBean(beanName);
}
}
}

// Trigger post-initialization callback for all applicable beans...
for (String beanName : beanNames) {
Object singletonInstance = getSingleton(beanName);
if (singletonInstance instanceof SmartInitializingSingleton) {
final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
smartSingleton.afterSingletonsInstantiated();
return null;
}, getAccessControlContext());
}
else {
smartSingleton.afterSingletonsInstantiated();
}
}
}
}


preInstantiateSingletons()方法中调用的getBean方法

  • getBean方法定义在BeanFactory接口中
  • getBean方法org.springframework.beans.factory.support.AbstractBeanFactory中实现
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    @Override
    public Object getBean(String name) throws BeansException {
    return doGetBean(name, null, null, false);
    }



    //下面是上面方法调用doGetBean(name, null, null, false)方法
    // 这个方法特别长,以下是完整代码:
    @SuppressWarnings("unchecked")
    protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
    @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {

    final String beanName = transformedBeanName(name);
    Object bean;

    // Eagerly check singleton cache for manually registered singletons.
    Object sharedInstance = getSingleton(beanName);
    if (sharedInstance != null && args == null) {
    if (logger.isTraceEnabled()) {
    if (isSingletonCurrentlyInCreation(beanName)) {
    logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
    "' that is not fully initialized yet - a consequence of a circular reference");
    }
    else {
    logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
    }
    }
    bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
    }

    else {
    // Fail if we're already creating this bean instance:
    // We're assumably within a circular reference.
    if (isPrototypeCurrentlyInCreation(beanName)) {
    throw new BeanCurrentlyInCreationException(beanName);
    }

    // Check if bean definition exists in this factory.
    BeanFactory parentBeanFactory = getParentBeanFactory();
    if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
    // Not found -> check parent.
    String nameToLookup = originalBeanName(name);
    if (parentBeanFactory instanceof AbstractBeanFactory) {
    return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
    nameToLookup, requiredType, args, typeCheckOnly);
    }
    else if (args != null) {
    // Delegation to parent with explicit args.
    return (T) parentBeanFactory.getBean(nameToLookup, args);
    }
    else if (requiredType != null) {
    // No args -> delegate to standard getBean method.
    return parentBeanFactory.getBean(nameToLookup, requiredType);
    }
    else {
    return (T) parentBeanFactory.getBean(nameToLookup);
    }
    }

    if (!typeCheckOnly) {
    markBeanAsCreated(beanName);
    }

    try {
    final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
    checkMergedBeanDefinition(mbd, beanName, args);

    // Guarantee initialization of beans that the current bean depends on.
    // 获取当前bean的依赖关系
    String[] dependsOn = mbd.getDependsOn();
    // 根据依赖的beanName递归调用getBean()方法,不断探寻其依赖的bean,直到getSingleton方法返回依赖的Bean,即当前正在创建的Bean
    // 直到依赖关系最底层的bean没有依赖对象了,至此整个递归过程结束
    if (dependsOn != null) {
    for (String dep : dependsOn) {
    if (isDependent(beanName, dep)) {
    throw new BeanCreationException(mbd.getResourceDescription(), beanName,
    "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
    }
    //
    registerDependentBean(dep, beanName);
    try {
    getBean(dep);
    }
    catch (NoSuchBeanDefinitionException ex) {
    throw new BeanCreationException(mbd.getResourceDescription(), beanName,
    "'" + beanName + "' depends on missing bean '" + dep + "'", ex);
    }
    }
    }
    // Create bean instance.
    if (mbd.isSingleton()) {
    // getSingleton方法的参数是createBean(beanName, mbd, args)方法的返回值
    sharedInstance = getSingleton(beanName, () -> {
    try {
    // createBean方法在AbstractBeanFactory抽象类中定义,具体实现是在AbstractAutowireCapableBeanFactory抽象类中
    return createBean(beanName, mbd, args);
    }
    catch (BeansException ex) {
    // Explicitly remove instance from singleton cache: It might have been put there
    // eagerly by the creation process, to allow for circular reference resolution.
    // Also remove any beans that received a temporary reference to the bean.
    destroySingleton(beanName);
    throw ex;
    }
    });
    bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
    }

    else if (mbd.isPrototype()) {
    // It's a prototype -> create a new instance.
    Object prototypeInstance = null;
    try {
    beforePrototypeCreation(beanName);
    prototypeInstance = createBean(beanName, mbd, args);
    }
    finally {
    afterPrototypeCreation(beanName);
    }
    bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
    }

    else {
    String scopeName = mbd.getScope();
    final Scope scope = this.scopes.get(scopeName);
    if (scope == null) {
    throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
    }
    try {
    Object scopedInstance = scope.get(beanName, () -> {
    beforePrototypeCreation(beanName);
    try {
    return createBean(beanName, mbd, args);
    }
    finally {
    afterPrototypeCreation(beanName);
    }
    });
    bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
    }
    catch (IllegalStateException ex) {
    throw new BeanCreationException(beanName,
    "Scope '" + scopeName + "' is not active for the current thread; consider " +
    "defining a scoped proxy for this bean if you intend to refer to it from a singleton",
    ex);
    }
    }
    }
    catch (BeansException ex) {
    cleanupAfterBeanCreationFailure(beanName);
    throw ex;
    }
    }

    // Check if required type matches the type of the actual bean instance.
    if (requiredType != null && !requiredType.isInstance(bean)) {
    try {
    T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
    if (convertedBean == null) {
    throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
    }
    return convertedBean;
    }
    catch (TypeMismatchException ex) {
    if (logger.isTraceEnabled()) {
    logger.trace("Failed to convert bean '" + name + "' to required type '" +
    ClassUtils.getQualifiedName(requiredType) + "'", ex);
    }
    throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
    }
    }
    return (T) bean;
    }


AbstractAutowireCapableBeanFactory类中的createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)方法

  • 代码位置:org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    @Override
    protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
    throws BeanCreationException {

    if (logger.isTraceEnabled()) {
    logger.trace("Creating instance of bean '" + beanName + "'");
    }
    RootBeanDefinition mbdToUse = mbd;

    // Make sure bean class is actually resolved at this point, and
    // clone the bean definition in case of a dynamically resolved Class
    // which cannot be stored in the shared merged bean definition.
    Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
    if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
    mbdToUse = new RootBeanDefinition(mbd);
    mbdToUse.setBeanClass(resolvedClass);
    }

    // Prepare method overrides.
    try {
    mbdToUse.prepareMethodOverrides();
    }
    catch (BeanDefinitionValidationException ex) {
    throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
    beanName, "Validation of method overrides failed", ex);
    }

    try {
    // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
    Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
    if (bean != null) {
    return bean;
    }
    }
    catch (Throwable ex) {
    throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
    "BeanPostProcessor before instantiation of bean failed", ex);
    }

    try {
    // createBean方法的核心 该方法会返回Bean对象的实例,具体代码在下面贴出
    Object beanInstance = doCreateBean(beanName, mbdToUse, args);
    if (logger.isTraceEnabled()) {
    logger.trace("Finished creating instance of bean '" + beanName + "'");
    }
    return beanInstance;
    }
    catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
    // A previously detected exception with proper bean creation context already,
    // or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
    throw ex;
    }
    catch (Throwable ex) {
    throw new BeanCreationException(
    mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
    }
    }



    // 在AbstractAutowireCapableBeanFactory抽象类的createBean方法中调用的doCreateBean(beanName, mbdToUse, args)方法
    protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
    throws BeanCreationException {

    // Instantiate the bean.
    BeanWrapper instanceWrapper = null;
    if (mbd.isSingleton()) {
    instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
    }
    if (instanceWrapper == null) {
    // 创建Bean实例
    instanceWrapper = createBeanInstance(beanName, mbd, args);
    }
    final Object bean = instanceWrapper.getWrappedInstance();
    Class<?> beanType = instanceWrapper.getWrappedClass();
    if (beanType != NullBean.class) {
    mbd.resolvedTargetType = beanType;
    }

    // Allow post-processors to modify the merged bean definition.
    synchronized (mbd.postProcessingLock) {
    if (!mbd.postProcessed) {
    try {
    applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
    }
    catch (Throwable ex) {
    throw new BeanCreationException(mbd.getResourceDescription(), beanName,
    "Post-processing of merged bean definition failed", ex);
    }
    mbd.postProcessed = true;
    }
    }

    // Eagerly cache singletons to be able to resolve circular references
    // even when triggered by lifecycle interfaces like BeanFactoryAware.
    boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
    isSingletonCurrentlyInCreation(beanName));
    if (earlySingletonExposure) {
    if (logger.isTraceEnabled()) {
    logger.trace("Eagerly caching bean '" + beanName +
    "' to allow for resolving potential circular references");
    }
    addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
    }

    // Initialize the bean instance.
    Object exposedObject = bean;
    try {
    // 填充bean,实际进行依赖注入的地方
    populateBean(beanName, mbd, instanceWrapper);
    exposedObject = initializeBean(beanName, exposedObject, mbd);
    }
    catch (Throwable ex) {
    if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
    throw (BeanCreationException) ex;
    }
    else {
    throw new BeanCreationException(
    mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
    }
    }

    if (earlySingletonExposure) {
    Object earlySingletonReference = getSingleton(beanName, false);
    if (earlySingletonReference != null) {
    if (exposedObject == bean) {
    exposedObject = earlySingletonReference;
    }
    else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
    String[] dependentBeans = getDependentBeans(beanName);
    Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
    for (String dependentBean : dependentBeans) {
    if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
    actualDependentBeans.add(dependentBean);
    }
    }
    if (!actualDependentBeans.isEmpty()) {
    throw new BeanCurrentlyInCreationException(beanName,
    "Bean with name '" + beanName + "' has been injected into other beans [" +
    StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
    "] in its raw version as part of a circular reference, but has eventually been " +
    "wrapped. This means that said other beans do not use the final version of the " +
    "bean. This is often the result of over-eager type matching - consider using " +
    "'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
    }
    }
    }
    }

    // Register bean as disposable.
    try {
    registerDisposableBeanIfNecessary(beanName, bean, mbd);
    }
    catch (BeanDefinitionValidationException ex) {
    throw new BeanCreationException(
    mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
    }

    return exposedObject;
    }


    // 在AbstractAutowireCapableBeanFactory抽象类的doCreateBean方法中调用的 createBeanInstance(beanName, mbd, args)方法
    protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
    // Make sure bean class is actually resolved at this point.
    Class<?> beanClass = resolveBeanClass(mbd, beanName);

    if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
    throw new BeanCreationException(mbd.getResourceDescription(), beanName,
    "Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
    }

    Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
    if (instanceSupplier != null) {
    return obtainFromSupplier(instanceSupplier, beanName);
    }

    if (mbd.getFactoryMethodName() != null) {
    return instantiateUsingFactoryMethod(beanName, mbd, args);
    }

    // Shortcut when re-creating the same bean...
    boolean resolved = false;
    boolean autowireNecessary = false;
    if (args == null) {
    synchronized (mbd.constructorArgumentLock) {
    if (mbd.resolvedConstructorOrFactoryMethod != null) {
    resolved = true;
    autowireNecessary = mbd.constructorArgumentsResolved;
    }
    }
    }
    if (resolved) {
    if (autowireNecessary) {
    return autowireConstructor(beanName, mbd, null, null);
    }
    else {
    // 调用instantiateBean方法
    return instantiateBean(beanName, mbd);
    }
    }

    // Candidate constructors for autowiring?
    Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
    if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
    mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
    return autowireConstructor(beanName, mbd, ctors, args);
    }

    // Preferred constructors for default construction?
    ctors = mbd.getPreferredConstructors();
    if (ctors != null) {
    return autowireConstructor(beanName, mbd, ctors, null);
    }

    // No special handling: simply use no-arg constructor.
    return instantiateBean(beanName, mbd);
    }

    // 在AbstractAutowireCapableBeanFactory抽象类的createBeanInstance方法中调用的instantiateBean(beanName, mbd)方法
    protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
    try {
    Object beanInstance;
    final BeanFactory parent = this;
    if (System.getSecurityManager() != null) {
    // 核心逻辑
    beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () ->
    getInstantiationStrategy().instantiate(mbd, beanName, parent),
    getAccessControlContext());
    }
    else {
    // 核心逻辑
    beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
    }
    BeanWrapper bw = new BeanWrapperImpl(beanInstance);
    initBeanWrapper(bw);
    return bw;
    }
    catch (Throwable ex) {
    throw new BeanCreationException(
    mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
    }
    }

    // 上面的getInstantiationStrategy()方法代码
    protected InstantiationStrategy getInstantiationStrategy() {
    return this.instantiationStrategy;
    }

getInstantiationStrategy()方法的返回接口对象的策略对象的一个实现SimpleInstantiationStrategy

  • org.springframework.beans.factory.support.SimpleInstantiationStrategy
  • SimpleInstantiationStrategy.instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner)方法的具体实现:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    @Override
    public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
    // Don't override the class with CGLIB if no overrides.
    if (!bd.hasMethodOverrides()) {
    Constructor<?> constructorToUse;
    synchronized (bd.constructorArgumentLock) {
    constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
    if (constructorToUse == null) {
    final Class<?> clazz = bd.getBeanClass();
    if (clazz.isInterface()) {
    throw new BeanInstantiationException(clazz, "Specified class is an interface");
    }
    try {
    if (System.getSecurityManager() != null) {
    constructorToUse = AccessController.doPrivileged(
    (PrivilegedExceptionAction<Constructor<?>>) clazz::getDeclaredConstructor);
    }
    else {
    constructorToUse = clazz.getDeclaredConstructor();
    }
    bd.resolvedConstructorOrFactoryMethod = constructorToUse;
    }
    catch (Throwable ex) {
    throw new BeanInstantiationException(clazz, "No default constructor found", ex);
    }
    }
    }
    // 调用静态方法BeanUtils.instantiateClass(constructorToUse);
    return BeanUtils.instantiateClass(constructorToUse);
    }
    else {
    // Must generate CGLIB subclass.
    return instantiateWithMethodInjection(bd, beanName, owner);
    }
    }

    静态方法BeanUtils.instantiateClass(constructorToUse)的实现细节

  • 代码位置:org.springframework.beans.BeanUtils
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    public static <T> T instantiateClass(Constructor<T> ctor, Object... args) throws BeanInstantiationException {
    Assert.notNull(ctor, "Constructor must not be null");
    try {
    ReflectionUtils.makeAccessible(ctor);
    // 判断是否是Kotlin类型
    if (KotlinDetector.isKotlinReflectPresent() && KotlinDetector.isKotlinType(ctor.getDeclaringClass())) {
    // 是Kotlin类型
    return KotlinDelegate.instantiateClass(ctor, args);
    }
    else {
    // 不是Kotlin类型
    Class<?>[] parameterTypes = ctor.getParameterTypes();
    Assert.isTrue(args.length <= parameterTypes.length, "Can't specify more arguments than constructor parameters");
    Object[] argsWithDefaultValues = new Object[args.length];
    for (int i = 0 ; i < args.length; i++) {
    if (args[i] == null) {
    Class<?> parameterType = parameterTypes[i];
    argsWithDefaultValues[i] = (parameterType.isPrimitive() ? DEFAULT_TYPE_VALUES.get(parameterType) : null);
    }
    else {
    argsWithDefaultValues[i] = args[i];
    }
    }
    // 调用Constructor的newInstance方法,使用反射创建实例
    // 到此之后bean实例创建完成
    return ctor.newInstance(argsWithDefaultValues);
    }
    }
    catch (InstantiationException ex) {
    throw new BeanInstantiationException(ctor, "Is it an abstract class?", ex);
    }
    catch (IllegalAccessException ex) {
    throw new BeanInstantiationException(ctor, "Is the constructor accessible?", ex);
    }
    catch (IllegalArgumentException ex) {
    throw new BeanInstantiationException(ctor, "Illegal arguments for constructor", ex);
    }
    catch (InvocationTargetException ex) {
    throw new BeanInstantiationException(ctor, "Constructor threw exception", ex.getTargetException());
    }
    }

AbstractAutowireCapableBeanFactory抽象类的中doCreateBean方法中调用的populateBean(beanName, mbd, instanceWrapper)方法

  • 在AbstractAutowireCapableBeanFactory抽象类中的方法populateBean方法
  • 该方法用于填充bean 具体发生依赖注入的地方
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    @SuppressWarnings("deprecation")  // for postProcessPropertyValues
    protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
    if (bw == null) {
    if (mbd.hasPropertyValues()) {
    throw new BeanCreationException(
    mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
    }
    else {
    // Skip property population phase for null instance.
    return;
    }
    }

    // Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
    // state of the bean before properties are set. This can be used, for example,
    // to support styles of field injection.
    boolean continueWithPropertyPopulation = true;

    if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
    for (BeanPostProcessor bp : getBeanPostProcessors()) {
    if (bp instanceof InstantiationAwareBeanPostProcessor) {
    InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
    if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
    continueWithPropertyPopulation = false;
    break;
    }
    }
    }
    }

    if (!continueWithPropertyPopulation) {
    return;
    }
    // 获取bean的所有属性 用于后面配置Property元素 即依赖关系
    PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);

    int resolvedAutowireMode = mbd.getResolvedAutowireMode();
    if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
    MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
    // Add property values based on autowire by name if applicable.
    if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
    autowireByName(beanName, mbd, bw, newPvs);
    }
    // Add property values based on autowire by type if applicable.
    if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
    autowireByType(beanName, mbd, bw, newPvs);
    }
    pvs = newPvs;
    }

    boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
    boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);

    PropertyDescriptor[] filteredPds = null;
    if (hasInstAwareBpps) {
    if (pvs == null) {
    pvs = mbd.getPropertyValues();
    }
    for (BeanPostProcessor bp : getBeanPostProcessors()) {
    if (bp instanceof InstantiationAwareBeanPostProcessor) {
    InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
    PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
    if (pvsToUse == null) {
    if (filteredPds == null) {
    filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
    }
    pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
    if (pvsToUse == null) {
    return;
    }
    }
    pvs = pvsToUse;
    }
    }
    }
    if (needsDepCheck) {
    if (filteredPds == null) {
    filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
    }
    checkDependencies(beanName, mbd, filteredPds, pvs);
    }

    if (pvs != null) {
    // 核心逻辑 applyPropertyValues方法的具体代码在下面
    applyPropertyValues(beanName, mbd, bw, pvs);
    }
    }

    // 上面方法中调用的applyPropertyValues方法具体代码
    protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
    if (pvs.isEmpty()) {
    return;
    }

    if (System.getSecurityManager() != null && bw instanceof BeanWrapperImpl) {
    ((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());
    }

    MutablePropertyValues mpvs = null;
    List<PropertyValue> original;

    if (pvs instanceof MutablePropertyValues) {
    mpvs = (MutablePropertyValues) pvs;
    if (mpvs.isConverted()) {
    // Shortcut: use the pre-converted values as-is.
    try {
    bw.setPropertyValues(mpvs);
    return;
    }
    catch (BeansException ex) {
    throw new BeanCreationException(
    mbd.getResourceDescription(), beanName, "Error setting property values", ex);
    }
    }
    original = mpvs.getPropertyValueList();
    }
    else {
    original = Arrays.asList(pvs.getPropertyValues());
    }

    TypeConverter converter = getCustomTypeConverter();
    if (converter == null) {
    converter = bw;
    }
    BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);

    // Create a deep copy, resolving any references for values.
    List<PropertyValue> deepCopy = new ArrayList<>(original.size());
    boolean resolveNecessary = false;
    for (PropertyValue pv : original) {
    if (pv.isConverted()) {
    deepCopy.add(pv);
    }
    else {
    String propertyName = pv.getName();
    Object originalValue = pv.getValue();
    if (originalValue == AutowiredPropertyMarker.INSTANCE) {
    Method writeMethod = bw.getPropertyDescriptor(propertyName).getWriteMethod();
    if (writeMethod == null) {
    throw new IllegalArgumentException("Autowire marker for property without write method: " + pv);
    }
    originalValue = new DependencyDescriptor(new MethodParameter(writeMethod, 0), true);
    }
    // 获取property对应的值 resolveValueIfNecessary方法的代码在下面给出
    Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
    Object convertedValue = resolvedValue;
    boolean convertible = bw.isWritableProperty(propertyName) &&
    !PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);
    if (convertible) {
    convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);
    }
    // Possibly store converted value in merged bean definition,
    // in order to avoid re-conversion for every created bean instance.
    if (resolvedValue == originalValue) {
    if (convertible) {
    pv.setConvertedValue(convertedValue);
    }
    deepCopy.add(pv);
    }
    else if (convertible && originalValue instanceof TypedStringValue &&
    !((TypedStringValue) originalValue).isDynamic() &&
    !(convertedValue instanceof Collection || ObjectUtils.isArray(convertedValue))) {
    pv.setConvertedValue(convertedValue);
    deepCopy.add(pv);
    }
    else {
    resolveNecessary = true;
    deepCopy.add(new PropertyValue(pv, convertedValue));
    }
    }
    }
    if (mpvs != null && !resolveNecessary) {
    mpvs.setConverted();
    }

    // Set our (possibly massaged) deep copy.
    try {
    // 获取到依赖的对象值后 将依赖值注入
    bw.setPropertyValues(new MutablePropertyValues(deepCopy));
    }
    catch (BeansException ex) {
    throw new BeanCreationException(
    mbd.getResourceDescription(), beanName, "Error setting property values", ex);
    }
    }


    ####################################################################################################################################################33

valueResolver.resolveValueIfNecessary(pv, originalValue);对应的方法

  • 代码位置:org.springframework.beans.factory.support.BeanDefinitionValueResolver
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    @Nullable
    public Object resolveValueIfNecessary(Object argName, @Nullable Object value) {
    // We must check each value to see whether it requires a runtime reference
    // to another bean to be resolved.
    if (value instanceof RuntimeBeanReference) {
    RuntimeBeanReference ref = (RuntimeBeanReference) value;
    // 核心逻辑 解决Bean依赖关系 具体代码在下方贴出
    return resolveReference(argName, ref);
    }
    else if (value instanceof RuntimeBeanNameReference) {
    String refName = ((RuntimeBeanNameReference) value).getBeanName();
    refName = String.valueOf(doEvaluate(refName));
    if (!this.beanFactory.containsBean(refName)) {
    throw new BeanDefinitionStoreException(
    "Invalid bean name '" + refName + "' in bean reference for " + argName);
    }
    return refName;
    }
    else if (value instanceof BeanDefinitionHolder) {
    // Resolve BeanDefinitionHolder: contains BeanDefinition with name and aliases.
    BeanDefinitionHolder bdHolder = (BeanDefinitionHolder) value;
    return resolveInnerBean(argName, bdHolder.getBeanName(), bdHolder.getBeanDefinition());
    }
    else if (value instanceof BeanDefinition) {
    // Resolve plain BeanDefinition, without contained name: use dummy name.
    BeanDefinition bd = (BeanDefinition) value;
    String innerBeanName = "(inner bean)" + BeanFactoryUtils.GENERATED_BEAN_NAME_SEPARATOR +
    ObjectUtils.getIdentityHexString(bd);
    return resolveInnerBean(argName, innerBeanName, bd);
    }
    else if (value instanceof DependencyDescriptor) {
    Set<String> autowiredBeanNames = new LinkedHashSet<>(4);
    Object result = this.beanFactory.resolveDependency(
    (DependencyDescriptor) value, this.beanName, autowiredBeanNames, this.typeConverter);
    for (String autowiredBeanName : autowiredBeanNames) {
    if (this.beanFactory.containsBean(autowiredBeanName)) {
    this.beanFactory.registerDependentBean(autowiredBeanName, this.beanName);
    }
    }
    return result;
    }
    else if (value instanceof ManagedArray) {
    // May need to resolve contained runtime references.
    ManagedArray array = (ManagedArray) value;
    Class<?> elementType = array.resolvedElementType;
    if (elementType == null) {
    String elementTypeName = array.getElementTypeName();
    if (StringUtils.hasText(elementTypeName)) {
    try {
    elementType = ClassUtils.forName(elementTypeName, this.beanFactory.getBeanClassLoader());
    array.resolvedElementType = elementType;
    }
    catch (Throwable ex) {
    // Improve the message by showing the context.
    throw new BeanCreationException(
    this.beanDefinition.getResourceDescription(), this.beanName,
    "Error resolving array type for " + argName, ex);
    }
    }
    else {
    elementType = Object.class;
    }
    }
    return resolveManagedArray(argName, (List<?>) value, elementType);
    }
    else if (value instanceof ManagedList) {
    // May need to resolve contained runtime references.
    return resolveManagedList(argName, (List<?>) value);
    }
    else if (value instanceof ManagedSet) {
    // May need to resolve contained runtime references.
    return resolveManagedSet(argName, (Set<?>) value);
    }
    else if (value instanceof ManagedMap) {
    // May need to resolve contained runtime references.
    return resolveManagedMap(argName, (Map<?, ?>) value);
    }
    else if (value instanceof ManagedProperties) {
    Properties original = (Properties) value;
    Properties copy = new Properties();
    original.forEach((propKey, propValue) -> {
    if (propKey instanceof TypedStringValue) {
    propKey = evaluate((TypedStringValue) propKey);
    }
    if (propValue instanceof TypedStringValue) {
    propValue = evaluate((TypedStringValue) propValue);
    }
    if (propKey == null || propValue == null) {
    throw new BeanCreationException(
    this.beanDefinition.getResourceDescription(), this.beanName,
    "Error converting Properties key/value pair for " + argName + ": resolved to null");
    }
    copy.put(propKey, propValue);
    });
    return copy;
    }
    else if (value instanceof TypedStringValue) {
    // Convert value to target type here.
    TypedStringValue typedStringValue = (TypedStringValue) value;
    Object valueObject = evaluate(typedStringValue);
    try {
    Class<?> resolvedTargetType = resolveTargetType(typedStringValue);
    if (resolvedTargetType != null) {
    return this.typeConverter.convertIfNecessary(valueObject, resolvedTargetType);
    }
    else {
    return valueObject;
    }
    }
    catch (Throwable ex) {
    // Improve the message by showing the context.
    throw new BeanCreationException(
    this.beanDefinition.getResourceDescription(), this.beanName,
    "Error converting typed String value for " + argName, ex);
    }
    }
    else if (value instanceof NullBean) {
    return null;
    }
    else {
    return evaluate(value);
    }
    }


    // 上面resolveValueIfNecessary方法中调用的resolveReference方法
    // 最后获取到依赖的bean
    @Nullable
    private Object resolveReference(Object argName, RuntimeBeanReference ref) {
    try {
    Object bean;
    Class<?> beanType = ref.getBeanType();
    if (ref.isToParent()) {
    BeanFactory parent = this.beanFactory.getParentBeanFactory();
    if (parent == null) {
    throw new BeanCreationException(
    this.beanDefinition.getResourceDescription(), this.beanName,
    "Cannot resolve reference to bean " + ref +
    " in parent factory: no parent factory available");
    }
    if (beanType != null) {
    // 发生递归调用
    bean = parent.getBean(beanType);
    }
    else {
    // 发生递归调用 根据依赖的名称从BeanFactory中递归得到依赖 最后获取到依赖的bean
    bean = parent.getBean(String.valueOf(doEvaluate(ref.getBeanName())));
    }
    }
    else {
    String resolvedName;
    if (beanType != null) {
    NamedBeanHolder<?> namedBean = this.beanFactory.resolveNamedBean(beanType);
    bean = namedBean.getBeanInstance();
    resolvedName = namedBean.getBeanName();
    }
    else {
    resolvedName = String.valueOf(doEvaluate(ref.getBeanName()));
    bean = this.beanFactory.getBean(resolvedName);
    }
    this.beanFactory.registerDependentBean(resolvedName, this.beanName);
    }
    if (bean instanceof NullBean) {
    bean = null;
    }
    return bean;
    }
    catch (BeansException ex) {
    throw new BeanCreationException(
    this.beanDefinition.getResourceDescription(), this.beanName,
    "Cannot resolve reference to bean '" + ref.getBeanName() + "' while setting " + argName, ex);
    }
    }

AbstractPropertyAccessor的setPropertyValues(PropertyValues pvs)方法

  • 代码位置:org.springframework.beans.AbstractPropertyAccessor
  • 循环属性列表
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    @Override
    public void setPropertyValues(PropertyValues pvs) throws BeansException {
    setPropertyValues(pvs, false, false);
    }

    // 循环属性列表
    @Override
    public void setPropertyValues(PropertyValues pvs, boolean ignoreUnknown, boolean ignoreInvalid)
    throws BeansException {

    List<PropertyAccessException> propertyAccessExceptions = null;
    List<PropertyValue> propertyValues = (pvs instanceof MutablePropertyValues ?
    ((MutablePropertyValues) pvs).getPropertyValueList() : Arrays.asList(pvs.getPropertyValues()));
    // 循环属性列表
    for (PropertyValue pv : propertyValues) {
    try {
    // This method may throw any BeansException, which won't be caught
    // here, if there is a critical failure such as no matching field.
    // We can attempt to deal only with less serious exceptions.
    // 该方法通过AbstractNestablePropertyAccessor的setPropertyValue(PropertyValue pv)方法实现
    setPropertyValue(pv);
    }
    catch (NotWritablePropertyException ex) {
    if (!ignoreUnknown) {
    throw ex;
    }
    // Otherwise, just ignore it and continue...
    }
    catch (NullValueInNestedPathException ex) {
    if (!ignoreInvalid) {
    throw ex;
    }
    // Otherwise, just ignore it and continue...
    }
    catch (PropertyAccessException ex) {
    if (propertyAccessExceptions == null) {
    propertyAccessExceptions = new ArrayList<>();
    }
    propertyAccessExceptions.add(ex);
    }
    }

    // If we encountered individual exceptions, throw the composite exception.
    if (propertyAccessExceptions != null) {
    PropertyAccessException[] paeArray = propertyAccessExceptions.toArray(new PropertyAccessException[0]);
    throw new PropertyBatchUpdateException(paeArray);
    }
    }

AbstractNestablePropertyAccessor的 setPropertyValue(PropertyValue pv)方法

  • 代码位置:org.springframework.beans.AbstractNestablePropertyAccessor
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    @Override
    public void setPropertyValue(PropertyValue pv) throws BeansException {
    PropertyTokenHolder tokens = (PropertyTokenHolder) pv.resolvedTokens;
    if (tokens == null) {
    String propertyName = pv.getName();
    AbstractNestablePropertyAccessor nestedPa;
    try {
    nestedPa = getPropertyAccessorForPropertyPath(propertyName);
    }
    catch (NotReadablePropertyException ex) {
    throw new NotWritablePropertyException(getRootClass(), this.nestedPath + propertyName,
    "Nested property in path '" + propertyName + "' does not exist", ex);
    }
    tokens = getPropertyNameTokens(getFinalPath(nestedPa, propertyName));
    if (nestedPa == this) {
    pv.getOriginalPropertyValue().resolvedTokens = tokens;
    }
    nestedPa.setPropertyValue(tokens, pv);
    }
    else {
    setPropertyValue(tokens, pv);
    }
    }
    ########################################################################################################################################
  • 上面setPropertyValue(PropertyValue pv)方法的重载方法setPropertyValue(PropertyTokenHolder tokens, PropertyValue pv)
    1
    2
    3
    4
    5
    6
    7
    8
    protected void setPropertyValue(PropertyTokenHolder tokens, PropertyValue pv) throws BeansException {
    if (tokens.keys != null) {
    processKeyedProperty(tokens, pv);
    }
    else {
    processLocalProperty(tokens, pv);
    }
    }
  • processLocalProperty(PropertyTokenHolder tokens, PropertyValue pv)方法
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    private void processLocalProperty(PropertyTokenHolder tokens, PropertyValue pv) {
    PropertyHandler ph = getLocalPropertyHandler(tokens.actualName);
    if (ph == null || !ph.isWritable()) {
    if (pv.isOptional()) {
    if (logger.isDebugEnabled()) {
    logger.debug("Ignoring optional value for property '" + tokens.actualName +
    "' - property not found on bean class [" + getRootClass().getName() + "]");
    }
    return;
    }
    else {
    throw createNotWritablePropertyException(tokens.canonicalName);
    }
    }

    Object oldValue = null;
    try {
    Object originalValue = pv.getValue();//
    Object valueToApply = originalValue;//
    if (!Boolean.FALSE.equals(pv.conversionNecessary)) {
    if (pv.isConverted()) {
    valueToApply = pv.getConvertedValue();
    }
    else {
    if (isExtractOldValueForEditor() && ph.isReadable()) {
    try {
    oldValue = ph.getValue();
    }
    catch (Exception ex) {
    if (ex instanceof PrivilegedActionException) {
    ex = ((PrivilegedActionException) ex).getException();
    }
    if (logger.isDebugEnabled()) {
    logger.debug("Could not read previous value of property '" +
    this.nestedPath + tokens.canonicalName + "'", ex);
    }
    }
    }
    valueToApply = convertForProperty(
    tokens.canonicalName, oldValue, originalValue, ph.toTypeDescriptor());
    }
    pv.getOriginalPropertyValue().conversionNecessary = (valueToApply != originalValue);
    }
    ph.setValue(valueToApply);// 具体代码在下方列出
    }
    catch (TypeMismatchException ex) {
    throw ex;
    }
    catch (InvocationTargetException ex) {
    PropertyChangeEvent propertyChangeEvent = new PropertyChangeEvent(
    getRootInstance(), this.nestedPath + tokens.canonicalName, oldValue, pv.getValue());
    if (ex.getTargetException() instanceof ClassCastException) {
    throw new TypeMismatchException(propertyChangeEvent, ph.getPropertyType(), ex.getTargetException());
    }
    else {
    Throwable cause = ex.getTargetException();
    if (cause instanceof UndeclaredThrowableException) {
    // May happen e.g. with Groovy-generated methods
    cause = cause.getCause();
    }
    throw new MethodInvocationException(propertyChangeEvent, cause);
    }
    }
    catch (Exception ex) {
    PropertyChangeEvent pce = new PropertyChangeEvent(
    getRootInstance(), this.nestedPath + tokens.canonicalName, oldValue, pv.getValue());
    throw new MethodInvocationException(pce, ex);
    }
    }

  • 上述ph.setValue方法在org.springframework.beans.AbstractNestablePropertyAccessor抽象类中定义
  • public abstract void setValue(@Nullable Object value) throws Exception;
  • 一个具体实现在org.springframework.beans.BeanWrapperImp的内部类BeanPropertyHandler中,完整代码如下:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    private final PropertyDescriptor pd;  //BeanPropertyHandler中的字段

    @Override
    public void setValue(final @Nullable Object value) throws Exception {
    final Method writeMethod = (this.pd instanceof GenericTypeAwarePropertyDescriptor ?
    ((GenericTypeAwarePropertyDescriptor) this.pd).getWriteMethodForActualAccess() :
    this.pd.getWriteMethod());// 找到属性的set方法
    if (System.getSecurityManager() != null) {
    AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
    ReflectionUtils.makeAccessible(writeMethod);
    return null;
    });
    try {
    AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () ->
    writeMethod.invoke(getWrappedInstance(), value), acc);
    // 调用Method的invoke方法,完成属性注入
    }
    catch (PrivilegedActionException ex) {
    throw ex.getException();
    }
    }
    else {
    ReflectionUtils.makeAccessible(writeMethod);
    writeMethod.invoke(getWrappedInstance(), value);//调用Method的invoke方法,完成属性注入
    }
    }
  • 至此Ioc容器的启动过程基本结束

15. finishRefresh();方法

  • org.springframework.context.support.AbstractApplicationContext中的finishRefresh()方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
protected void finishRefresh() {
// Clear context-level resource caches (such as ASM metadata from scanning).
clearResourceCaches();

// Initialize lifecycle processor for this context.
initLifecycleProcessor();

// Propagate refresh to lifecycle processor first.
getLifecycleProcessor().onRefresh();

// Publish the final event.
publishEvent(new ContextRefreshedEvent(this));

// Participate in LiveBeansView MBean, if active.
LiveBeansView.registerApplicationContext(this);
}

16refresh()过程抛出异常时

  • 之中有两个处理方法destroyBeans()和cancelRefresh(ex)

16.1 destroyBeans();方法

  • org.springframework.context.support.AbstractApplicationContext中的destroyBeans()方法
1
2
3
protected void destroyBeans() {
getBeanFactory().destroySingletons();
}

16.2 cancelRefresh(ex);方法

  • org.springframework.context.support.AbstractApplicationContext中的cancelRefresh(ex)方法
    1
    2
    3
    protected void cancelRefresh(BeansException ex) {
    this.active.set(false);
    }

    16.3抛出异常BeansException

17 resetCommonCaches();方法

  • org.springframework.context.support.AbstractApplicationContext中的resetCommonCaches()方法
  • try-catch-finally代码块中finally包裹的方法
    1
    2
    3
    4
    5
    6
    protected void resetCommonCaches() {
    ReflectionUtils.clearCache();
    AnnotationUtils.clearCache();
    ResolvableType.clearCache();
    CachedIntrospectionResults.clearClassLoader(getClassLoader());
    }
  • 执行到此Ioc容器启动完成,可以正式投入使用

总结

  • Ioc的底层原理实现:Spring Ioc启动分为两步:
    • 1.创建BeanFactory
    • 2.实例化Bean
  • Spring的Bean在内存中的状态就是BeanDefination
  • 在Bean的创建和依赖注入的过程中,需要根据BeanDefination的信息来递归的完成依赖注入,从代码可以看到,这些递归都是以getBean()为入口的,一个递归是在上下文体系中查找需要的bean和bean的依赖关系;另一个递归是在依赖注入时,通过递归调用容器的getBean方法得到当前依赖的Bean,同时也触发对依赖bean的创建和注入。在对bean的属性进行依赖注入时,解析过程也是一个递归过程,这样根据依赖关系,一层一层的完成Bean的创建和注入,直到当前bean相关的整个依赖链的注入完成。由于整个IoC容器启动过程较为复杂,使用下面的一张图来描述让读者更清楚厘清IoC容器的启动过程。

Ioc容器启动过程

模板

  • 代码位置:org.springframework.context.support.AbstractApplicationContext.java

    1
    2
    3
    protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {

    }
  • 代码位置:org.springframework.context.support.AbstractApplicationContext.java

    1

  • 代码位置:.java

    1

  • 代码位置:.java

    1

参考资料

坚持原创技术分享,您的支持是我前进的动力!