面试必问-Spring常见问题及源码分析之持续更新

SteveCode. 2022-05-14 15:00:23 阅读数:597

面试spring问题常见问题常见

IOC bean的执行流程以及生命周期

先写一个dome

在这里插入图片描述
在这里插入图片描述
catBean对象

/** * 功能描述:bean 对象 * * @author Songxianyang * @date 2022-05-13 15:42 */
@Data
public class CatBean {

private String name;
}

spring-config.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="catBean" class="com.song.boot.springstudy.myspring.bean.CatBean">
<property name="name" value="洛洛"></property>
</bean>
</beans>

TestXmlSpring

/** * 功能描述:学习 Spring 源码 * * @author Songxianyang * @date 2022-05-13 15:35 */
public class TestXmlSpring {

public static void main(String[] args) {

ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
"spring-config.xml");
CatBean cat = (CatBean) context.getBean("catBean");
System.out.println(cat.getName());
}
}

org.springframework.context.support.AbstractApplicationContext#refresh()方法

setConfigLocations(configLocations); 显然装在我们的配置文件

在这里插入图片描述

public void refresh() throws BeansException, IllegalStateException {

synchronized (this.startupShutdownMonitor) {

StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
// 准备此上下文以进行刷新。
prepareRefresh();
// 告诉子类刷新内部 bean 工厂。去获取工程中自己配置的bean
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 准备 bean 工厂以在此上下文中使用。 准备好自己工厂里面的bean 
prepareBeanFactory(beanFactory);
try {

// 允许在上下文子类中对 bean 工厂进行后处理。
postProcessBeanFactory(beanFactory);
StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
// 调用在上下文中注册为 bean 的工厂处理器。
invokeBeanFactoryPostProcessors(beanFactory);
//注册拦截 bean 创建的 bean 处理器。
registerBeanPostProcessors(beanFactory);
beanPostProcess.end();
// 为此上下文初始化消息源。
initMessageSource();
// 为此上下文初始化事件多播器
initApplicationEventMulticaster();
// 初始化特定上下文子类中的其他特殊 bean。
onRefresh();
// 检查侦听器 bean 并注册它们。
registerListeners();
//实例化所有剩余的(非惰性初始化)单例。
finishBeanFactoryInitialization(beanFactory);
//最后一步:发布相应的事件。
finishRefresh();
}
catch (BeansException ex) {

if (logger.isWarnEnabled()) {

logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// 销毁已经创建的单例以避免悬空资源。
destroyBeans();
// 重置“活动”标志。
cancelRefresh(ex);
// 将异常传播给调用者。
throw ex;
}
finally {

// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
//重置 Spring 核心中的常见自省缓存,因为我们可能不再需要单例 bean 的元数据......
resetCommonCaches();
contextRefresh.end();
}
}
}

告诉子类刷新内部 bean 工厂。去获取工程中自己配置的bean

ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

在这里插入图片描述
后续我们在跟到里面…这里先放在这里 。先大概再到具体分析

准备 bean 工厂以在此上下文中使用。 准备好自己工厂里面的bean

 prepareBeanFactory(beanFactory);

大概意思就是:我们已经实例话一个bean工厂,但是这个beanFactory 并不是我们拿来就能用的。这个方法就是对这个beanFactory 上下问的初始化工作。有了这些初始化我们才能进行,系统环境才能使用这个beanFactory。

具体初始化了什么?

这个方法比较简单 我们就在这里说说:先看这段code
简明知意

/** * Configure the factory's standard context characteristics, * such as the context's ClassLoader and post-processors. * @param beanFactory the BeanFactory to configure * 配置工厂的标准上下文特征,例如上下文的 ClassLoader 和后处理器。 @param beanFactory 要配置的 BeanFactory */
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {

// Tell the internal bean factory to use the context's class loader etc.
// 告诉内部 bean 工厂使用上下文的类加载器等。
// 获取获取默认的类加载器 放进 bean工厂
beanFactory.setBeanClassLoader(getClassLoader());
if (!shouldIgnoreSpel) {

beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
}
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
// Configure the bean factory with context callbacks.
// 使用上下文回调配置 bean 工厂。 配置 环境、解析器、信息资源、上下文、类加载器 等等
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 接口未在普通工厂中注册为可解析类型。 MessageSource 作为 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.
// 将用于检测内部 bean 的早期后处理器注册为 ApplicationListener。
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
// Detect a LoadTimeWeaver and prepare for weaving, if found.
// 检测 LoadTimeWeaver 并准备编织(如果找到)。
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.
// 给 bean 赋值默认的环境配置
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());
}
if (!beanFactory.containsLocalBean(APPLICATION_STARTUP_BEAN_NAME)) {

beanFactory.registerSingleton(APPLICATION_STARTUP_BEAN_NAME, getApplicationStartup());
}
}
版权声明:本文为[SteveCode.]所创,转载请带上原文链接,感谢。 https://blog.csdn.net/weixin_48278764/article/details/124753031