我们先分析一下 AbstractXmlApplicationContext
这个容器的加载过程。
AbstractXmlApplicationContext
的老爸是 AbstractRefreshableApplicationContext
。
它老爸是 AbstractApplicationContext
的两个儿子之一。
从一张关系图开始:
demo中使用了 ClassPathXmlApplicationContext
,然后还有它旁边的兄弟 FileSystemXmlApplicationContext
,它们俩都是从xml配置文件加载配置的
除了这两个之外还有一个 AnnotationConfigApplicationContext
public class ClassPathXmlApplicationContext extends AbstractXmlApplicationContext { //配置文件数组 private Resource[] configResources; // 指定ApplicationContext的父容器 public ClassPathXmlApplicationContext(ApplicationContext parent) { super(parent); } public ClassPathXmlApplicationContext(String configLocation) throws BeansException { this(new String[] {configLocation}, true, null); } public ClassPathXmlApplicationContext(String... configLocations) throws BeansException { this(configLocations, true, null); } public ClassPathXmlApplicationContext(String[] configLocations, @Nullable ApplicationContext parent) throws BeansException { this(configLocations, true, parent); } public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent) throws BeansException { super(parent); // 根据提供的路径,处理成配置文件数组(以分号、逗号、空格、tab、换行符分割) setConfigLocations(configLocations); if (refresh) { refresh(); } } } 复制代码
可以看到, ClassPathXmlApplicationContext
提供了一系列的构造方法,主要是为了指定配置文件的位置,以及设置一个父容器,还有就是调用了 refresh()
方法, setConfigLocations()
这个很简单,看来主要的就是在 refresh
方法中了
先看看setConfigLocations()方法中做了什么
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; } } protected String resolvePath(String path) { return getEnironment().resolveRequiredPlaceholders(path); } 复制代码
setConfigLocations()
方法的主要工作有两个:创建环境对象 ConfigurableEnvironment
和处理构造 ClassPathXmlApplicationContext
时传入的字符串中的占位符, 这里 getEnvironment()
就涉及到了创建环境变量相关的操作了
getEnvironment()获取环境变量
public ConfigurableEnvironment getEnvironment() { if (this.environment == null) { this.environment = createEnvironment(); } return this.environment; } 复制代码
在上面的 getEnvironment()
方法的返回值中,我们看到一个 ConfigurableEnvironment
的类 先看看这个类的结构:
这个接口比较重要的就是两部分内容了,一个是设置Spring的环境就是我们经常用的spring.profile配置。另外就是系统资源Property
接着看看getEnvironment()中的createEnvironment()方法, 这个类创建了一个StandardEnvironment:
public class StandardEnvironment extends AbstractEnvironment { /** System environment property source name: {@value} 系统属性 eg:System.getProperty("java.home"); */ public static final String SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME = "systemEnvironment"; /** JVM system properties property source name: {@value} JVM 属性 --name=ranger OR -Dname=ranger */ public static final String SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME = "systemProperties"; /** * Customize the set of property sources with those appropriate for any standard * Java environment: * 使用任何适合标准Java环境来定义资源集 * <ul> * <li>{@value #SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME} * <li>{@value #SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME} * </ul> * JVM属性的优先级比系统属性高 * <p>Properties present in {@value #SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME} will * take precedence over those in {@value #SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME}. * @see AbstractEnvironment#customizePropertySources(MutablePropertySources) * 根据父类中对于这个方法的解释: 子类可以重写这个方法来添加自定义的PropertySource, 添加方式如下: public class Level1Environment extends AbstractEnvironment { Override protected void customizePropertySources(MutablePropertySources propertySources) { super.customizePropertySources(propertySources); // no-op from base class propertySources.addLast(new PropertySourceA(...)); propertySources.addLast(new PropertySourceB(...)); } } 在Level1Environment的子类中,还可以这样添加自定义的PropertySource,而且加入的这个是有优先级的, 比如上面的示例中, 子类添加的 > A > B * @see #getSystemProperties() * @see #getSystemEnvironment() */ @Override protected void customizePropertySources(MutablePropertySources propertySources) { propertySources.addLast(new MapPropertySource(SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME, getSystemProperties())); propertySources.addLast(new SystemEnvironmentPropertySource(SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME, getSystemEnvironment())); } } 复制代码
而这个类中的 customizePropertySources
方法就会往资源列表中添加Java进程中的变量和系统的环境变量。 可以看出一个 Environment
即是包含了一系列 PropertySource
的资源集合, 而 PropertySource
就是资源属性
再次回到 resolvePath()
方法,一直跟踪这个方法,最后到了 org.springframework.util.PropertyPlaceholderHelper.parseStringValue()
方法,这个方法主要就是处理所有使用${}方式的占位符
protected String parseStringValue( String value, PlaceholderResolver placeholderResolver, Set<String> visitedPlaceholders) { StringBuilder result = new StringBuilder(value); int startIndex = value.indexOf(this.placeholderPrefix); while (startIndex != -1) { int endIndex = findPlaceholderEndIndex(result, startIndex); if (endIndex != -1) { String placeholder = result.substring(startIndex + this.placeholderPrefix.length(), endIndex); String originalPlaceholder = placeholder; if (!visitedPlaceholders.add(originalPlaceholder)) { throw new IllegalArgumentException( "Circular placeholder reference '" + originalPlaceholder + "' in property definitions"); } placeholder = parseStringValue(placeholder, placeholderResolver, visitedPlaceholders); // Now obtain the value for the fully resolved key... String propVal = placeholderResolver.resolvePlaceholder(placeholder); if (propVal == null && this.valueSeparator != null) { int separatorIndex = placeholder.indexOf(this.valueSeparator); if (separatorIndex != -1) { String actualPlaceholder = placeholder.substring(0, separatorIndex); String defaultValue = placeholder.substring(separatorIndex + this.valueSeparator.length()); propVal = placeholderResolver.resolvePlaceholder(actualPlaceholder); if (propVal == null) { propVal = defaultValue; } } } if (propVal != null) { // Recursive invocation, parsing placeholders contained in the // previously resolved placeholder value. propVal = parseStringValue(propVal, placeholderResolver, visitedPlaceholders); result.replace(startIndex, endIndex + this.placeholderSuffix.length(), propVal); if (logger.isTraceEnabled()) { logger.trace("Resolved placeholder '" + placeholder + "'"); } startIndex = result.indexOf(this.placeholderPrefix, startIndex + propVal.length()); } else if (this.ignoreUnresolvablePlaceholders) { // Proceed with unprocessed value. startIndex = result.indexOf(this.placeholderPrefix, endIndex + this.placeholderSuffix.length()); } else { throw new IllegalArgumentException("Could not resolve placeholder '" + placeholder + "'" + " in value /"" + value + "/""); } visitedPlaceholders.remove(originalPlaceholder); } else { startIndex = -1; } } return result.toString(); } 复制代码
关于 PropertyResolver
以后再做解析
这个方法很长,将会长篇幅来介绍,先看个大概干了什么:
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(); } } } 复制代码
接下来逐步解剖:
protected void prepareRefresh() { this.startupDate = System.currentTimeMillis(); this.closed.set(false); this.active.set(true); if (logger.isInfoEnabled()) { logger.info("Refreshing " + this); } // 初始化加载配置文件方法,并没有具体实现,一个留给用户的扩展点 initPropertySources(); // 检查环境变量 getEnvironment().validateRequiredProperties(); this.earlyApplicationEvents = new LinkedHashSet<>(); } 复制代码
其中有个方法为validateRequiredProperties(),这个方法是为了检查所有需要的环境变量是否为空,如果为空就停止启动,然后抛出异常
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() { // 核心 refreshBeanFactory(); // 返回创建的 BeanFactory ConfigurableListableBeanFactory beanFactory = getBeanFactory(); if (logger.isDebugEnabled()) { logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory); } return beanFactory; } 复制代码
/** * This implementation performs an actual refresh of this context's underlying * bean factory, shutting down the previous bean factory (if any) and * initializing a fresh bean factory for the next phase of the context's lifecycle. */ @Override protected final void refreshBeanFactory() throws BeansException { // 判断当前ApplicationContext是否存在BeanFactory,如果存在的话就销毁所有 Bean,关闭 BeanFactory // 注意,一个应用可以存在多个BeanFactory,这里判断的是当前ApplicationContext是否存在BeanFactory if (hasBeanFactory()) { destroyBeans(); closeBeanFactory(); } try { // 初始化DefaultListableBeanFactory DefaultListableBeanFactory beanFactory = createBeanFactory(); beanFactory.setSerializationId(getId()); // 设置 BeanFactory 的两个配置属性:是否允许 Bean 覆盖、是否允许循环引用 customizeBeanFactory(beanFactory); // 加载 Bean 到 BeanFactory 中 loadBeanDefinitions(beanFactory); synchronized (this.beanFactoryMonitor) { this.beanFactory = beanFactory; } } catch (IOException ex) { throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex); } } 复制代码
在这里初始化了一个DefaultListableBeanFactory,看看这个类的继承图
这是一个非常庞大的家伙
先了解 BeanDefinition
,我们知道 BeanFactory
是一个Bean容器,而 BeanDefinition
就是Bean的一种形式(它里面包含了Bean指向的类、是否单例、是否懒加载、Bean的依赖关系等相关的属性)。 BeanFactory
中就是保存的 BeanDefinition
。
BeanDefinition的接口定义:
public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement { // Bean的生命周期,默认只提供sington和prototype两种,在WebApplicationContext中还会有request, session, globalSession, application, websocket 等 String SCOPE_SINGLETON = ConfigurableBeanFactory.SCOPE_SINGLETON; String SCOPE_PROTOTYPE = ConfigurableBeanFactory.SCOPE_PROTOTYPE; // 设置父Bean void setParentName(String parentName); // 获取父Bean String getParentName(); // 设置Bean的类名称 void setBeanClassName(String beanClassName); // 获取Bean的类名称 String getBeanClassName(); // 设置bean的scope void setScope(String scope); String getScope(); // 设置是否懒加载 void setLazyInit(boolean lazyInit); boolean isLazyInit(); // 设置该Bean依赖的所有Bean void setDependsOn(String... dependsOn); // 返回该Bean的所有依赖 String[] getDependsOn(); // 设置该Bean是否可以注入到其他Bean中 void setAutowireCandidate(boolean autowireCandidate); // 该Bean是否可以注入到其他Bean中 boolean isAutowireCandidate(); // 同一接口的多个实现,如果不指定名字的话,Spring会优先选择设置primary为true的bean void setPrimary(boolean primary); // 是否是primary的 boolean isPrimary(); // 指定工厂名称 void setFactoryBeanName(String factoryBeanName); // 获取工厂名称 String getFactoryBeanName(); // 指定工厂类中的工厂方法名称 void setFactoryMethodName(String factoryMethodName); // 获取工厂类中的工厂方法名称 String getFactoryMethodName(); // 构造器参数 ConstructorArgumentValues getConstructorArgumentValues(); // Bean 中的属性值,后面给 bean 注入属性值的时候会说到 MutablePropertyValues getPropertyValues(); // 是否 singleton boolean isSingleton(); // 是否 prototype boolean isPrototype(); // 如果这个 Bean 是被设置为 abstract,那么不能实例化,常用于作为 父bean 用于继承 boolean isAbstract(); int getRole(); String getDescription(); String getResourceDescription(); BeanDefinition getOriginatingBeanDefinition(); } 复制代码
而 loadBeanDefinitions()
方法会读取配置文件加载各个 BeanDefinition
,然后放到 BeanFactory
中
@Override protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException { // 实例化XmlBeanDefinitionReader XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory); beanDefinitionReader.setEnvironment(this.getEnvironment()); beanDefinitionReader.setResourceLoader(this); beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this)); // 初始化 BeanDefinitionReader initBeanDefinitionReader(beanDefinitionReader); // 接着往下看 loadBeanDefinitions(beanDefinitionReader); } protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException { Resource[] configResources = getConfigResources(); if (configResources != null) { reader.loadBeanDefinitions(configResources); } String[] configLocations = getConfigLocations(); if (configLocations != null) { reader.loadBeanDefinitions(configLocations); } } 复制代码
然后调用 XmlBeanDefinitionReader
的 loadBeanDefinitions()
方法
public int loadBeanDefinitions(Resource... resources) throws BeanDefinitionStoreException { Assert.notNull(resources, "Resource array must not be null"); int counter = 0; // 循环,处理所有配置文件,咱们这里就传了一个 for (Resource resource : resources) { // 继续往下看 counter += loadBeanDefinitions(resource); } // 最后返回加载的所有BeanDefinition的数量 return counter; } @Override public int loadBeanDefinitions(String location) throws BeanDefinitionStoreException { return loadBeanDefinitions(location, null); } public int loadBeanDefinitions(String location, @Nullable Set<Resource> actualResources) throws BeanDefinitionStoreException { ResourceLoader resourceLoader = getResourceLoader(); if (resourceLoader == null) { throw new BeanDefinitionStoreException( "Cannot import bean definitions from location [" + location + "]: no ResourceLoader available"); } if (resourceLoader instanceof ResourcePatternResolver) { try { //将配置文件转换为Resource对象 Resource[] resources = ((ResourcePatternResolver) resourceLoader).getResources(location); //接着往下看 int loadCount = loadBeanDefinitions(resources); if (actualResources != null) { for (Resource resource : resources) { actualResources.add(resource); } } if (logger.isDebugEnabled()) { logger.debug("Loaded " + loadCount + " bean definitions from location pattern [" + location + "]"); } return loadCount; } catch (IOException ex) { throw new BeanDefinitionStoreException( "Could not resolve bean definition resource pattern [" + location + "]", ex); } } else { // Can only load single resources by absolute URL. Resource resource = resourceLoader.getResource(location); int loadCount = loadBeanDefinitions(resource); if (actualResources != null) { actualResources.add(resource); } if (logger.isDebugEnabled()) { logger.debug("Loaded " + loadCount + " bean definitions from location [" + location + "]"); } return loadCount; } } 复制代码
这里面多次提到了一个XmlBeanDefinitionReader,这个类主要实现的接口是BeanDefinitionReader
这个类如何读取配置文件,创建BeanDefinition,然后注册到容器beanDefinitionMap,我们以后再来细讲,看太远就回不来了
现在回到refresh()方法的主线上,现在refresh已经走到了prepareBeanFactory,看名字就知道是给BeanFactory准备一些东西, 实际上这个方法就是BeanFactory的类加载器,添加BeanPostProcessor,然后手动注册几个特殊的bean
/** * 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. // 设置当前BeanFacoty的类加载器 beanFactory.setBeanClassLoader(getClassLoader()); // 设置BeanExpressionResolver beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader())); // 注册PropertyEditor beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment())); // Configure the bean factory with context callbacks. // 在所有实现了Aware接口的bean在初始化的时候,这个 processor负责回调 // 例如,bean获取ApplicationContext 而 implement ApplicationContextAware // 当然,它也处理实现了 EnvironmentAware、ResourceLoaderAware 等的bean beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this)); // 下面几行的意思就是,如果某个 bean 依赖于以下几个接口的实现类的bean,在自动装配的时候忽略它们 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. // 下面几行就是为特殊的几个 bean 赋值,如果有 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. // 如果存在bean名称为loadTimeWeaver的bean则注册一个BeanPostProcessor // 具体的这个LoadTimeWeaver是干啥的后面再说 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. // 注册environment这个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()); } // JVM属性 if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) { beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment()); } } 复制代码
这里是Spring中提供的一个扩展,调用类中的,这个留给子类去扩展,具体的子类可以在这步的时候添加一些特殊的 BeanFactoryPostProcessor
的实现类或做点什么事.方法定义如下
/** * 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) { } 复制代码
这里是Spring中提供的一个扩展,若有bean实现了 BeanFactoryPostProcessor
,那么在容器初始化以后,Spring 会负责调用里面的 postProcessBeanFactory
方法 这个接口的定义如下:
public interface BeanFactoryPostProcessor { void postProcessBeanFactory(ConfigurableListableBeanFactory beanfactory) throws BeansException; } 复制代码
这里又是一个扩展点, 注册 拦截bean创建的bean处理器,每个bean创建的时候都会调用所有的 BeanPostProcessor
注册 BeanPostProcessor
的实现类,注意不是 BeanFactoryPostProcessor
此接口有两个方法: postProcessBeforeInitialization
和 postProcessAfterInitialization
分别会在Bean初始化之前和初始化之后得到执行
初始化当前 ApplicationContext
的 MessageSource
,为了国际化
初始化当前 BeanFactory
事件广播器,会注册一个 SimpleApplicationEventMulticaster
单例,可以调用 ApplicationEventMulticaster
的 multicastEvent
方法来触发一个事件, ApplicationEventMulticaster
会调用相应的 ApplicationListener
,到后面讲Spring事件机制再细说
这里又是给子类的一个扩展点,
/** * 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. } 复制代码
检测Listener然后注册到容器
protected void registerListeners() { //先添加手动set的一些监听器 for (ApplicationListener<?> listener : getApplicationListeners()) { getApplicationEventMulticaster().addApplicationListener(listener); } //取到监听器的名称,设置到广播器 String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false); for (String listenerBeanName : listenerBeanNames) { getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName); } // 如果存在早期应用事件,发布 Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents; this.earlyApplicationEvents = null; if (earlyEventsToProcess != null) { for (ApplicationEvent earlyEvent : earlyEventsToProcess) { getApplicationEventMulticaster().multicastEvent(earlyEvent); } } } 复制代码
在前面refresh方法内走了那么长的路,但是依然没有完成bean的初始化和依赖注入,到这里,Spring觉得时机成熟了,就开始初始化 不是懒加载的单例bean
这里又会迎来一段艰难的路程
/** * 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. // 为当前BeanFactory初始化ConversionService 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(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(); } 复制代码
ConversionService 这个是类型转换相关的类,场景之一就是将前端传过来的参数和后端的controller方法上的参数格式转换的时候使用
EmbeddedValueResolver 利用EmbeddedValueResolver可以很方便的实现读取配置文件的属性
@Component public class PropertiesUtil implements EmbeddedValueResolverAware { private StringValueResolver resolver; @Override public void setEmbeddedValueResolver(StringValueResolver resolver) { this.resolver = resolver; } /** * 获取属性时直接传入属性名称即可 */ public String getPropertiesValue(String key) { StringBuilder name = new StringBuilder("${").append(key).append("}"); return resolver.resolveStringValue(name.toString()); } } 复制代码
这个方法是重点
public void preInstantiateSingletons() throws BeansException { if (this.logger.isDebugEnabled()) { this.logger.debug("Pre-instantiating singletons in " + this); } // this.beanDefinitionNames 保存了所有的 beanNames List<String> beanNames = new ArrayList<String>(this.beanDefinitionNames); for (String beanName : beanNames) { // Return a merged RootBeanDefinition, traversing the parent bean definition,if the specified bean corresponds to a child bean definition. RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName); // 不是抽象类、是单例的且不是懒加载的 if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) { // 处理 FactoryBean if (isFactoryBean(beanName)) { //在 beanName 前面加上“&” 符号 final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName); // 判断当前 FactoryBean 是否是 SmartFactoryBean 的实现 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 { // 不是FactoryBean的直接使用此方法进行初始化 getBean(beanName); } } } // 如果bean实现了 SmartInitializingSingleton 接口的,那么在这里得到回调 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(); } } } } 复制代码
可以看到,无论是否是FactoryBean,最后都会调用getBean(String beanName)方法
@Override public Object getBean(String name) throws BeansException { return doGetBean(name, null, null, false); } protected <T> T doGetBean( final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly) throws BeansException { // 获取beanName,处理两种情况,一个是前面说的 FactoryBean(前面带 ‘&’),再一个这个方法是可以根据别名来获取Bean的,所以在这里是要转换成最正统的BeanName //主要逻辑就是如果是FactoryBean就把&去掉如果是别名就把根据别名获取真实名称后面就不贴代码了 final String beanName = transformedBeanName(name); //最后的返回值 Object bean; // 检查是否已初始化 Object sharedInstance = getSingleton(beanName); //如果已经初始化过了,且没有传args参数就代表是get,直接取出返回 if (sharedInstance != null && args == null) { if (logger.isDebugEnabled()) { if (isSingletonCurrentlyInCreation(beanName)) { logger.debug("..."); } else { logger.debug("Returning cached instance of singleton bean '" + beanName + "'"); } } // 这里如果是普通Bean 的话,直接返回,如果是 FactoryBean 的话,返回它创建的那个实例对象 bean = getObjectForBeanInstance(sharedInstance, name, beanName, null); } else { // 如果存在prototype类型的这个bean if (isPrototypeCurrentlyInCreation(beanName)) { throw new BeanCurrentlyInCreationException(beanName); } // 如果当前BeanDefinition不存在这个bean且具有父BeanFactory BeanFactory parentBeanFactory = getParentBeanFactory(); if (parentBeanFactory != null && !containsBeanDefinition(beanName)) { String nameToLookup = originalBeanName(name); // 返回父容器的查询结果 if (args != null) { return (T) parentBeanFactory.getBean(nameToLookup, args); } else { return parentBeanFactory.getBean(nameToLookup, requiredType); } } if (!typeCheckOnly) { // typeCheckOnly 为 false,将当前 beanName 放入一个 alreadyCreated 的 Set 集合中。 markBeanAsCreated(beanName); } /* * 到这就要创建bean了 */ try { final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); checkMergedBeanDefinition(mbd, beanName, args); // 先初始化依赖的所有 Bean, depends-on 中定义的依赖 String[] dependsOn = mbd.getDependsOn(); if (dependsOn != null) { for (String dep : dependsOn) { // 检查是不是有循环依赖 if (isDependent(beanName, dep)) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'"); } // 注册一下依赖关系 registerDependentBean(dep, beanName); // 先初始化被依赖项 getBean(dep); } } // 如果是单例的 if (mbd.isSingleton()) { sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() { @Override public Object getObject() throws BeansException { try { // 执行创建 Bean,下面说 return createBean(beanName, mbd, args); } catch (BeansException ex) { destroySingleton(beanName); throw ex; } } }); bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); } // 如果是prototype else if (mbd.isPrototype()) { Object prototypeInstance = null; try { beforePrototypeCreation(beanName); // 执行创建 Bean prototypeInstance = createBean(beanName, mbd, args); } finally { afterPrototypeCreation(beanName); } bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd); } // 如果不是 singleton 和 prototype 那么就是自定义的scope、例如Web项目中的session等类型,这里就交给自定义scope的应用方去实现 else { String scopeName = mbd.getScope(); final Scope scope = this.scopes.get(scopeName); if (scope == null) { throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'"); } try { Object scopedInstance = scope.get(beanName, new ObjectFactory<Object>() { @Override public Object getObject() throws BeansException { beforePrototypeCreation(beanName); try { // 执行创建 Bean return createBean(beanName, mbd, args); } finally { afterPrototypeCreation(beanName); } } }); bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd); } catch (IllegalStateException ex) { throw new BeanCreationException(beanName, "Scope '" + scopeName + "' is not active for the current thread; consider " + "defining a scoped proxy for this bean if you intend to refer to it from a singleton", ex); } } } catch (BeansException ex) { cleanupAfterBeanCreationFailure(beanName); throw ex; } } //检查bean的类型 if (requiredType != null && bean != null && !requiredType.isInstance(bean)) { try { return getTypeConverter().convertIfNecessary(bean, requiredType); } catch (TypeMismatchException ex) { if (logger.isDebugEnabled()) { logger.debug("Failed to convert bean '" + name + "' to required type '" + ClassUtils.getQualifiedName(requiredType) + "'", ex); } throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass()); } } return (T) bean; } 复制代码
开始会先判断bean存不存在,如果存在就直接返回了。如果不存在调用 createBean(String beanName, RootBeanDefinition mbd, Object[] args)
方法了
protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException { if (logger.isDebugEnabled()) { logger.debug("Creating instance of bean '" + beanName + "'"); } RootBeanDefinition mbdToUse = mbd; // 确保 BeanDefinition 中的 Class 被加载 Class<?> resolvedClass = resolveBeanClass(mbd, beanName); if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) { mbdToUse = new RootBeanDefinition(mbd); mbdToUse.setBeanClass(resolvedClass); } // 准备方法覆写,如果bean中定义了 <lookup-method /> 和 <replaced-method /> try { mbdToUse.prepareMethodOverrides(); } catch (BeanDefinitionValidationException ex) { throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(), beanName, "Validation of method overrides failed", ex); } try { // 如果有代理的话直接返回 Object bean = resolveBeforeInstantiation(beanName, mbdToUse); if (bean != null) { return bean; } } catch (Throwable ex) { throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "BeanPostProcessor before instantiation of bean failed", ex); } // 创建 bean Object beanInstance = doCreateBean(beanName, mbdToUse, args); if (logger.isDebugEnabled()) { logger.debug("Finished creating instance of bean '" + beanName + "'"); } return beanInstance; } protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) throws BeanCreationException { BeanWrapper instanceWrapper = null; if (mbd.isSingleton()) { //如果是.factoryBean则从缓存删除 instanceWrapper = this.factoryBeanInstanceCache.remove(beanName); } if (instanceWrapper == null) { // 实例化 Bean,这个方法里面才是终点,下面说 instanceWrapper = createBeanInstance(beanName, mbd, args); } //bean实例 final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null); //bean类型 Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null); mbd.resolvedTargetType = beanType; synchronized (mbd.postProcessingLock) { if (!mbd.postProcessed) { try { // 循环调用实现了MergedBeanDefinitionPostProcessor接口的postProcessMergedBeanDefinition方法 // Spring对这个接口有几个默认的实现,其中大家最熟悉的一个是操作@Autowired注解的 applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName); } catch (Throwable ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Post-processing of merged bean definition failed", ex); } mbd.postProcessed = true; } } // 解决循环依赖问题 boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences && isSingletonCurrentlyInCreation(beanName)); if (earlySingletonExposure) { if (logger.isDebugEnabled()) { logger.debug("Eagerly caching bean '" + beanName + "' to allow for resolving potential circular references"); } //当正在创建A时,A依赖B,此时通过(8将A作为ObjectFactory放入单例工厂中进行early expose,此处B需要引用A,但A正在创建,从单例工厂拿到ObjectFactory,从而允许循环依赖 addSingletonFactory(beanName, new ObjectFactory<Object>() { @Override public Object getObject() throws BeansException { return getEarlyBeanReference(beanName, mbd, bean); } }); } Object exposedObject = bean; try { // 负责属性装配,很重要,下面说 // 装配属性 populateBean(beanName, mbd, instanceWrapper); if (exposedObject != null) { // 这里是处理bean初始化完成后的各种回调,例如init-method、InitializingBean 接口、BeanPostProcessor 接口 exposedObject = initializeBean(beanName, exposedObject, mbd); } } catch (Throwable ex) { if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) { throw (BeanCreationException) ex; } else { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex); } } //同样的,如果存在循环依赖 if (earlySingletonExposure) { Object earlySingletonReference = getSingleton(beanName, false); if (earlySingletonReference != null) { if (exposedObject == bean) { exposedObject = earlySingletonReference; } else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) { String[] dependentBeans = getDependentBeans(beanName); Set<String> actualDependentBeans = new LinkedHashSet<String>(dependentBeans.length); for (String dependentBean : dependentBeans) { if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) { actualDependentBeans.add(dependentBean); } } if (!actualDependentBeans.isEmpty()) { throw new BeanCurrentlyInCreationException(beanName, "Bean with name '" + beanName + "' has been injected into other beans [" + StringUtils.collectionToCommaDelimitedString(actualDependentBeans) + "] in its raw version as part of a circular reference, but has eventually been " + "wrapped. This means that said other beans do not use the final version of the " + "bean. This is often the result of over-eager type matching - consider using " + "'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example."); } } } } // 把bean注册到相应的Scope中 try { registerDisposableBeanIfNecessary(beanName, bean, mbd); } catch (BeanDefinitionValidationException ex) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex); } return exposedObject; } 复制代码
这个方法完成bean内部属性的注入
protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) { // bean的所有属性 PropertyValues pvs = mbd.getPropertyValues(); if (bw == null) { if (!pvs.isEmpty()) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance"); } else { return; } } boolean continueWithPropertyPopulation = true; if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; // 如果返回 false,代表不需要进行后续的属性设值,也不需要再经过其他的 BeanPostProcessor 的处理 if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) { continueWithPropertyPopulation = false; break; } } } } if (!continueWithPropertyPopulation) { return; } if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME || mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) { MutablePropertyValues newPvs = new MutablePropertyValues(pvs); // 通过名字找到所有属性值,如果是 bean 依赖,先初始化依赖的 bean。记录依赖关系 if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) { autowireByName(beanName, mbd, bw, newPvs); } // 通过类型装配。复杂一些 if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) { autowireByType(beanName, mbd, bw, newPvs); } pvs = newPvs; } boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors(); boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE); if (hasInstAwareBpps || needsDepCheck) { PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching); if (hasInstAwareBpps) { for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; // 这里就是上方曾经提到过得对@Autowired处理的一个BeanPostProcessor了 // 它会对所有标记@Autowired、@Value 注解的属性进行设值 pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName); if (pvs == null) { return; } } } } if (needsDepCheck) { checkDependencies(beanName, mbd, filteredPds, pvs); } } // 设置 bean 实例的属性值 applyPropertyValues(beanName, mbd, bw, pvs); } 复制代码
protected void finishRefresh() { //看名字就知道了,清理刚才一系列操作使用到的资源缓存 clearResourceCaches(); // 初始化LifecycleProcessor initLifecycleProcessor(); // 这个方法的内部实现是启动所有实现了Lifecycle接口的bean getLifecycleProcessor().onRefresh(); //发布ContextRefreshedEvent事件 publishEvent(new ContextRefreshedEvent(this)); // 检查spring.liveBeansView.mbeanDomain是否存在,有就会创建一个MBeanServer LiveBeansView.registerApplicationContext(this); } 复制代码