Commit 04177ba3 by SunWei峰

Spring上下文

parent 307c9ae2
......@@ -124,7 +124,6 @@ import org.springframework.util.ReflectionUtils;
* @author Sam Brannen
* @author Sebastien Deleuze
* @author Brian Clozel
* @since January 21, 2001
* @see #refreshBeanFactory
* @see #getBeanFactory
* @see org.springframework.beans.factory.config.BeanFactoryPostProcessor
......@@ -132,6 +131,7 @@ import org.springframework.util.ReflectionUtils;
* @see org.springframework.context.event.ApplicationEventMulticaster
* @see org.springframework.context.ApplicationListener
* @see org.springframework.context.MessageSource
* @since January 21, 2001
*/
public abstract class AbstractApplicationContext extends DefaultResourceLoader
implements ConfigurableApplicationContext {
......@@ -139,6 +139,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
/**
* Name of the MessageSource bean in the factory.
* If none is supplied, message resolution is delegated to the parent.
*
* @see MessageSource
*/
public static final String MESSAGE_SOURCE_BEAN_NAME = "messageSource";
......@@ -146,6 +147,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
/**
* Name of the LifecycleProcessor bean in the factory.
* If none is supplied, a DefaultLifecycleProcessor is used.
*
* @see org.springframework.context.LifecycleProcessor
* @see org.springframework.context.support.DefaultLifecycleProcessor
*/
......@@ -154,6 +156,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
/**
* Name of the ApplicationEventMulticaster bean in the factory.
* If none is supplied, a default SimpleApplicationEventMulticaster is used.
*
* @see org.springframework.context.event.ApplicationEventMulticaster
* @see org.springframework.context.event.SimpleApplicationEventMulticaster
*/
......@@ -174,68 +177,106 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
}
/** Logger used by this class. Available to subclasses. */
/**
* Logger used by this class. Available to subclasses.
*/
protected final Log logger = LogFactory.getLog(getClass());
/** Unique id for this context, if any. */
/**
* Unique id for this context, if any.
*/
private String id = ObjectUtils.identityToString(this);
/** Display name. */
/**
* Display name.
*/
private String displayName = ObjectUtils.identityToString(this);
/** Parent context. */
/**
* Parent context.
*/
@Nullable
private ApplicationContext parent;
/** Environment used by this context. */
/**
* Environment used by this context.
*/
@Nullable
private ConfigurableEnvironment environment;
/** BeanFactoryPostProcessors to apply on refresh. */
/**
* BeanFactoryPostProcessors to apply on refresh.
*/
private final List<BeanFactoryPostProcessor> beanFactoryPostProcessors = new ArrayList<>();
/** System time in milliseconds when this context started. */
/**
* System time in milliseconds when this context started.
*/
private long startupDate;
/** Flag that indicates whether this context is currently active. */
/**
* Flag that indicates whether this context is currently active.
*/
private final AtomicBoolean active = new AtomicBoolean();
/** Flag that indicates whether this context has been closed already. */
/**
* Flag that indicates whether this context has been closed already.
*/
private final AtomicBoolean closed = new AtomicBoolean();
/** Synchronization monitor for the "refresh" and "destroy". */
/**
* Synchronization monitor for the "refresh" and "destroy".
*/
private final Object startupShutdownMonitor = new Object();
/** Reference to the JVM shutdown hook, if registered. */
/**
* Reference to the JVM shutdown hook, if registered.
*/
@Nullable
private Thread shutdownHook;
/** ResourcePatternResolver used by this context. */
/**
* ResourcePatternResolver used by this context.
*/
private final ResourcePatternResolver resourcePatternResolver;
/** LifecycleProcessor for managing the lifecycle of beans within this context. */
/**
* LifecycleProcessor for managing the lifecycle of beans within this context.
*/
@Nullable
private LifecycleProcessor lifecycleProcessor;
/** MessageSource we delegate our implementation of this interface to. */
/**
* MessageSource we delegate our implementation of this interface to.
*/
@Nullable
private MessageSource messageSource;
/** Helper class used in event publishing. */
/**
* Helper class used in event publishing.
*/
@Nullable
private ApplicationEventMulticaster applicationEventMulticaster;
/** Application startup metrics. **/
/**
* Application startup metrics.
**/
private ApplicationStartup applicationStartup = ApplicationStartup.DEFAULT;
/** Statically specified listeners. */
/**
* Statically specified listeners.
*/
private final Set<ApplicationListener<?>> applicationListeners = new LinkedHashSet<>();
/** Local listeners registered before refresh. */
/**
* Local listeners registered before refresh.
*/
@Nullable
private Set<ApplicationListener<?>> earlyApplicationListeners;
/** ApplicationEvents published before the multicaster setup. */
/**
* ApplicationEvents published before the multicaster setup.
*/
@Nullable
private Set<ApplicationEvent> earlyApplicationEvents;
......@@ -249,6 +290,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
/**
* Create a new AbstractApplicationContext with the given parent context.
*
* @param parent the parent context
*/
public AbstractApplicationContext(@Nullable ApplicationContext parent) {
......@@ -265,6 +307,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
* Set the unique id of this application context.
* <p>Default is the object id of the context instance, or the name
* of the context bean if the context is itself defined as a bean.
*
* @param id the unique id of the context
*/
@Override
......@@ -294,6 +337,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
/**
* Return a friendly name for this context.
*
* @return a display name for this context (never {@code null})
*/
@Override
......@@ -317,6 +361,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
* default with this method is one option but configuration through {@link
* #getEnvironment()} should also be considered. In either case, such modifications
* should be performed <em>before</em> {@link #refresh()}.
*
* @see org.springframework.context.support.AbstractApplicationContext#createEnvironment
*/
@Override
......@@ -350,6 +395,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
/**
* Return this context's internal bean factory as AutowireCapableBeanFactory,
* if already available.
*
* @see #getBeanFactory()
*/
@Override
......@@ -370,6 +416,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
* <p>Note: Listeners get initialized after the MessageSource, to be able
* to access it within listener implementations. Thus, MessageSource
* implementations cannot publish events.
*
* @param event the event to publish (may be application-specific or a
* standard framework event)
*/
......@@ -383,6 +430,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
* <p>Note: Listeners get initialized after the MessageSource, to be able
* to access it within listener implementations. Thus, MessageSource
* implementations cannot publish events.
*
* @param event the event to publish (may be an {@link ApplicationEvent}
* or a payload object to be turned into a {@link PayloadApplicationEvent})
*/
......@@ -393,6 +441,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
/**
* Publish the given event to all listeners.
*
* @param event the event to publish (may be an {@link ApplicationEvent}
* or a payload object to be turned into a {@link PayloadApplicationEvent})
* @param eventType the resolved event type, if known
......@@ -405,8 +454,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
ApplicationEvent applicationEvent;
if (event instanceof ApplicationEvent) {
applicationEvent = (ApplicationEvent) event;
}
else {
} else {
applicationEvent = new PayloadApplicationEvent<>(this, event, eventType);
if (eventType == null) {
eventType = ((PayloadApplicationEvent<?>) applicationEvent).getResolvableType();
......@@ -416,8 +464,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
// Multicast right now if possible - or lazily once the multicaster is initialized
if (this.earlyApplicationEvents != null) {
this.earlyApplicationEvents.add(applicationEvent);
}
else {
} else {
getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);
}
......@@ -425,8 +472,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
if (this.parent != null) {
if (this.parent instanceof AbstractApplicationContext) {
((AbstractApplicationContext) this.parent).publishEvent(event, eventType);
}
else {
} else {
this.parent.publishEvent(event);
}
}
......@@ -434,6 +480,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
/**
* Return the internal ApplicationEventMulticaster used by the context.
*
* @return the internal ApplicationEventMulticaster (never {@code null})
* @throws IllegalStateException if the context has not been initialized yet
*/
......@@ -458,6 +505,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
/**
* Return the internal LifecycleProcessor used by the context.
*
* @return the internal LifecycleProcessor (never {@code null})
* @throws IllegalStateException if the context has not been initialized yet
*/
......@@ -479,6 +527,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
* <p><b>Do not call this when needing to resolve a location pattern.</b>
* Call the context's {@code getResources} method instead, which
* will delegate to the ResourcePatternResolver.
*
* @return the ResourcePatternResolver for this context
* @see #getResources
* @see org.springframework.core.io.support.PathMatchingResourcePatternResolver
......@@ -498,6 +547,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
* {@linkplain ConfigurableEnvironment#merge(ConfigurableEnvironment) merged} with
* this (child) application context environment if the parent is non-{@code null} and
* its environment is an instance of {@link ConfigurableEnvironment}.
*
* @see ConfigurableEnvironment#merge(ConfigurableEnvironment)
*/
@Override
......@@ -594,9 +644,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
// 12,完成刷新过程, 通知生命周期处理器 LifecycleProcessor 刷新过程同时发出 ContextRefreshEvent通知别人
finishRefresh();
}
catch (BeansException ex) {
} catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
......@@ -610,9 +658,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
// Propagate exception to caller.
throw ex;
}
finally {
} finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
resetCommonCaches();
......@@ -634,8 +680,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
if (logger.isDebugEnabled()) {
if (logger.isTraceEnabled()) {
logger.trace("Refreshing " + this);
}
else {
} else {
logger.debug("Refreshing " + getDisplayName());
}
}
......@@ -651,8 +696,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
// Store pre-refresh ApplicationListeners...
if (this.earlyApplicationListeners == null) {
this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
}
else {
} else {
// Reset local application listeners to pre-refresh state.
this.applicationListeners.clear();
this.applicationListeners.addAll(this.earlyApplicationListeners);
......@@ -665,6 +709,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
/**
* <p>Replace any stub property sources with actual instances.
*
* @see org.springframework.core.env.PropertySource.StubPropertySource
* @see org.springframework.web.context.support.WebApplicationContextUtils#initServletPropertySources
*/
......@@ -674,6 +719,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
/**
* Tell the subclass to refresh the internal bean factory.
*
* @return the fresh BeanFactory instance
* @see #refreshBeanFactory()
* @see #getBeanFactory()
......@@ -688,6 +734,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
/**
* Configure the factory's standard context characteristics,
* such as the context's ClassLoader and post-processors.
*
* @param beanFactory the BeanFactory to configure
*/
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
......@@ -757,6 +804,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
* initialization. All bean definitions will have been loaded, but no beans
* will have been instantiated yet. This allows for registering special
* BeanPostProcessors etc in certain ApplicationContext implementations.
*
* @param beanFactory the bean factory used by the application context
*/
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
......@@ -785,6 +833,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
* <p>Must be called before any instantiation of application beans.
*/
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
// 开始注册 BeanPostProcessor
PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}
......@@ -807,8 +856,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
if (logger.isTraceEnabled()) {
logger.trace("Using MessageSource [" + this.messageSource + "]");
}
}
else {
} else {
// Use empty MessageSource to be able to accept getMessage calls.
DelegatingMessageSource dms = new DelegatingMessageSource();
dms.setParentMessageSource(getInternalParentMessageSource());
......@@ -823,19 +871,25 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
/**
* Initialize the ApplicationEventMulticaster.
* Uses SimpleApplicationEventMulticaster if none defined in the context.
*
* @see org.springframework.context.event.SimpleApplicationEventMulticaster
*/
protected void initApplicationEventMulticaster() {
// 作用就是就是将事件通知给监听者
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
// 当前是否包含了名为 applicationEventMulticaster 的事件多播器bean注入
if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
// 若存在,则实例化该多播器,并赋值给 applicationEventMulticaster 变量
this.applicationEventMulticaster =
beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
if (logger.isTraceEnabled()) {
logger.trace("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
}
}
// 若不存在,构造一个 SimpleApplicationEventMulticaster 多播器对象,并赋值给applicationEventMulticaster 变量
else {
this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
// 将该对象注入bean工厂
beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
if (logger.isTraceEnabled()) {
logger.trace("No '" + APPLICATION_EVENT_MULTICASTER_BEAN_NAME + "' bean, using " +
......@@ -847,6 +901,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
/**
* Initialize the LifecycleProcessor.
* Uses DefaultLifecycleProcessor if none defined in the context.
*
* @see org.springframework.context.support.DefaultLifecycleProcessor
*/
protected void initLifecycleProcessor() {
......@@ -857,8 +912,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
if (logger.isTraceEnabled()) {
logger.trace("Using LifecycleProcessor [" + this.lifecycleProcessor + "]");
}
}
else {
} else {
DefaultLifecycleProcessor defaultProcessor = new DefaultLifecycleProcessor();
defaultProcessor.setBeanFactory(beanFactory);
this.lifecycleProcessor = defaultProcessor;
......@@ -874,6 +928,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
* Template method which can be overridden to add context-specific refresh work.
* Called on initialization of special beans, before instantiation of singletons.
* <p>This implementation is empty.
*
* @throws BeansException in case of errors
* @see #refresh()
*/
......@@ -887,12 +942,14 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
*/
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);
......@@ -914,6 +971,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
*/
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// Initialize conversion service for this context.
// 1.初始化此上下文的转换服务
if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
beanFactory.setConversionService(
......@@ -923,6 +981,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
// Register a default embedded value resolver if no BeanFactoryPostProcessor
// (such as a PropertySourcesPlaceholderConfigurer bean) registered any before:
// at this point, primarily for resolution in annotation attribute values.
// 2.如果beanFactory之前没有注册嵌入值解析器,则注册默认的嵌入值解析器:主要用于注解属性值的解析。
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
}
......@@ -966,6 +1025,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
/**
* Cancel this context's refresh attempt, resetting the {@code active} flag
* after an exception got thrown.
*
* @param ex the exception that led to the cancellation
*/
protected void cancelRefresh(BeansException ex) {
......@@ -976,11 +1036,12 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
* Reset Spring's common reflection metadata caches, in particular the
* {@link ReflectionUtils}, {@link AnnotationUtils}, {@link ResolvableType}
* and {@link CachedIntrospectionResults} caches.
* @since 4.2
*
* @see ReflectionUtils#clearCache()
* @see AnnotationUtils#clearCache()
* @see ResolvableType#clearCache()
* @see CachedIntrospectionResults#clearClassLoader(ClassLoader)
* @since 4.2
*/
protected void resetCommonCaches() {
ReflectionUtils.clearCache();
......@@ -995,6 +1056,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
* {@code SpringContextShutdownHook} with the JVM runtime, closing this
* context on JVM shutdown unless it has already been closed at that time.
* <p>Delegates to {@code doClose()} for the actual closing procedure.
*
* @see Runtime#addShutdownHook
* @see ConfigurableApplicationContext#SHUTDOWN_HOOK_THREAD_NAME
* @see #close()
......@@ -1020,6 +1082,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
* Close this application context, destroying all beans in its bean factory.
* <p>Delegates to {@code doClose()} for the actual closing procedure.
* Also removes a JVM shutdown hook, if registered, as it's not needed anymore.
*
* @see #doClose()
* @see #registerShutdownHook()
*/
......@@ -1032,8 +1095,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
if (this.shutdownHook != null) {
try {
Runtime.getRuntime().removeShutdownHook(this.shutdownHook);
}
catch (IllegalStateException ex) {
} catch (IllegalStateException ex) {
// ignore - VM is already shutting down
}
}
......@@ -1044,6 +1106,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
* Actually performs context closing: publishes a ContextClosedEvent and
* destroys the singletons in the bean factory of this application context.
* <p>Called by both {@code close()} and a JVM shutdown hook, if any.
*
* @see org.springframework.context.event.ContextClosedEvent
* @see #destroyBeans()
* @see #close()
......@@ -1060,8 +1123,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
try {
// Publish shutdown event.
publishEvent(new ContextClosedEvent(this));
}
catch (Throwable ex) {
} catch (Throwable ex) {
logger.warn("Exception thrown from ApplicationListener handling ContextClosedEvent", ex);
}
......@@ -1069,8 +1131,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
if (this.lifecycleProcessor != null) {
try {
this.lifecycleProcessor.onClose();
}
catch (Throwable ex) {
} catch (Throwable ex) {
logger.warn("Exception thrown from LifecycleProcessor on context close", ex);
}
}
......@@ -1103,6 +1164,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
* <p>Can be overridden to add context-specific bean destruction steps
* right before or right after standard singleton destruction,
* while the context's BeanFactory is still active.
*
* @see #getBeanFactory()
* @see org.springframework.beans.factory.config.ConfigurableBeanFactory#destroySingletons()
*/
......@@ -1140,8 +1202,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
if (!this.active.get()) {
if (this.closed.get()) {
throw new IllegalStateException(getDisplayName() + " has been closed already");
}
else {
} else {
throw new IllegalStateException(getDisplayName() + " has not been refreshed yet");
}
}
......@@ -1364,6 +1425,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
/**
* Return the internal bean factory of the parent context if it implements
* ConfigurableApplicationContext; else, return the parent context itself.
*
* @see org.springframework.context.ConfigurableApplicationContext#getBeanFactory
*/
@Nullable
......@@ -1394,6 +1456,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
/**
* Return the internal MessageSource used by the context.
*
* @return the internal MessageSource (never {@code null})
* @throws IllegalStateException if the context has not been initialized yet
*/
......@@ -1458,6 +1521,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
* <p>A subclass will either create a new bean factory and hold a reference to it,
* or return a single BeanFactory instance that it holds. In the latter case, it will
* usually throw an IllegalStateException if refreshing the context more than once.
*
* @throws BeansException if initialization of the bean factory failed
* @throws IllegalStateException if already initialized and multiple refresh
* attempts are not supported
......@@ -1477,6 +1541,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
* <p>Note: Subclasses should check whether the context is still active before
* returning the internal bean factory. The internal factory should generally be
* considered unavailable once the context has been closed.
*
* @return this application context's internal bean factory (never {@code null})
* @throws IllegalStateException if the context does not hold an internal bean factory yet
* (usually if {@link #refresh()} has never been called) or if the context has been
......
......@@ -175,7 +175,7 @@ final class PostProcessorRegistrationDelegate {
// Now, invoke the postProcessBeanFactory callback of all processors handled so far.
// 6.调用所有 BeanDefinitionRegistryPostProcessor 的 postProcessBeanFactory 方法
// (BeanDefinitionRegistryPostProcessor继承自BeanFactoryPostProcessor)
// (BeanDefinitionRegistryPostProcessor 继承自 BeanFactoryPostProcessor)
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
// 7.最后, 调用入参 beanFactoryPostProcessors 中的普通 BeanFactoryPostProcessor 的 postProcessBeanFactory 方法
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
......@@ -263,20 +263,27 @@ final class PostProcessorRegistrationDelegate {
// to ensure that your proposal does not result in a breaking change:
// https://github.com/spring-projects/spring-framework/issues?q=PostProcessorRegistrationDelegate+is%3Aclosed+label%3A%22status%3A+declined%22
// 1.找出所有实现BeanPostProcessor接口的类
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.
// BeanPostProcessorChecker 是一个普通的信息打印,可能会有些情况,
// 当Spring中的后置处理器还没有被注册就已经开始了bean的初始化时,
// 便会打印 BeanPostProcessorChecker 中的信息
// BeanPostProcessor的目标计数
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
// 2.添加BeanPostProcessorChecker(主要用于记录信息)到beanFactory中
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
// Separate between BeanPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
// 3.定义不同的变量用于区分:
// 实现PriorityOrdered接口的BeanPostProcessor、实现Ordered接口的BeanPostProcessor、普通BeanPostProcessor
// 第一个是对象链表,第二三个是 beanName链表
// 用于存放实现PriorityOrdered接口的BeanPostProcessor
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
// 用于存放Spring内部的BeanPostProcessor
List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
// 4.遍历 postProcessorNames, 将 BeanPostProcessors分开
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
......@@ -321,11 +328,13 @@ final class PostProcessorRegistrationDelegate {
registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
// Finally, re-register all internal BeanPostProcessors.
// 重新注册内部PostProcessors,(相当于内部的BeanPostProcessor会被移到处理器链的末尾)
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).
// 重新注册 ApplicationListenerDetector(跟上面类似,主要是为了移动到处理器链的末尾)
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment