[Java/Spring] 深入理解 : Spring ApplicationContext

news/2024/10/11 14:00:59

[Java/Spring] 深入理解 : Spring ApplicationContext

1 概述 : ApplicationContext

简介

2 源码分析

ApplicationContext

package org.springframework.context;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*/@NullableString 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*/@NullableApplicationContext 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;}

AbstractApplicationContext

属性

package org.springframework.context.support;public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory,MessageSource, ApplicationEventPublisher, ResourcePatternResolver {/*** 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";/*** 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*/public static final String LIFECYCLE_PROCESSOR_BEAN_NAME = "lifecycleProcessor";/*** 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*/public static final String APPLICATION_EVENT_MULTICASTER_BEAN_NAME = "applicationEventMulticaster";static {// Eagerly load the ContextClosedEvent class to avoid weird classloader issues// on application shutdown in WebLogic 8.1. (Reported by Dustin Woods.)ContextClosedEvent.class.getName();}/** Logger used by this class. Available to subclasses. */protected final Log logger = LogFactory.getLog(getClass());/** Unique id for this context, if any. */private String id = ObjectUtils.identityToString(this);/** Display name. */private String displayName = ObjectUtils.identityToString(this);/** Parent context. */@Nullableprivate ApplicationContext parent;/** Environment used by this context. */@Nullableprivate ConfigurableEnvironment environment;/** BeanFactoryPostProcessors to apply on refresh. */private final List<BeanFactoryPostProcessor> beanFactoryPostProcessors = new ArrayList<>();/** System time in milliseconds when this context started. */private long startupDate;/** 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. */private final AtomicBoolean closed = new AtomicBoolean();/** Synchronization monitor for the "refresh" and "destroy". */private final Object startupShutdownMonitor = new Object();/** Reference to the JVM shutdown hook, if registered. */@Nullableprivate Thread shutdownHook;/** ResourcePatternResolver used by this context. */private ResourcePatternResolver resourcePatternResolver;/** LifecycleProcessor for managing the lifecycle of beans within this context. */@Nullableprivate LifecycleProcessor lifecycleProcessor;/** MessageSource we delegate our implementation of this interface to. */@Nullableprivate MessageSource messageSource;/** Helper class used in event publishing. */@Nullableprivate ApplicationEventMulticaster applicationEventMulticaster;/** Statically specified listeners. */private final Set<ApplicationListener<?>> applicationListeners = new LinkedHashSet<>();/** Local listeners registered before refresh. */@Nullableprivate Set<ApplicationListener<?>> earlyApplicationListeners;/** ApplicationEvents published before the multicaster setup. */@Nullableprivate Set<ApplicationEvent> earlyApplicationEvents;// ...}

构造器

/*** Create a new AbstractApplicationContext with no parent.*/
public AbstractApplicationContext() {this.resourcePatternResolver = getResourcePatternResolver();
}/*** Create a new AbstractApplicationContext with the given parent context.* @param parent the parent context*/
public AbstractApplicationContext(@Nullable ApplicationContext parent) {this();setParent(parent);
}

setId/getId

	//---------------------------------------------------------------------// Implementation of ApplicationContext interface//---------------------------------------------------------------------/*** 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*/@Overridepublic void setId(String id) {this.id = id;}@Overridepublic String getId() {return this.id;}

getApplicationName/setDisplayName/getDisplayName

	@Overridepublic String getApplicationName() {return "";}/*** Set a friendly name for this context.* Typically done during initialization of concrete context implementations.* <p>Default is the object id of the context instance.*/public void setDisplayName(String displayName) {Assert.hasLength(displayName, "Display name must not be empty");this.displayName = displayName;}/*** Return a friendly name for this context.* @return a display name for this context (never {@code null})*/@Overridepublic String getDisplayName() {return this.displayName;}

getParent

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

setEnvironment/getEnvironment/createEnvironment

/*** Set the {@code Environment} for this application context.* <p>Default value is determined by {@link #createEnvironment()}. Replacing the* 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
public void setEnvironment(ConfigurableEnvironment environment) {this.environment = environment;
}/*** Return the {@code Environment} for this application context in configurable* form, allowing for further customization.* <p>If none specified, a default environment will be initialized via* {@link #createEnvironment()}.*/
@Override
public ConfigurableEnvironment getEnvironment() { // 实现 EnvironmentCapable 接口,并在此懒式创建 Environmentif (this.environment == null) {this.environment = createEnvironment();}return this.environment;
}/*** Create and return a new {@link StandardEnvironment}.* <p>Subclasses may override this method in order to supply* a custom {@link ConfigurableEnvironment} implementation.*/
protected ConfigurableEnvironment createEnvironment() {return new StandardEnvironment(); //默认创建 StandardEnvironment ,而非 Web应用的 StandardServletEnvironment
}

### getAutowireCapableBeanFactory
``` java/*** Return this context's internal bean factory as AutowireCapableBeanFactory,* if already available.* @see #getBeanFactory()*/@Overridepublic AutowireCapableBeanFactory getAutowireCapableBeanFactory() throws IllegalStateException {return getBeanFactory();}

getStartupDate

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

publishEvent(...)

	/*** Publish the given event to all listeners.* <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)*/@Overridepublic void publishEvent(ApplicationEvent event) {publishEvent(event, null);}/*** Publish the given event to all listeners.* <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})*/@Overridepublic void publishEvent(Object event) {publishEvent(event, null);}/*** 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* @since 4.2*/protected void publishEvent(Object event, @Nullable ResolvableType eventType) {Assert.notNull(event, "Event must not be null");// Decorate event as an ApplicationEvent if necessaryApplicationEvent applicationEvent;if (event instanceof ApplicationEvent) {applicationEvent = (ApplicationEvent) event;}else {applicationEvent = new PayloadApplicationEvent<>(this, event);if (eventType == null) {eventType = ((PayloadApplicationEvent<?>) applicationEvent).getResolvableType();}}// Multicast right now if possible - or lazily once the multicaster is initializedif (this.earlyApplicationEvents != null) {this.earlyApplicationEvents.add(applicationEvent);}else {getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);}// Publish event via parent context as well...if (this.parent != null) {if (this.parent instanceof AbstractApplicationContext) {((AbstractApplicationContext) this.parent).publishEvent(event, eventType);}else {this.parent.publishEvent(event);}}}

getApplicationEventMulticaster

	/*** 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*/ApplicationEventMulticaster getApplicationEventMulticaster() throws IllegalStateException {if (this.applicationEventMulticaster == null) {throw new IllegalStateException("ApplicationEventMulticaster not initialized - " +"call 'refresh' before multicasting events via the context: " + this);}return this.applicationEventMulticaster;}

getLifecycleProcessor

	/*** 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*/LifecycleProcessor getLifecycleProcessor() throws IllegalStateException {if (this.lifecycleProcessor == null) {throw new IllegalStateException("LifecycleProcessor not initialized - " +"call 'refresh' before invoking lifecycle methods via the context: " + this);}return this.lifecycleProcessor;}

getResourcePatternResolver

	/*** Return the ResourcePatternResolver to use for resolving location patterns* into Resource instances. Default is a* {@link org.springframework.core.io.support.PathMatchingResourcePatternResolver},* supporting Ant-style location patterns.* <p>Can be overridden in subclasses, for extended resolution strategies,* for example in a web environment.* <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*/protected ResourcePatternResolver getResourcePatternResolver() {return new PathMatchingResourcePatternResolver(this);}

setParent

	//---------------------------------------------------------------------// Implementation of ConfigurableApplicationContext interface//---------------------------------------------------------------------/*** Set the parent of this application context.* <p>The parent {@linkplain ApplicationContext#getEnvironment() environment} is* {@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)*/@Overridepublic void setParent(@Nullable ApplicationContext parent) {this.parent = parent;if (parent != null) {Environment parentEnvironment = parent.getEnvironment();if (parentEnvironment instanceof ConfigurableEnvironment) {getEnvironment().merge((ConfigurableEnvironment) parentEnvironment);}}}

addBeanFactoryPostProcessor/getBeanFactoryPostProcessors

	@Overridepublic void addBeanFactoryPostProcessor(BeanFactoryPostProcessor postProcessor) {Assert.notNull(postProcessor, "BeanFactoryPostProcessor must not be null");this.beanFactoryPostProcessors.add(postProcessor);}/*** Return the list of BeanFactoryPostProcessors that will get applied* to the internal BeanFactory.*/public List<BeanFactoryPostProcessor> getBeanFactoryPostProcessors() {return this.beanFactoryPostProcessors;}

addApplicationListener/getApplicationListeners

	@Overridepublic void addApplicationListener(ApplicationListener<?> listener) {Assert.notNull(listener, "ApplicationListener must not be null");if (this.applicationEventMulticaster != null) {this.applicationEventMulticaster.addApplicationListener(listener);}this.applicationListeners.add(listener);}/*** Return the list of statically specified ApplicationListeners.*/public Collection<ApplicationListener<?>> getApplicationListeners() {return this.applicationListeners;}

refresh/prepareRefresh

	@Overridepublic void refresh() throws BeansException, IllegalStateException {synchronized (this.startupShutdownMonitor) {// Prepare this context for refreshing.prepareRefresh();// Tell the subclass to refresh the internal bean factory.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.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();}}}/*** Prepare this context for refreshing, setting its startup date and* active flag as well as performing any initialization of property sources.*/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#setRequiredPropertiesgetEnvironment().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

	/*** <p>Replace any stub property sources with actual instances.* @see org.springframework.core.env.PropertySource.StubPropertySource* @see org.springframework.web.context.support.WebApplicationContextUtils#initServletPropertySources*/protected void initPropertySources() {// For subclasses: do nothing by default.}

obtainFreshBeanFactory/prepareBeanFactory/postProcessBeanFactory

	/*** Tell the subclass to refresh the internal bean factory.* @return the fresh BeanFactory instance* @see #refreshBeanFactory()* @see #getBeanFactory()*/protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {refreshBeanFactory();return getBeanFactory();}/*** 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) {// 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());}}/*** Modify the application context's internal bean factory after its standard* 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) {}

invokeBeanFactoryPostProcessors/registerBeanPostProcessors

	/*** Instantiate and invoke all registered BeanFactoryPostProcessor beans,* respecting explicit order if given.* <p>Must be called before singleton instantiation.*/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()));}}/*** Instantiate and register all BeanPostProcessor beans,* respecting explicit order if given.* <p>Must be called before any instantiation of application beans.*/protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);}

initMessageSource

	/*** Initialize the MessageSource.* Use parent's if none defined in this context.*/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 + "]");}}}

initApplicationEventMulticaster

	/*** Initialize the ApplicationEventMulticaster.* Uses SimpleApplicationEventMulticaster if none defined in the context.* @see org.springframework.context.event.SimpleApplicationEventMulticaster*/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() + "]");}}}

initLifecycleProcessor

	/*** Initialize the LifecycleProcessor.* Uses DefaultLifecycleProcessor if none defined in the context.* @see org.springframework.context.support.DefaultLifecycleProcessor*/protected void initLifecycleProcessor() {ConfigurableListableBeanFactory beanFactory = getBeanFactory();if (beanFactory.containsLocalBean(LIFECYCLE_PROCESSOR_BEAN_NAME)) {this.lifecycleProcessor =beanFactory.getBean(LIFECYCLE_PROCESSOR_BEAN_NAME, LifecycleProcessor.class);if (logger.isTraceEnabled()) {logger.trace("Using LifecycleProcessor [" + this.lifecycleProcessor + "]");}}else {DefaultLifecycleProcessor defaultProcessor = new DefaultLifecycleProcessor();defaultProcessor.setBeanFactory(beanFactory);this.lifecycleProcessor = defaultProcessor;beanFactory.registerSingleton(LIFECYCLE_PROCESSOR_BEAN_NAME, this.lifecycleProcessor);if (logger.isTraceEnabled()) {logger.trace("No '" + LIFECYCLE_PROCESSOR_BEAN_NAME + "' bean, using " +"[" + this.lifecycleProcessor.getClass().getSimpleName() + "]");}}}

onRefresh

	/*** 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()*/protected void onRefresh() throws BeansException {// For subclasses: do nothing by default.}

registerListeners

	/*** Add beans that implement ApplicationListener as listeners.* Doesn't affect other listeners, which can be added without being beans.*/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 (!CollectionUtils.isEmpty(earlyEventsToProcess)) {for (ApplicationEvent earlyEvent : earlyEventsToProcess) {getApplicationEventMulticaster().multicastEvent(earlyEvent);}}}

finishBeanFactoryInitialization

	/*** Finish the initialization of this context's bean factory,* initializing all remaining singleton beans.*/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 BeanFactoryPostProcessor// (such as a PropertySourcesPlaceholderConfigurer 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.beanFactory.preInstantiateSingletons();}

finishRefresh/cancelRefresh

	/*** Finish the refresh of this context, invoking the LifecycleProcessor's* onRefresh() method and publishing the* {@link org.springframework.context.event.ContextRefreshedEvent}.*/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);}/*** 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) {this.active.set(false);}

resetCommonCaches

	/*** 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)*/protected void resetCommonCaches() {ReflectionUtils.clearCache();AnnotationUtils.clearCache();ResolvableType.clearCache();CachedIntrospectionResults.clearClassLoader(getClassLoader());}

registerShutdownHook/destroy/close/doClose/destroyBeans/onClose

	/*** Register a shutdown hook {@linkplain Thread#getName() named}* {@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()* @see #doClose()*/@Overridepublic void registerShutdownHook() {if (this.shutdownHook == null) {// No shutdown hook registered yet.this.shutdownHook = new Thread(SHUTDOWN_HOOK_THREAD_NAME) {@Overridepublic void run() {synchronized (startupShutdownMonitor) {doClose();}}};Runtime.getRuntime().addShutdownHook(this.shutdownHook);}}/*** Callback for destruction of this instance, originally attached* to a {@code DisposableBean} implementation (not anymore in 5.0).* <p>The {@link #close()} method is the native way to shut down* an ApplicationContext, which this method simply delegates to.* @deprecated as of Spring Framework 5.0, in favor of {@link #close()}*/@Deprecatedpublic void destroy() {close();}/*** 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()*/@Overridepublic void close() {synchronized (this.startupShutdownMonitor) {doClose();// If we registered a JVM shutdown hook, we don't need it anymore now:// We've already explicitly closed the context.if (this.shutdownHook != null) {try {Runtime.getRuntime().removeShutdownHook(this.shutdownHook);}catch (IllegalStateException ex) {// ignore - VM is already shutting down}}}}/*** 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()* @see #registerShutdownHook()*/protected void doClose() {// Check whether an actual close attempt is necessary...if (this.active.get() && this.closed.compareAndSet(false, true)) {if (logger.isDebugEnabled()) {logger.debug("Closing " + this);}LiveBeansView.unregisterApplicationContext(this);try {// Publish shutdown event.publishEvent(new ContextClosedEvent(this));}catch (Throwable ex) {logger.warn("Exception thrown from ApplicationListener handling ContextClosedEvent", ex);}// Stop all Lifecycle beans, to avoid delays during individual destruction.if (this.lifecycleProcessor != null) {try {this.lifecycleProcessor.onClose();}catch (Throwable ex) {logger.warn("Exception thrown from LifecycleProcessor on context close", ex);}}// Destroy all cached singletons in the context's BeanFactory.destroyBeans();// Close the state of this context itself.closeBeanFactory();// Let subclasses do some final clean-up if they wish...onClose();// Reset local application listeners to pre-refresh state.if (this.earlyApplicationListeners != null) {this.applicationListeners.clear();this.applicationListeners.addAll(this.earlyApplicationListeners);}// Switch to inactive.this.active.set(false);}}/*** Template method for destroying all beans that this context manages.* The default implementation destroy all cached singletons in this context,* invoking {@code DisposableBean.destroy()} and/or the specified* "destroy-method".* <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()*/protected void destroyBeans() {getBeanFactory().destroySingletons();}/*** Template method which can be overridden to add context-specific shutdown work.* The default implementation is empty.* <p>Called at the end of {@link #doClose}'s shutdown procedure, after* this context's BeanFactory has been closed. If custom shutdown logic* needs to execute while the BeanFactory is still active, override* the {@link #destroyBeans()} method instead.*/protected void onClose() {// For subclasses: do nothing by default.}

isActive/assertBeanFactoryActive

	@Overridepublic boolean isActive() {return this.active.get();}/*** Assert that this context's BeanFactory is currently active,* throwing an {@link IllegalStateException} if it isn't.* <p>Invoked by all {@link BeanFactory} delegation methods that depend* on an active context, i.e. in particular all bean accessor methods.* <p>The default implementation checks the {@link #isActive() 'active'} status* of this context overall. May be overridden for more specific checks, or for a* no-op if {@link #getBeanFactory()} itself throws an exception in such a case.*/protected void assertBeanFactoryActive() {if (!this.active.get()) {if (this.closed.get()) {throw new IllegalStateException(getDisplayName() + " has been closed already");}else {throw new IllegalStateException(getDisplayName() + " has not been refreshed yet");}}}

getBean/getBeanProvider/containsBean/

	//---------------------------------------------------------------------// Implementation of BeanFactory interface//---------------------------------------------------------------------@Overridepublic Object getBean(String name) throws BeansException {assertBeanFactoryActive();return getBeanFactory().getBean(name);}@Overridepublic <T> T getBean(String name, Class<T> requiredType) throws BeansException {assertBeanFactoryActive();return getBeanFactory().getBean(name, requiredType);}@Overridepublic Object getBean(String name, Object... args) throws BeansException {assertBeanFactoryActive();return getBeanFactory().getBean(name, args);}@Overridepublic <T> T getBean(Class<T> requiredType) throws BeansException {assertBeanFactoryActive();return getBeanFactory().getBean(requiredType);}@Overridepublic <T> T getBean(Class<T> requiredType, Object... args) throws BeansException {assertBeanFactoryActive();return getBeanFactory().getBean(requiredType, args);}@Overridepublic <T> ObjectProvider<T> getBeanProvider(Class<T> requiredType) {assertBeanFactoryActive();return getBeanFactory().getBeanProvider(requiredType);}@Overridepublic <T> ObjectProvider<T> getBeanProvider(ResolvableType requiredType) {assertBeanFactoryActive();return getBeanFactory().getBeanProvider(requiredType);}@Overridepublic boolean containsBean(String name) {return getBeanFactory().containsBean(name);}

isSingleton/isPrototype/isTypeMatch/getType/getAliases

	@Overridepublic boolean isSingleton(String name) throws NoSuchBeanDefinitionException {assertBeanFactoryActive();return getBeanFactory().isSingleton(name);}@Overridepublic boolean isPrototype(String name) throws NoSuchBeanDefinitionException {assertBeanFactoryActive();return getBeanFactory().isPrototype(name);}@Overridepublic boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException {assertBeanFactoryActive();return getBeanFactory().isTypeMatch(name, typeToMatch);}@Overridepublic boolean isTypeMatch(String name, Class<?> typeToMatch) throws NoSuchBeanDefinitionException {assertBeanFactoryActive();return getBeanFactory().isTypeMatch(name, typeToMatch);}@Override@Nullablepublic Class<?> getType(String name) throws NoSuchBeanDefinitionException {assertBeanFactoryActive();return getBeanFactory().getType(name);}@Override@Nullablepublic Class<?> getType(String name, boolean allowFactoryBeanInit) throws NoSuchBeanDefinitionException {assertBeanFactoryActive();return getBeanFactory().getType(name, allowFactoryBeanInit);}@Overridepublic String[] getAliases(String name) {return getBeanFactory().getAliases(name);}

containsBeanDefinition/getBeanDefinitionCount/

	//---------------------------------------------------------------------// Implementation of ListableBeanFactory interface//---------------------------------------------------------------------@Overridepublic boolean containsBeanDefinition(String beanName) {return getBeanFactory().containsBeanDefinition(beanName);}@Overridepublic int getBeanDefinitionCount() {return getBeanFactory().getBeanDefinitionCount();}@Overridepublic String[] getBeanDefinitionNames() {return getBeanFactory().getBeanDefinitionNames();}

getBeanNamesForType

	@Overridepublic String[] getBeanNamesForType(ResolvableType type) {assertBeanFactoryActive();return getBeanFactory().getBeanNamesForType(type);}@Overridepublic String[] getBeanNamesForType(ResolvableType type, boolean includeNonSingletons, boolean allowEagerInit) {assertBeanFactoryActive();return getBeanFactory().getBeanNamesForType(type, includeNonSingletons, allowEagerInit);}@Overridepublic String[] getBeanNamesForType(@Nullable Class<?> type) {assertBeanFactoryActive();return getBeanFactory().getBeanNamesForType(type);}@Overridepublic String[] getBeanNamesForType(@Nullable Class<?> type, boolean includeNonSingletons, boolean allowEagerInit) {assertBeanFactoryActive();return getBeanFactory().getBeanNamesForType(type, includeNonSingletons, allowEagerInit);}

getBeansOfType/getBeanNamesForAnnotation/getBeansWithAnnotation/findAnnotationOnBean

	@Overridepublic <T> Map<String, T> getBeansOfType(@Nullable Class<T> type) throws BeansException {assertBeanFactoryActive();return getBeanFactory().getBeansOfType(type);}@Overridepublic <T> Map<String, T> getBeansOfType(@Nullable Class<T> type, boolean includeNonSingletons, boolean allowEagerInit)throws BeansException {assertBeanFactoryActive();return getBeanFactory().getBeansOfType(type, includeNonSingletons, allowEagerInit);}@Overridepublic String[] getBeanNamesForAnnotation(Class<? extends Annotation> annotationType) {assertBeanFactoryActive();return getBeanFactory().getBeanNamesForAnnotation(annotationType);}@Overridepublic Map<String, Object> getBeansWithAnnotation(Class<? extends Annotation> annotationType)throws BeansException {assertBeanFactoryActive();return getBeanFactory().getBeansWithAnnotation(annotationType);}@Override@Nullablepublic <A extends Annotation> A findAnnotationOnBean(String beanName, Class<A> annotationType)throws NoSuchBeanDefinitionException {assertBeanFactoryActive();return getBeanFactory().findAnnotationOnBean(beanName, annotationType);}

getParentBeanFactory/containsLocalBean/getInternalParentBeanFactory

	//---------------------------------------------------------------------// Implementation of HierarchicalBeanFactory interface//---------------------------------------------------------------------@Override@Nullablepublic BeanFactory getParentBeanFactory() {return getParent();}@Overridepublic boolean containsLocalBean(String name) {return getBeanFactory().containsLocalBean(name);}/*** 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*/@Nullableprotected BeanFactory getInternalParentBeanFactory() {return (getParent() instanceof ConfigurableApplicationContext ?((ConfigurableApplicationContext) getParent()).getBeanFactory() : getParent());}

getMessage/getMessageSource/getInternalParentMessageSource

	//---------------------------------------------------------------------// Implementation of MessageSource interface//---------------------------------------------------------------------@Overridepublic String getMessage(String code, @Nullable Object[] args, @Nullable String defaultMessage, Locale locale) {return getMessageSource().getMessage(code, args, defaultMessage, locale);}@Overridepublic String getMessage(String code, @Nullable Object[] args, Locale locale) throws NoSuchMessageException {return getMessageSource().getMessage(code, args, locale);}@Overridepublic String getMessage(MessageSourceResolvable resolvable, Locale locale) throws NoSuchMessageException {return getMessageSource().getMessage(resolvable, locale);}/*** 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*/private MessageSource getMessageSource() throws IllegalStateException {if (this.messageSource == null) {throw new IllegalStateException("MessageSource not initialized - " +"call 'refresh' before accessing messages via the context: " + this);}return this.messageSource;}/*** Return the internal message source of the parent context if it is an* AbstractApplicationContext too; else, return the parent context itself.*/@Nullableprotected MessageSource getInternalParentMessageSource() {return (getParent() instanceof AbstractApplicationContext ?((AbstractApplicationContext) getParent()).messageSource : getParent());}

getResources

	//---------------------------------------------------------------------// Implementation of ResourcePatternResolver interface//---------------------------------------------------------------------@Overridepublic Resource[] getResources(String locationPattern) throws IOException {return this.resourcePatternResolver.getResources(locationPattern);}

start/stop/isRunning

	//---------------------------------------------------------------------// Implementation of Lifecycle interface//---------------------------------------------------------------------@Overridepublic void start() {getLifecycleProcessor().start();publishEvent(new ContextStartedEvent(this));}@Overridepublic void stop() {getLifecycleProcessor().stop();publishEvent(new ContextStoppedEvent(this));}@Overridepublic boolean isRunning() {return (this.lifecycleProcessor != null && this.lifecycleProcessor.isRunning());}

refreshBeanFactory/closeBeanFactory/getBeanFactory (抽象方法)

//---------------------------------------------------------------------// Abstract methods that must be implemented by subclasses//---------------------------------------------------------------------/*** Subclasses must implement this method to perform the actual configuration load.* The method is invoked by {@link #refresh()} before any other initialization work.* <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*/protected abstract void refreshBeanFactory() throws BeansException, IllegalStateException;/*** Subclasses must implement this method to release their internal bean factory.* This method gets invoked by {@link #close()} after all other shutdown work.* <p>Should never throw an exception but rather log shutdown failures.*/protected abstract void closeBeanFactory();/*** Subclasses must return their internal bean factory here. They should implement the* lookup efficiently, so that it can be called repeatedly without a performance penalty.* <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* closed already* @see #refreshBeanFactory()* @see #closeBeanFactory()*/@Overridepublic abstract ConfigurableListableBeanFactory getBeanFactory() throws IllegalStateException;

toString

	/*** Return information about this context.*/@Overridepublic String toString() {StringBuilder sb = new StringBuilder(getDisplayName());sb.append(", started on ").append(new Date(getStartupDate()));ApplicationContext parent = getParent();if (parent != null) {sb.append(", parent: ").append(parent.getDisplayName());}return sb.toString();}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ryyt.cn/news/70213.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

聊天系统产品分析:技术视角的深度探索

随着互联网技术的飞速发展,聊天系统已经成为人们日常沟通不可或缺的一部分。无论是社交媒体、即时通讯软件,还是企业协作平台,聊天系统都扮演着重要的角色。本文将从技术视角出发,对聊天系统的架构、关键技术、安全性以及用户体验进行深入分析。一、聊天系统的架构设计 聊天…

外贸电商系统如何保障交易安全:技术视角的深度解析与效果评估

外贸电商系统是一个集成了多种先进技术和功能的综合性平台,旨在为国际间的商业交易提供便捷、高效的服务。该系统不仅支持多语言界面和多种货币结算,还涵盖了从产品展示、客户管理、订单处理到物流配送、支付结算等全流程的管理功能。通过优化供应链管理,提高交易效率,减少…

Android iOS 使用 ARMS 用户体验监控(RUM)的最佳实践

本文主要介绍了 ARMS 用户体验监控的基本功能特性,并介绍了在几种常见场景下的最佳实践。ARMS 用户体验监控作为一个面向终端的实时监控服务,不仅能够提供专业的、深层次的、精细化的数据采集和洞察能力,还能通过集成 ARMS 应用监控和可观测链路 OpenTelemetry 版本进行端到…

[自用] 虚拟机windows11-x64,安装MySQL 8.0.32,记录

前面忘截图了 提示要求电脑里安装VS2015/2017/2019,但虚拟机里只有VS2013。网上说可以一起装,但是我虚拟机配置不太行,再说吧,不行用我自己笔记本,虽然也有点菜,但比虚拟机强。虚拟机配置安装之后的配置密码三个旧的特殊符号这少一步,写的是点击execute来应用配置 apply…

20222319zzs 2024-2025-1 《网络与系统攻防技术》实验一实验报告

1.实验内容 1.1知识回顾 1.1.1什么是缓冲区溢出? 计算机中,如果程序试图向一个缓冲区填充超出它能够容纳的数据,溢出的数据可能会覆盖其他重要的内存区域,导致程序运行失败甚至崩溃,如果这些溢出数据是精心设计的.则攻击者就可以利用它们指向预先设计的攻击代码(shellcod…

MQTT

安装 服务端 EMQX 客户端 MQTTXJava集成SrpingBoot pom.xml <dependency><groupId>org.springframework.integration</groupId><artifactId>spring-integration-mqtt</artifactId> </dependency> <dependency><groupId>org.ec…

AI云平台怎么构建

构建AI云平台是一个复杂而系统的过程,涉及多个环节和技术栈。从准备工作到最终的部署运行,每一步都需要精心设计和实现。构建AI云平台是一个复杂而系统的过程,涉及多个环节和技术栈。从准备工作到最终的部署运行,每一步都需要精心设计和实现。下面,petacloud.ai小编将详细…

AI云平台建设意义

AI云平台,作为AI技术与云计算深度融合的产物,其建设不仅标志着技术创新的又一高峰,更蕴含着对社会经济发展、产业升级、创新生态构建等多方面的深远意义。AI云平台,作为AI技术与云计算深度融合的产物,其建设不仅标志着技术创新的又一高峰,更蕴含着对社会经济发展、产业升…