• spring ioc源码解读


    一、spring ioc源码解读

    1.加载静态资源

    ClassPathApplication,AnnotationConfigApplicationContext 等spring容器 通过加载spring配置信息,以下以ClassPathApplication为例

    public ClassPathXmlApplicationContext(String configLocation) throws BeansException {
    	this(new String[] {configLocation}, true, null);
    }
    
    public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)
    			throws BeansException {
    
    		super(parent);
    		setConfigLocations(configLocations);
    		if (refresh) {
    			refresh();
    		}
    	}
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    2.refresh()

    refresh() spring 容器最关键的方法,它表示整个factorybean,以及spring bean创建,执行他们父容器refresh()

    @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.
    			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();
    			}
    		}
    	}public void setConfigLocations(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;
    	}
    }
    
    • 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

    3.加载配置信息

    创建beanFactory容器,负责所有bean的加载与创建

    // 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);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    1.prepareRefresh() :首先spring 加载总容器状态信息

    	this.startupDate = System.currentTimeMillis();
    		this.closed.set(false);
    		this.active.set(true);
    	
    	if (logger.isInfoEnabled()) {
    		logger.info("Refreshing " + this);
    	}
    
    	// Initialize any placeholder property sources in the context environment
    	initPropertySources();
    
    	// Validate that all properties marked as required are resolvable
    	// see ConfigurablePropertyResolver#setRequiredProperties
    	getEnvironment().validateRequiredProperties();
    
    	// Allow for the collection of early ApplicationEvents,
    	// to be published once the multicaster is available...
    	this.earlyApplicationEvents = new LinkedHashSet<ApplicationEvent>();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    2.ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

    创建spring bean 容器,他主要负责存spring 的关键信息,负责加载springbean

    3.prepareBeanFactory(beanFactory);

    加载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());
    		}
    
    • 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

    4、spring创建 bean

    spring 创建factorybean 和 bean ,以及spring 事件注册与执行

    1.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();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    2.invokeBeanFactoryPostProcessors(beanFactory):

    spring用的模版设计模式,以下使用一个钩子方法,由它子类进行实现

    	protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    	}
    
    • 1
    • 2

    3.invokeBeanFactoryPostProcessors(beanFactory)

    执行beanFactory 的 后置处理器getBeanFactoryPostProcessors()

    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()));
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    4.registerBeanPostProcessors(beanFactory);

    registerBeanPostProcessors方法是用来注册spring 每一个bean 前置或者后置处理器,

    会通过一些登记对这些后置处理器的登记进行排序,然后判断是不是一个特殊的处理器

    ,然后注册BeanPostProcessors

    protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
    	PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
    }
    
    
    
    		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<BeanPostProcessor>();
    		List<BeanPostProcessor> internalPostProcessors = new ArrayList<BeanPostProcessor>();
    		List<String> orderedPostProcessorNames = new ArrayList<String>();
    		List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
    		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<BeanPostProcessor>();
    		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<BeanPostProcessor>();
    		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));
    
    • 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

    5.initMessageSource();

    注册spring 的国际化组件

    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.isDebugEnabled()) {
    			logger.debug("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.isDebugEnabled()) {
    			logger.debug("Unable to locate MessageSource with name '" + MESSAGE_SOURCE_BEAN_NAME +
    					"': using default [" + this.messageSource + "]");
    		}
    	}
    }
    
    • 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

    6.initApplicationEventMulticaster()

    初始化spring 监听器,执行我们对应 监听器方法

    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.isDebugEnabled()) {
    				logger.debug("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
    			}
    		}
    		else {
    			this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
    			beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
    			if (logger.isDebugEnabled()) {
    				logger.debug("Unable to locate ApplicationEventMulticaster with name '" +
    						APPLICATION_EVENT_MULTICASTER_BEAN_NAME +
    						"': using default [" + this.applicationEventMulticaster + "]");
    			}
    		}
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    7.onRefresh();

    子容器钩子方法

    protected void onRefresh() throws BeansException {
    	// For subclasses: do nothing by default.
    }
    
    • 1
    • 2
    • 3

    8.finishBeanFactoryInitialization(beanFactory);

    加载 weaverAwareName aop bean组件,通过beanFactory.preInstantiateSingletons();将所有bean注册执行

    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(new StringValueResolver() {
    			@Override
    			public String resolveStringValue(String strVal) {
    				return 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();
    }
    
    • 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

    加载spring 容器。。。。。。。。。。。。。。。

    @Override
    public void preInstantiateSingletons() throws BeansException {
    	if (this.logger.isDebugEnabled()) {
    		this.logger.debug("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<String>(this.beanDefinitionNames);
    
    	// Trigger initialization of all non-lazy singleton beans...
    	for (String beanName : beanNames) {
    		RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
    		if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
    			if (isFactoryBean(beanName)) {
    				final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);
    				boolean isEagerInit;
    				if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
    					isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
    						@Override
    						public Boolean run() {
    							return ((SmartFactoryBean<?>) factory).isEagerInit();
    						}
    					}, getAccessControlContext());
    				}
    				else {
    					isEagerInit = (factory instanceof SmartFactoryBean &&
    							((SmartFactoryBean<?>) factory).isEagerInit());
    				}
    				if (isEagerInit) {
    					getBean(beanName);
    				}
    			}
    			else {
    				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(new PrivilegedAction<Object>() {
    					@Override
    					public Object run() {
    						smartSingleton.afterSingletonsInstantiated();
    						return null;
    					}
    				}, getAccessControlContext());
    			}
    			else {
    				smartSingleton.afterSingletonsInstantiated();
    			}
    		}
    	}
    }
    
    • 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

    9.finishRefresh();

    检查创建所有监听器

    // 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);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
  • 相关阅读:
    卖家如何搭上独立站这趟快车
    springmvc http请求,支持get,post,附件传输和参数传输
    什么时候一个变量应该以state的形式出现?
    第十三届 Java B 组省赛 D 题—— 最少刷题数(AC)
    老卫带你学---leetcode刷题(32. 最长有效括号)
    gts分布式事务框架踩坑记录
    UDS(83服务-AccessTimingParameter)
    【Unity】导航 Navigation 设置:窄桥、隧道、斜坡、台阶、坠落、跳跃
    低代码平台在金融行业的OA解决方案
    分布式锁的实现方案
  • 原文地址:https://blog.csdn.net/Afu1021/article/details/133722742