您的位置:首页 > 房产 > 建筑 > 合肥做网站推广的公司_公诚管理咨询有限公司_百度电脑版网页_南昌seo技术外包

合肥做网站推广的公司_公诚管理咨询有限公司_百度电脑版网页_南昌seo技术外包

2025/1/6 16:43:06 来源:https://blog.csdn.net/2301_79308687/article/details/144656483  浏览:    关键词:合肥做网站推广的公司_公诚管理咨询有限公司_百度电脑版网页_南昌seo技术外包
合肥做网站推广的公司_公诚管理咨询有限公司_百度电脑版网页_南昌seo技术外包

配置IOC容器

public ConfigurableApplicationContext run(String... args) {// -- sniptry {// context的类型是AnnotationConfigServletWebServerApplicationContextcontext = createApplicationContext();context.setApplicationStartup(this.applicationStartup);// 1. 准备容器prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);// 2. 刷新容器refreshContext(context);afterRefresh(context, applicationArguments);startup.started();if (this.logStartupInfo) {new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), startup);}listeners.started(context, startup.timeTakenToStarted());callRunners(context, applicationArguments);}catch (Throwable ex) {throw handleRunFailure(context, ex, listeners);}try {if (context.isRunning()) {listeners.ready(context, startup.ready());}}catch (Throwable ex) {throw handleRunFailure(context, ex, null);}return context;}

1. 准备容器

private void prepareContext(DefaultBootstrapContext bootstrapContext, ConfigurableApplicationContext context,ConfigurableEnvironment environment, SpringApplicationRunListeners listeners,ApplicationArguments applicationArguments, Banner printedBanner) {context.setEnvironment(environment);// 配置容器的类加载器、资源加载器、类型转换器postProcessApplicationContext(context);// 如果JVM允许AOT,则配置AOT相关的ApplicationContextInitializer// AOT(ahead of time)是在程序运行前将字节码编译成机器码,JIT(just in time)是程序边运行边将字节码编译成机器码。普通SpringBoot用的是JITaddAotGeneratedInitializerIfNecessary(this.initializers);// 1. 执行初始化器applyInitializers(context);listeners.contextPrepared(context);// 关闭引导上下文bootstrapContext.close(context);if (this.logStartupInfo) {logStartupInfo(context.getParent() == null);logStartupProfileInfo(context);}// Add boot specific singleton beans// beanFactory的类型是DefaultListableBeanFactoryConfigurableListableBeanFactory beanFactory = context.getBeanFactory();// 向bean工厂注册单例applicationArgumentsbeanFactory.registerSingleton("springApplicationArguments", applicationArguments);if (printedBanner != null) {beanFactory.registerSingleton("springBootBanner", printedBanner);}if (beanFactory instanceof AbstractAutowireCapableBeanFactory autowireCapableBeanFactory) {// 配置是否允许循环依赖autowireCapableBeanFactory.setAllowCircularReferences(this.allowCircularReferences);if (beanFactory instanceof DefaultListableBeanFactory listableBeanFactory) {listableBeanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);}}if (this.lazyInitialization) {// 设置延迟加载context.addBeanFactoryPostProcessor(new LazyInitializationBeanFactoryPostProcessor());}if (this.keepAlive) {// KeepAlive()对象额外启动一个非守护线程,避免`SpringBoot`因为非守护线程结束而关闭JVMcontext.addApplicationListener(new KeepAlive());}// PropertySourceOrderingBeanFactoryPostProcessor是对@PropertySource注解修饰的类进行排序context.addBeanFactoryPostProcessor(new PropertySourceOrderingBeanFactoryPostProcessor(context));if (!AotDetector.useGeneratedArtifacts()) {// Load the sourcesSet<Object> sources = getAllSources();Assert.notEmpty(sources, "Sources must not be empty");load(context, sources.toArray(new Object[0]));}listeners.contextLoaded(context);
}

1. 执行初始化器

protected void applyInitializers(ConfigurableApplicationContext context) {for (ApplicationContextInitializer initializer : getInitializers()) {Class<?> requiredType = GenericTypeResolver.resolveTypeArgument(initializer.getClass(),ApplicationContextInitializer.class);Assert.isInstanceOf(requiredType, context, "Unable to call initializer.");initializer.initialize(context);}
}

SpringBoot默认的初始化器有7个。从上到下它们的功能分别是
0. 执行环境属性context.initializer.classes指定的初始化器。它的优先级最高。

  1. 向容器添加一个CachingMetadataReaderFactoryPostProcessor
  2. 初始化容器的ID。
  3. 向容器增加一个处理错误告警的BeanFactoryPostProcessor。
  4. RSocket是基于Reactive Streams的通信协议。
  5. 向容器配置server.port端口属性。
  6. 向容器中配置ConditionEvaluationReportListener。
    在这里插入图片描述

2.刷新容器


最终调用的是AbstractApplicationContext#refresh()方法。

private final Lock startupShutdownLock = new ReentrantLock();public void refresh() throws BeansException, IllegalStateException {// startupShutdownLock锁是防止当前线程刷新容器,别的线程关闭容器。this.startupShutdownLock.lock();try {this.startupShutdownThread = Thread.currentThread();StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");// Prepare this context for refreshing.// 1. 准备刷新prepareRefresh();// Tell the subclass to refresh the internal bean factory.// 2. 重获容器ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();// Prepare the bean factory for use in this context.// 3. 配置容器prepareBeanFactory(beanFactory);try {// Allows post-processing of the bean factory in context subclasses.// 4. 容器子类添加后处理器postProcessBeanFactory(beanFactory);// 标记阶段StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");// Invoke factory processors registered as beans in the context.// 5. 调用BeanFactory后处理器invokeBeanFactoryPostProcessors(beanFactory);// Register bean processors that intercept bean creation.// 6. 注册bean后处理器registerBeanPostProcessors(beanFactory);beanPostProcess.end();// Initialize message source for this context.// 向bean工厂注册一个名为`messageSource`的单例beaninitMessageSource();// Initialize event multicaster for this context.// 向bean工厂注册一个名为`applicationEventMulticaster`的SimpleApplicationEventMulticaster对象initApplicationEventMulticaster();// Initialize other special beans in specific context subclasses.// 7. tomcat初始化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 (RuntimeException | Error 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 {contextRefresh.end();}}finally {this.startupShutdownThread = null;this.startupShutdownLock.unlock();}
}

1. 准备刷新

protected void prepareRefresh() {// Switch to active.this.startupDate = System.currentTimeMillis(); // startupDate的类型是`long`,标记容器启动时刻this.closed.set(false); // close的类型是`AtomicBoolean`,标记当前容器是否已就绪this.active.set(true); // active的类型是`AtomicBoolean`,标记当前容器是否活跃// 源码此处有log// Initialize any placeholder property sources in the context environment.// 初始化名称为`servletContextInitParams`的ServletContextPropertySource`,即初始化Servlet相关属性initPropertySources();// Validate that all properties marked as required are resolvable:// see ConfigurablePropertyResolver#setRequiredPropertiesgetEnvironment().validateRequiredProperties();// Store pre-refresh ApplicationListeners...// earlyApplicationListeners 刷新容器之前已存在的监听器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<>();
}

2. 重获容器

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {refreshBeanFactory();// 当前applicationContext是容器对象,但是包含了环境配置,事件发布器等等。而`getBeanFactory`返回的容器仅仅处理对象return getBeanFactory();
}
// GenericApplicationContext#refreshBeanFactory
protected final void refreshBeanFactory() throws IllegalStateException {// refreshed的类型是`AtomicBoolean`,代表容器正在刷新,cas表示容器只能刷新一次if (!this.refreshed.compareAndSet(false, true)) {throw new IllegalStateException("GenericApplicationContext does not support multiple refresh attempts: just call 'refresh' once");}// 容器的id是`application`this.beanFactory.setSerializationId(getId());
}

3. 配置容器

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {// Tell the internal bean factory to use the context's class loader etc.// 设置bean的类加载器,是`AppClassLoader`beanFactory.setBeanClassLoader(getClassLoader());// 设置SPEL解析器beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));// 设置属性编辑器,将字符串属性转为java对象,比如将"false"字符串转为Boolean.False。beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));// Configure the bean factory with context callbacks.// 配置bean后处理器。`ignoreDependencyInterface`表示容器不解析这些接口,不将接口的实现放入容器。//源码里是将这些接口放入`Set<Class<?>> ignoredDependencyInterfaces`。// 这些接口统一由`ApplicationContextAwareProcessor`处理。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.ignoreDependencyInterface(ApplicationStartupAware.class);// BeanFactory interface not registered as resolvable type in a plain factory.// MessageSource registered (and found for autowiring) as a bean.// 指定BeanFactory.class接口的容器对象是beanfactory// 源码里就是将`BeanFactory.class`和`beanFactory`放入`Map<Class<?>, Object> resolvableDependencies`。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.// 添加bean后处理器,ApplicationListenerDetector监听实现ApplicationListener接口的beanbeanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));// Detect a LoadTimeWeaver and prepare for weaving, if found.// NativeDetector检测当前环境是否是GraalVM native镜像。if (!NativeDetector.inNativeImage() && 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.// 向容器注册名为"environment"的单例ApplicationServletEnvironment对象if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());}// 向容器注册名为"systemProperties"的单例Properties对象if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());}// 向容器注册名为"systemEnvironment"的`UnmodifiableMap`对象if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());}// 向容器注册名为"applicationStartup"的单例DefaultApplicationStartup对象if (!beanFactory.containsLocalBean(APPLICATION_STARTUP_BEAN_NAME)) {beanFactory.registerSingleton(APPLICATION_STARTUP_BEAN_NAME, getApplicationStartup());}
}

4. 容器子类添加后处理器

ServletWebServerApplicationContext是容器实现类,它添加bean后处理器。WebApplicationContextServletContextAwareProcessor是向容器添加servletContext

// org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {beanFactory.addBeanPostProcessor(new WebApplicationContextServletContextAwareProcessor(this));beanFactory.ignoreDependencyInterface(ServletContextAware.class);registerWebApplicationScopes();
}

5. 调用BeanFactory后处理器

最终调用的是PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors()方法。后处理器分2种,一种是BeanDefinitionRegistryPostProcessors,处理BeanDefinitionRegistry中登记的BeanDefinitionBeanDefinition是bean的定义类,是对不同来源(Annotation注解,xml文件)的容器定义(scope, beanName)的抽象。容器根据定义类创建容器。一种是BeanFactoryPostProcessors,处理容器。
在这里插入图片描述
先看BeanDefinitionRegistryPostProcessors。首先处理PriorityOrdered接口,之后处理Ordered接口,其余的最后处理。
在这里插入图片描述
invokeBeanDefinitionRegistryPostProcessors方法让每个后处理器postProcessor调用自己的postProcessBeanDefinitionRegistry方法。其中有个org.springframework.context.annotation.ConfigurationClassPostProcessor将所有@Confuguration注解类解析成BeanDefinitionHolder

private static void invokeBeanDefinitionRegistryPostProcessors(Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry, ApplicationStartup applicationStartup) {for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {StartupStep postProcessBeanDefRegistry = applicationStartup.start("spring.context.beandef-registry.post-process").tag("postProcessor", postProcessor::toString);postProcessor.postProcessBeanDefinitionRegistry(registry);postProcessBeanDefRegistry.end();}}

BeanFactoryPostProcessors也是按照优先级进行处理。
在这里插入图片描述
处理结束后,删除缓存。

@Override
public void clearMetadataCache() {super.clearMetadataCache();this.mergedBeanDefinitionHolders.clear();clearByTypeCache();
}

在这里插入图片描述

6. 注册bean后处理器

在这里插入图片描述
registerBeanPostProcessors方法也是按照优先级注册bean后处理方法。这里的注册指的是将BeanPostProcessors放入容器,即abstractBeanFactory.addBeanPostProcessors(postProcessors)。而不是执行BeanPostProcessors,因为此时还没有创建bean。
在这里插入图片描述
最后将后处理器重新注册一遍。并且添加ApplicationListenerDetector容器后处理器。
在这里插入图片描述

7. tomcat初始化

onfresh()是交给容器子类自定义初始化,web容器在此配置web环境并且启动tomcat。
在这里插入图片描述

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com