本文章出处 Spring使用xml启动源码解析
转载请说明出处
<properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <spring.version>5.1.8.RELEASE</spring.version> </properties> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency> </dependencies>
<?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="myBean" class="org.ting.spring.study.App"/> </beans>
package org.ting.spring.study; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class App { public static void main( String[] args ){ ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml"); App myBean = (App) app.getBean("myBean"); System.out.println(myBean); } }
这个类基本上都是构造函数
可以看出,这个没有任何业务逻辑代码,都是通过继承抽象类扩展功能,主要业务都在父类中。下面我们看下构造方法是怎么初始化Spring容器的
public ClassPathXmlApplicationContext(String configLocation) throws BeansException { this(new String[] {configLocation}, true, null); }
进入this构造方法
public ClassPathXmlApplicationContext( String[] configLocations, boolean refresh, @Nullable ApplicationContext parent) throws BeansException { //设置父容器 super(parent); setConfigLocations(configLocations); if (refresh) { refresh(); } }
可以看出,这个才是ClassPathXmlApplicatonContext实例化方法,设置父容器对象,添加配置文件路径到容器中,开始启动容器工作。
super(parent)
方法依次调用服务父类 AbstractXmlApplicationContext
、 AbstractRefreshableConfigApplicationContext
、 AbstractRefreshableApplicationContext
、 AbstractApplicationContext
的构造方法。
public AbstractApplicationContext(@Nullable ApplicationContext parent) { this(); setParent(parent); } @Override public void setParent(@Nullable ApplicationContext parent) { this.parent = parent; if (parent != null) { Environment parentEnvironment = parent.getEnvironment(); if (parentEnvironment instanceof ConfigurableEnvironment) { getEnvironment().merge((ConfigurableEnvironment) parentEnvironment); } } }
这个方法主要是向上调用父类构造方法,一直到AbstractApplicationContext对象。参数不为空的话将父上下文对像 Environment
设置合并到当前容器中,将两个容器配置文件合并起来,一般在web环境有使用到。
public void setConfigLocations(@Nullable 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++) { //处理路径,从环境变量中替换占位符 ${x} this.configLocations[i] = resolvePath(locations[i]).trim(); } } else { this.configLocations = null; } }
将路径添加到 AbstractRefreshableConfigApplicationContext
configLocations 属性中,并且出来掉路径中环境变量占位符,保证configLocaiton得到是可用地址。
@Override public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { //准备刷新上下文对象 prepareRefresh(); // 创建Spring Factory对象,清空缓存,解析xml文件转换成BeanDefinition 保存到缓存中 ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); //初始化BeanFactory 内部属性值,添加类型转换 ,前置处理器 prepareBeanFactory(beanFactory); try { // 空方法,让字类实现查看或者修改beanFacory内部属性值 postProcessBeanFactory(beanFactory); // 注册实例化BeanFactoryPostProcessor,并且执行所有类接口方法 invokeBeanFactoryPostProcessors(beanFactory); //注册所有后置处理器 registerBeanPostProcessors(beanFactory); //初始化messageSource bean initMessageSource(); //初始化组播器 initApplicationEventMulticaster(); // 空方法,让字类自行初始化特别bean onRefresh(); // 初始化所有事件监听器,加入组播器中,广播事件 registerListeners(); //启动所有非延迟单例bean finishBeanFactoryInitialization(beanFactory); // 完成applicationContext初始化工作 finishRefresh(); } catch (BeansException ex) { if (logger.isWarnEnabled()) { logger.warn("Exception encountered during context initialization - " + "cancelling refresh attempt: " + ex); } // 销毁已经创建成功bean destroyBeans(); // Reset 'active' flag. cancelRefresh(ex); // Propagate exception to caller. throw ex; } finally { // Reset common introspection caches in Spring's core, since we //清空所有类型注解扫描,反射等元数据集合 resetCommonCaches(); } } }
下面我们一个个方法解析
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()); } } // 初始化PropertySource ,默认不做任何处理,让子类实现 initPropertySources(); // Validate that all properties marked as required are resolvable: // see ConfigurablePropertyResolver#setRequiredProperties getEnvironment().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<>(); }
设置启动时间,将关闭标记设置false,活动开关设置true,initPropertySources(),本身是一个空方法,由子类自行去实现,让子类在容器创建之前修改 ConfigurableEnvironment
的 PropertySources
对象属性。 PropertySources
name/value键值对的封装接口,主要用来装配配置变量。虽然 ClassPathXmlApplicatonContext
和他的父类都没有实现这个方法,在Spring MVC中, GenericWebApplicationContext
实现initPropertySources方法,将 servletContext
配置变量合并到 ProertySources
中。接着看getEnvironment().validateRequiredProperties()这个方法实现在
@Override public void validateRequiredProperties() { MissingRequiredPropertiesException ex = new MissingRequiredPropertiesException(); for (String key : this.requiredProperties) { if (this.getProperty(key) == null) { ex.addMissingRequiredProperty(key); } } if (!ex.getMissingRequiredProperties().isEmpty()) { throw ex; } }
主要校验 ProertySources
中key value,是否有不对应的情况。其实这个主要校验上一个initPropertySources()方法安全措施来的。比如老爸放手让自己儿子去做一件事,自己完全不干预,但是他会偷偷去查看事件做得怎么样?如果做不不行,狠狠打儿子一顿。
这部分应该是整个代码解析最核心的功能了,这个类就是我们经常说的Spring容器,Spring工厂的实现 DefaultListableBeanFactory
。主要负责bean注册实例化,bean查找,bean别名,bean销毁。这里实例化这个对象,也开始说明Spring生命周期正式开始。下面是 DefaultListableBeanFactory的继承关系
查看obtainFreshBeanFactory方法具体内容
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() { refreshBeanFactory(); return getBeanFactory(); }
refreshBeanFactory主要是清除ConfigurableListableBeanFactory bean缓存,重新实例化。
这个方法在 AbstractRefreshableApplicationContext
中
protected final void refreshBeanFactory() throws BeansException { if (hasBeanFactory()) { //判断ConfigurableListableBeanFactory 是否已经创建了 destroyBeans(); closeBeanFactory(); } try { //使用构造函数实例化new DefaultListableBeanFactory(parent) DefaultListableBeanFactory beanFactory = createBeanFactory(); beanFactory.setSerializationId(getId()); //Spring 工厂自定义设置,是否运行已经注册bean被相同beanName覆盖,默认是true,设置是否允许bean之间的循环引用 - 并尝试自动解决它默认也是true customizeBeanFactory(beanFactory); //开始解析xml配置文件,注册BeanDefinition,下面具体分析 loadBeanDefinitions(beanFactory); synchronized (this.beanFactoryMonitor) { this.beanFactory = beanFactory; } } catch (IOException ex) { throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex); } }
先判断ConfigurableListableBeanFactory对象是否已经创建成功了,如果已经存在了,执行销毁Spring容器内已经注册bean销毁,重新实例化ConfigurableListableBeanFactory对象,设置id,设置beanFactory bean重名,依赖解决方式。开始加载xml配置文件,注册BeanDefinition,将已经实例化BeanFactory指引再指向this.beanFactory。
protected void destroyBeans() { getBeanFactory().destroySingletons(); }
调用了ConfigurableListableBeanFactory的destroySingletons方法,接口的实现类是 DefaultListableBeanFactory
。
@Override public void destroySingletons() { super.destroySingletons(); updateManualSingletonNames(Set::clear, set -> !set.isEmpty()); clearByTypeCache(); }
super.destroySingletons()调用了 DefaultSingletonBeanRegistry
的 destroySingletons
方法
public void destroySingletons() { if (logger.isTraceEnabled()) { logger.trace("Destroying singletons in " + this); } synchronized (this.singletonObjects) { this.singletonsCurrentlyInDestruction = true; } String[] disposableBeanNames; synchronized (this.disposableBeans) { //将map key 转化成string 数组 disposableBeanNames = StringUtils.toStringArray(this.disposableBeans.keySet()); } for (int i = disposableBeanNames.length - 1; i >= 0; i--) { destroySingleton(disposableBeanNames[i]); } this.containedBeanMap.clear(); this.dependentBeanMap.clear(); this.dependenciesForBeanMap.clear(); clearSingletonCache(); }
public void destroySingleton(String beanName) { // Remove a registered singleton of the given name, if any. removeSingleton(beanName); // Destroy the corresponding DisposableBean instance. DisposableBean disposableBean; synchronized (this.disposableBeans) { disposableBean = (DisposableBean) this.disposableBeans.remove(beanName); } destroyBean(beanName, disposableBean); }
查看removeSingleton方法
protected void removeSingleton(String beanName) { synchronized (this.singletonObjects) { this.singletonObjects.remove(beanName); this.singletonFactories.remove(beanName); this.earlySingletonObjects.remove(beanName); this.registeredSingletons.remove(beanName); } }
这几个分别就是内部容器来的,看下主要用途
/**缓存单例bean对象 : beanName 对应 bean对象 */ private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256); /**缓存单例工厂: beanName 对应 bean工厂实体. */ private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16); /** 缓存bean早期对象,主要是bean注册的实体依赖对象: beanName 对应 实体对象 */ private final Map<String, Object> earlySingletonObjects = new HashMap<>(16); /**已经成功注册beanName,按住注册顺序保存 */ private final Set<String> registeredSingletons = new LinkedHashSet<>(256);
protected void destroyBean(String beanName, @Nullable DisposableBean bean) { // Trigger destruction of dependent beans first... Set<String> dependencies; synchronized (this.dependentBeanMap) { // Within full synchronization in order to guarantee a disconnected Set dependencies = this.dependentBeanMap.remove(beanName); } if (dependencies != null) { if (logger.isTraceEnabled()) { logger.trace("Retrieved dependent beans for bean '" + beanName + "': " + dependencies); } for (String dependentBeanName : dependencies) { destroySingleton(dependentBeanName); } } // Actually destroy the bean now... if (bean != null) { try { bean.destroy(); } catch (Throwable ex) { if (logger.isInfoEnabled()) { logger.info("Destroy method on bean with name '" + beanName + "' threw an exception", ex); } } } // Trigger destruction of contained beans... Set<String> containedBeans; synchronized (this.containedBeanMap) { // Within full synchronization in order to guarantee a disconnected Set containedBeans = this.containedBeanMap.remove(beanName); } if (containedBeans != null) { for (String containedBeanName : containedBeans) { destroySingleton(containedBeanName); } }
在删除DisposableBean实例的时候,获取bean下依赖实例,逐个移除。最后将Spring容器依赖实体逐个移除。接着看 closeBeanFactory()
办法
@Override protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException { // Create a new XmlBeanDefinitionReader for the given BeanFactory. XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory); // Configure the bean definition reader with this context's // resource loading environment. beanDefinitionReader.setEnvironment(this.getEnvironment()); beanDefinitionReader.setResourceLoader(this); //xml 文件约束校验 beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this)); // Allow a subclass to provide custom initialization of the reader, // 设置xml校验方式 initBeanDefinitionReader(beanDefinitionReader); //开始解析xml转化BeanDefinition loadBeanDefinitions(beanDefinitionReader); }
实例化 XmlBeanDefinitionReader
将资源文件xml解析成BeanDefinition,将Spring上下文对象赋值给对象属性。loadBeanDefinitions会将xml文件转化成 Document
对象,由于这部分太过繁琐,需要根据文件名获取ResouceLoader,再获取到文件流对象,解析xml成Document,觉得省略这些代码解析,主要放在Document如何转化成 BeanDefinition
,在 DefaultBeanDefinitionDocumentReader
实现。
protected void doRegisterBeanDefinitions(Element root) { // Any nested <beans> elements will cause recursion in this method. In // order to propagate and preserve <beans> default-* attributes correctly, // keep track of the current (parent) delegate, which may be null. Create // the new (child) delegate with a reference to the parent for fallback purposes, // then ultimately reset this.delegate back to its original (parent) reference. // this behavior emulates a stack of delegates without actually necessitating one. BeanDefinitionParserDelegate parent = this.delegate; this.delegate = createDelegate(getReaderContext(), root, parent); if (this.delegate.isDefaultNamespace(root)) { String profileSpec = root.getAttribute(PROFILE_ATTRIBUTE); //判断文件profile属性,转化成array if (StringUtils.hasText(profileSpec)) { String[] specifiedProfiles = StringUtils.tokenizeToStringArray( profileSpec, BeanDefinitionParserDelegate.MULTI_VALUE_ATTRIBUTE_DELIMITERS); // We cannot use Profiles.of(...) since profile expressions are not supported // in XML config. See SPR-12458 for details. if (!getReaderContext().getEnvironment().acceptsProfiles(specifiedProfiles)) { if (logger.isDebugEnabled()) { logger.debug("Skipped XML bean definition file due to specified profiles [" + profileSpec + "] not matching: " + getReaderContext().getResource()); } return; } } } //运行自定义实现类 预处理xml文件,空方法,让子类实现。 preProcessXml(root); parseBeanDefinitions(root, this.delegate); //运行自定义自主实心方法,修改xml属性,空方法。 postProcessXml(root); this.delegate = parent; }
BeanDefinitionParserDelegate
主要是解析Document命名空间,标签元素,属性,将xml标签转化成对象。
protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) { if (delegate.isDefaultNamespace(root)) { NodeList nl = root.getChildNodes(); for (int i = 0; i < nl.getLength(); i++) { Node node = nl.item(i); if (node instanceof Element) { Element ele = (Element) node; if (delegate.isDefaultNamespace(ele)) { //注册BeanDefinition parseDefaultElement(ele, delegate); } else { delegate.parseCustomElement(ele); } } } } else { delegate.parseCustomElement(root); } }
循环遍历 beans
的子标签,符合"import", "alias", "bean"命名空间,进入标签解析环节
private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) { if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) { importBeanDefinitionResource(ele); } else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) { processAliasRegistration(ele); } else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) { processBeanDefinition(ele, delegate); } else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) { // recurse doRegisterBeanDefinitions(ele); } }
主要看下bean标签解析
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) { BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele); if (bdHolder != null) { bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder); try { // Register the final decorated instance. BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry()); } catch (BeanDefinitionStoreException ex) { getReaderContext().error("Failed to register bean definition with name '" + bdHolder.getBeanName() + "'", ele, ex); } // Send registration event. getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder)); } }
这个方法将xml解析返回 BeanDefinition对象,如果对象不为空,继续解析元素的自定义属性,并将元素自定义属性设置给刚刚创建BeanDefiniton对象,最后广播注册BeanDefinition对象。关于如何生成BeanDefiniton对象,这个方法我不具体深入了解了,毕竟里面篇幅很多的,以后会专门出一个章节去说明。
prepareBeanFactory方法主要是配置BeanFactory 类加载器,Spring el表达式实现,bean前置处理器等等的属性设置,主要逻辑详看下面的代码
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) { // Tell the internal bean factory to use the context's class loader etc. //设置工厂类加载器 beanFactory.setBeanClassLoader(getClassLoader()); //设置Spring el表达式实现 beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader())); //添加属性转化器 beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment())); /* * 添加后置处理器实现, 如果实现了相应的 Aware 接口,则注入对应的资源 * 1. EnvironmentAware * 2. EmbeddedValueResolverAware * 3. ResourceLoaderAware * 4. ApplicationEventPublisherAware * 5. MessageSourceAware * 6. ApplicationContextAware */ 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); //将Spring 内部对象缓存起来,注册到容器内部。 beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory); beanFactory.registerResolvableDependency(ResourceLoader.class, this); beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this); beanFactory.registerResolvableDependency(ApplicationContext.class, this); // 注册 事件监听器前置处理 beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this)); // 判断存在AOP bean name 则注册aop前置处理器 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())); } // 注册 默认environment beans. if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) { //向Spring容器注册bean 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());0 } }
addBeanPostProcessor方法主要添加BeanPostProcessor接口实现类,Bean 的后置处理器,主要是在 bean 初始化前后进行一些处理工作,spring bean 创建委派给个大后置处理器创建。
public interface BeanPostProcessor { /** * bean 在创建之前,对bean进行处理,将处理过实体返回给BeanFactory容器 */ @Nullable default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { return bean; } /** * bean创建之后,对bean进行处理,相当于给已经创建的进行功能加强 */ @Nullable default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { return bean; } }
@Override @Nullable public Object postProcessBeforeInitialization(final Object bean, String beanName) throws BeansException { AccessControlContext acc = null; if (System.getSecurityManager() != null && (bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware || bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware || bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)) { acc = this.applicationContext.getBeanFactory().getAccessControlContext(); } if (acc != null) { AccessController.doPrivileged((PrivilegedAction<Object>) () -> { invokeAwareInterfaces(bean); return null; }, acc); } else { invokeAwareInterfaces(bean); } return bean; } private void invokeAwareInterfaces(Object bean) { if (bean instanceof Aware) { if (bean instanceof EnvironmentAware) { ((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment()); } if (bean instanceof EmbeddedValueResolverAware) { ((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver); } if (bean instanceof ResourceLoaderAware) { ((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext); } if (bean instanceof ApplicationEventPublisherAware) { ((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext); } if (bean instanceof MessageSourceAware) { ((MessageSourceAware) bean).setMessageSource(this.applicationContext); } if (bean instanceof ApplicationContextAware) { ((ApplicationContextAware) bean).setApplicationContext(this.applicationContext); } } }
上面的逻辑非常判断准备初始化bean是否实现了 EnvironmentAware
, EmbeddedValueResolverAware
, ResourceLoaderAware
, ApplicationEventPublisherAware
, MessageSourceAware
. ApplicationContextAware
接口,如果是,直接执行接口方法,将Spring工厂方法注入属性中。这个也解析了上面设置 registerResolvableDependency
依赖注入忽略。
postProcessBeanFactory方法中没有任何实现,主要是允许子类在Spring工厂还没有初始化bean之前,添加一些特殊bean进入到容器中,比如添加BeanPostProcessors接口实现类。这时候Spring 已经解析完xml,还需要想添加一些bean到容器中,这时候就可以实现这个方法。
BeanFactoryPostProcessors接口跟BeanPostProcessor类似,可以用于bean的定义进行处理,也可以在bean初始化之前修改bean元数据。可以配置多个BeanFactoryPostProcessor,使用Order接口来控制执行顺序。源码展示
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) { //执行BeanFactoryPostProcessors ,从容器中已经实例化对象中执行方法 PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors()); if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {//判断是否需要AOP支持,注册AOP前置处理器 beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory)); beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader())); } }
public static void invokeBeanFactoryPostProcessors( ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) { // Invoke BeanDefinitionRegistryPostProcessors first, if any. Set<String> processedBeans = new HashSet<>(); if (beanFactory instanceof BeanDefinitionRegistry) { //强制类型 BeanDefinitionRegistryPostProcessor接口需要用到 BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory; List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>(); List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>(); //遍历所有BeanFactoryPostProcessor,按照BeanFactoryPostProcessor类型和BeanDefinitionRegistryPostProcessor类型分别放入不用容器中, //并且执行BeanDefinitionRegistryPostProcessor接口方法。 for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) { if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) { BeanDefinitionRegistryPostProcessor registryProcessor = (BeanDefinitionRegistryPostProcessor) postProcessor; registryProcessor.postProcessBeanDefinitionRegistry(registry); //执行接口方法,参考或者修改bean 元数据 registryProcessors.add(registryProcessor); } else { regularPostProcessors.add(postProcessor); } } // Do not initialize FactoryBeans here: We need to leave all regular beans // uninitialized to let the bean factory post-processors apply to them! // Separate between BeanDefinitionRegistryPostProcessors that implement // PriorityOrdered, Ordered, and the rest. List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>(); // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered. //获取工厂中所以BeanDefinitionRegistryPostProcessor类型 bean String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); for (String ppName : postProcessorNames) { if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); processedBeans.add(ppName); } } sortPostProcessors(currentRegistryProcessors, beanFactory); registryProcessors.addAll(currentRegistryProcessors); //执行集合中所有BeanDefinitionRegistryPostProcessors 接口方法 invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry); currentRegistryProcessors.clear(); // Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered. postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); for (String ppName : postProcessorNames) { if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) { currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); processedBeans.add(ppName); } } //根据order接口排序集合中的顺序 sortPostProcessors(currentRegistryProcessors, beanFactory); registryProcessors.addAll(currentRegistryProcessors); invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry); currentRegistryProcessors.clear(); // Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear. boolean reiterate = true; while (reiterate) { reiterate = false; postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); for (String ppName : postProcessorNames) { if (!processedBeans.contains(ppName)) { currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); processedBeans.add(ppName); reiterate = true; } } sortPostProcessors(currentRegistryProcessors, beanFactory); registryProcessors.addAll(currentRegistryProcessors); invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry); currentRegistryProcessors.clear(); } // Now, invoke the postProcessBeanFactory callback of all processors handled so far. invokeBeanFactoryPostProcessors(registryProcessors, beanFactory); invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory); } else { // Invoke factory processors registered with the context instance. invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory); } // Do not initialize FactoryBeans here: We need to leave all regular beans // uninitialized to let the bean factory post-processors apply to them! String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false); // Separate between BeanFactoryPostProcessors that implement PriorityOrdered, // Ordered, and the rest. List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>(); List<String> orderedPostProcessorNames = new ArrayList<>(); List<String> nonOrderedPostProcessorNames = new ArrayList<>(); for (String ppName : postProcessorNames) { if (processedBeans.contains(ppName)) { // skip - already processed in first phase above } else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class)); } else if (beanFactory.isTypeMatch(ppName, Ordered.class)) { orderedPostProcessorNames.add(ppName); } else { nonOrderedPostProcessorNames.add(ppName); } } // First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered. sortPostProcessors(priorityOrderedPostProcessors, beanFactory); invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory); // Next, invoke the BeanFactoryPostProcessors that implement Ordered. List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(); for (String postProcessorName : orderedPostProcessorNames) { orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class)); } sortPostProcessors(orderedPostProcessors, beanFactory); invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory); // Finally, invoke all other BeanFactoryPostProcessors. List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(); for (String postProcessorName : nonOrderedPostProcessorNames) { nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class)); } invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory); // Clear cached merged bean definitions since the post-processors might have // modified the original metadata, e.g. replacing placeholders in values... beanFactory.clearMetadataCache(); }
看起来代码挺多,其实很简单的逻辑。
BeanFactoryPostProcessor
集合,首先取出 BeanDefinitionRegistryPostProcessor
,并且执行接口方法,再放入registryProcessors容器中。 BeanDefinitionRegistryPostProcessor
类型的bean name 数组,遍历循环数据,判断是否有 PriorityOrdered
接口,加入容器中,并且根据接口重新排序后,遍历容器所有类,执行接口方法,加入registryProcessors容器中。 BeanDefinitionRegistryPostProcessor
类型的bean name 数组,循环遍历bean name 取出实现 Ordered
接口,按照 Orderd
顺序排序集合,依次执行接口方法,加入放入registryProcessors容器中. BeanFactoryPostProcessor
的接口方法。 BeanFactoryPostProcessor
也是按照上面的思路,先过滤排序执行接口方法。 看到这里我有一个疑问,这些接口对象怎么产生的?Spring 工厂并没有开始实例化对象,这时候Spring只进行到将xml转化成beanDefinition这个对象,不可能从Spring 工厂获取出来的。
实例化bean 的方法主要在 AbstractBeanFactory
中
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType, @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException { // 取出&提取对应beanName final String beanName = transformedBeanName(name); Object bean; // 在缓存中获取对象 Object sharedInstance = getSingleton(beanName); if (sharedInstance != null && args == null) { if (logger.isTraceEnabled()) { if (isSingletonCurrentlyInCreation(beanName)) { logger.trace("Returning eagerly cached instance of singleton bean '" + beanName + "' that is not fully initialized yet - a consequence of a circular reference"); } else { logger.trace("Returning cached instance of singleton bean '" + beanName + "'"); } } //判断缓存中对象是否是正确的bean实例化,如果是FactoryBean接口对象,调用接口方法获取到bean实例 bean = getObjectForBeanInstance(sharedInstance, name, beanName, null); } else { // 如果beanName 是prototpe或者scope类型,并且正在创建中,直接抛出异常 if (isPrototypeCurrentlyInCreation(beanName)) { throw new BeanCurrentlyInCreationException(beanName); } // 尝试在父容器获取 BeanFactory parentBeanFactory = getParentBeanFactory(); if (parentBeanFactory != null && !containsBeanDefinition(beanName)) { // 没有找到,尝试修改beanName名称,重新来过 String nameToLookup = originalBeanName(name); if (parentBeanFactory instanceof AbstractBeanFactory) { return ((AbstractBeanFactory) parentBeanFactory).doGetBean( nameToLookup, requiredType, args, typeCheckOnly); } else if (args != null) { // Delegation to parent with explicit args. return (T) parentBeanFactory.getBean(nameToLookup, args); } else if (requiredType != null) { // No args -> delegate to standard getBean method. return parentBeanFactory.getBean(nameToLookup, requiredType); } else { return (T) parentBeanFactory.getBean(nameToLookup); } } //如果只是做类型检查,不进行实例化,这将bean加入创建记录中 if (!typeCheckOnly) { markBeanAsCreated(beanName); } try { final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); //判断BeanDefinition 类型不是抽象类 checkMergedBeanDefinition(mbd, beanName, args); // 获取bean 元数据所有依赖bean 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); try { getBean(dep); //实例化创建依赖bean } catch (NoSuchBeanDefinitionException ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "'" + beanName + "' depends on missing bean '" + dep + "'", ex); } } } // 创建单例对象 if (mbd.isSingleton()) { sharedInstance = getSingleton(beanName, () -> { try { //具体创建bean方法,由子类 AbstractAutowireCapableBeanFactory实现 return createBean(beanName, mbd, args); } catch (BeansException ex) { destroySingleton(beanName); throw ex; } }); bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); } else if (mbd.isPrototype()) { // It's a prototype -> create a new instance. Object prototypeInstance = null; try { //添加创建记录 beforePrototypeCreation(beanName); prototypeInstance = createBean(beanName, mbd, args); } finally { //删除记录 afterPrototypeCreation(beanName); } bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd); } 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, () -> { beforePrototypeCreation(beanName); try { 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可能是String类型,但是需要转化成Integer类型 if (requiredType != null && !requiredType.isInstance(bean)) { try { //使用类型转化器 T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType); if (convertedBean == null) { throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass()); } return convertedBean; } catch (TypeMismatchException ex) { if (logger.isTraceEnabled()) { logger.trace("Failed to convert bean '" + name + "' to required type '" + ClassUtils.getQualifiedName(requiredType) + "'", ex); } throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass()); } } return (T) bean; }
这个就是Spring 创建bean具体流程,但是任然还有很多细节没有表达出来,看了这么多源码,都知道一个方法不可能放得下这么多逻辑的。以后有机会我入深入每个方法再具体讲解的。主要总结下Spring 创建bean整体路程。
注册所有 BeanPostProcessor
后置处理类,这里只是注册,不会执行任何接口方法。具体流程跟上面 BeanFactoryPostProcessor
非常相似。在 PostProcessorRegistrationDelegate
看下具体代码逻辑,注意与上面代码相似地方。
public static void registerBeanPostProcessors( ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) { //根据类型获取所有BeanPostProcessor beanName String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false); // 注册 BeanPostProcessorChecker 只是一个info 日志信息打印类 // 当一个bean 正在被BeanPostProcessor 创建时就会打印信息 // 这个bean不能是BeanPostProcessor类型 int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length; beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount)); // 使用PriorityOrdered 排序bean 执行顺序 List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>(); //MergedBeanDefinitionPostProcessor 接口容器 List<BeanPostProcessor> internalPostProcessors = new ArrayList<>(); //使用Ordered 接口排序bean 执行顺序 List<String> orderedPostProcessorNames = new ArrayList<>(); // 默认顺序排序 List<String> nonOrderedPostProcessorNames = new ArrayList<>(); 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); } } //首先注册PriorityOrdered 优先排序 sortPostProcessors(priorityOrderedPostProcessors, beanFactory); //只是注册处理器,不调用方法 registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors); // 接着注册Ordered 类型 优先排序 List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(); 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); // 注册所有常规 BeanPostProcessors. List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(); for (String ppName : nonOrderedPostProcessorNames) { BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class); nonOrderedPostProcessors.add(pp); if (pp instanceof MergedBeanDefinitionPostProcessor) { internalPostProcessors.add(pp); } } registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors); // 最后注册 MergedBeanDefinitionPostProcessor 类型 sortPostProcessors(internalPostProcessors, beanFactory); registerBeanPostProcessors(beanFactory, internalPostProcessors); // 注册ApplicationListener 后置处理器 // 添加到所有处理器链后面 beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext)); }
BeanPostProcessor
注册流程跟上面 BeanFactoryPostProcessor
非常相似啊。
BeanPostProcessor BeanPostProcessorChecker
初始化信息资源类,Spring内部国际化支持。逻辑非常简单,先判断容器内是否有 messageSource
,直接注册bean,否则Spring内部注册 DelegatingMessageSource
。代码我就不放出来了,有兴趣同学自行去查看。
初始化 ApplicationEventMulticaster
事件组播器,主要判断用户是否自定义了事件组播器,直接使用用户定义的组播器。如果没有用户自定义组播器,默认使用 SimpleApplicationEventMulticaster
,代码略...
初始化其他特殊bean,由子类自行实现。这里又是使用了模板方法设计模式,让使用者可以扩展新功能。
注册所有实现ApplicationListeners接口的监听器,添加到上面刚刚初始化组播器中。获取所有事件集合,发布到组播器中,组播器再广播到监听指定事件的监听器中。
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 (earlyEventsToProcess != null) { for (ApplicationEvent earlyEvent : earlyEventsToProcess) { getApplicationEventMulticaster().multicastEvent(earlyEvent); } } }
这个方法就是我们解析Spring IOC核心了,初始化所有Spring bean,看这么多代码,终于到了我们最想了解部分了,直接上代码
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) { // 初始化conversion service 用于类型转化 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)); } //如果没有后置处理器,默认就支持嵌入值解析器 // 例如PropertyPlaceholderConfigurer bean之前注册的任何一个 // 主要用于配置占位符解析 if (!beanFactory.hasEmbeddedValueResolver()) { beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal)); } // 在所有bean初始化之前初始化所有AOP 代理对象 String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false); for (String weaverAwareName : weaverAwareNames) { getBean(weaverAwareName); } // 取消临时类加载器,关闭类型查找 beanFactory.setTempClassLoader(null); //冻结所有beanDefinition 特性 beanFactory.freezeConfiguration(); // 初始化非延迟单例bean (创建所有bean) beanFactory.preInstantiateSingletons(); }
conversionService StringValueResolver
4.冻结所有bean元数据特性,不允许任何修改。
public void preInstantiateSingletons() throws BeansException { if (logger.isTraceEnabled()) { logger.trace("Pre-instantiating singletons in " + this); } // 遍历所有beanDefinitionNames,copy 到信息list中 List<String> beanNames = new ArrayList<>(this.beanDefinitionNames); // 实例化所有非延迟bean for (String beanName : beanNames) { RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName); if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) { if (isFactoryBean(beanName)) {// 判断FactoryBean 接口类型bean Object bean = getBean(FACTORY_BEAN_PREFIX + beanName); if (bean instanceof FactoryBean) { final FactoryBean<?> factory = (FactoryBean<?>) bean; boolean isEagerInit; if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) { isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit, getAccessControlContext()); } else { isEagerInit = (factory instanceof SmartFactoryBean && ((SmartFactoryBean<?>) factory).isEagerInit()); } if (isEagerInit) { getBean(beanName); } } } else { getBean(beanName); } } } // 执行bean中实现SmartInitializingSingleton接口,执行接口方法,用与单例bean 初始化成功后执行 for (String beanName : beanNames) { Object singletonInstance = getSingleton(beanName); if (singletonInstance instanceof SmartInitializingSingleton) { final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance; if (System.getSecurityManager() != null) { AccessController.doPrivileged((PrivilegedAction<Object>) () -> { smartSingleton.afterSingletonsInstantiated(); return null; }, getAccessControlContext()); } else { smartSingleton.afterSingletonsInstantiated(); } } } }
protected void finishRefresh() { // 清空容器中Resource缓存 clearResourceCaches(); // 初始化LifecycleProcessor,注册到Spring容器中 initLifecycleProcessor(); //调用上面刚刚注册LifecycleProcessor onRefresh方法 getLifecycleProcessor().onRefresh(); // 发布ApplicationContext 完成初始化事件 publishEvent(new ContextRefreshedEvent(this)); // 如果配置文件中存在spring.liveBeansView.mbeanDomain 初始化LiveBeansView 注册到容器中 LiveBeansView.registerApplicationContext(this); }
到这里说明Spring 创建bean过程差不多完成了,但是还有很多细节没有展示出来,因为篇幅实在太多了。可以看出我前面讲得还是比较详细的,到了后面简略一些方法解析,篇幅实在太长了。如果有哪里说错了,或者讲得不好,请指出来,大家一起学习讨论下。