obtainFreshBeanFactory方法实现代码如下:
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {// 1.刷新 BeanFactory --具体实现见AbstractRefreshableApplicationContextrefreshBeanFactory();// 2.返回刷新后的 BeanFactoryreturn getBeanFactory();}
1 refreshBeanFactory方法
/*** 刷新 BeanFactory*/@Overrideprotected final void refreshBeanFactory() throws BeansException {// 1.判断是否已经存在 BeanFactory,如果存在则先销毁、关闭该 BeanFactory// 注意,应用中 BeanFactory 本来就是可以多个的,这里可不是说应用全局是否有 BeanFactory,而是当前// ApplicationContext 是否有 BeanFactoryif (hasBeanFactory()) {destroyBeans(); //销毁所有 BeancloseBeanFactory();//关闭 BeanFactory}try {// 2.创建一个新的BeanFactoryDefaultListableBeanFactory beanFactory = createBeanFactory();beanFactory.setSerializationId(getId()); // 用于 BeanFactory 的序列化// 设置 BeanFactory 的两个配置属性:是否允许 Bean 覆盖、是否允许循环引用customizeBeanFactory(beanFactory);// 3.加载 bean 定义。loadBeanDefinitions(beanFactory); //AbstractXmlApplicationContext类中实现synchronized (this.beanFactoryMonitor) {this.beanFactory = beanFactory;}}catch (IOException ex) {throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);}}
1.1 判断beanFactory是否存在,若存在先销毁关闭
1.hasBeanFactory 判断beanFactory是否已存在,我们第一次启动时hasBeanFactory 应该是返回false
/** Synchronization monitor for the internal BeanFactory. */private final Object beanFactoryMonitor = new Object();/*** 判断beanFactory是否存在*/protected final boolean hasBeanFactory() {synchronized (this.beanFactoryMonitor) { //加锁return (this.beanFactory != null); //直接返回beanFactory 是否为null}}
2.destroyBeans销毁所有已创建bean,我们直接ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");启动容器是不会执行到该方法的,但是启动后调用context.refresh();会进入到条件中执行该方法。
/*** 销毁所有bean 前提条件:beanFactory存在*/protected void destroyBeans() {//getBeanFactory 在AbstractRefreshableApplicationContext中实现//destroySingletons 在DefaultListableBeanFactory中实现getBeanFactory().destroySingletons();}
//========================AbstractRefreshableApplicationContext > getBeanFactory===========/*** 获取beanFactory*/@Overridepublic final ConfigurableListableBeanFactory getBeanFactory() {synchronized (this.beanFactoryMonitor) {//加锁if (this.beanFactory == null) { //判断是否为null 为null则抛出异常throw new IllegalStateException("BeanFactory not initialized or already closed - " +"call 'refresh' before accessing beans via the ApplicationContext");}return this.beanFactory; //返回beanFactory}}
//========================DefaultListableBeanFactory > destroySingletons===========/*** DefaultListableBeanFactory--销毁bean*/@Overridepublic void destroySingletons() {super.destroySingletons(); //调用父类方法销毁Singletons的Bean//更新ManualSingletonNamesupdateManualSingletonNames(Set::clear, set -> !set.isEmpty());clearByTypeCache(); //清空ByType的缓存}
下面分析destroySingletons方法
2.1 super.destroySingletons()
/*** DefaultSingletonBeanRegistry:销毁所有单例bean*/public void destroySingletons() {if (logger.isTraceEnabled()) {logger.trace("Destroying singletons in " + this);}synchronized (this.singletonObjects) { //加锁this.singletonsCurrentlyInDestruction = true; //标记设置为true}String[] disposableBeanNames; //所有待销毁的beanNamesynchronized (this.disposableBeans) { //加锁//拿出disposableBeans中的所有key,放入disposableBeanNames数组中disposableBeanNames = StringUtils.toStringArray(this.disposableBeans.keySet()); }//遍历disposableBeanNames数组 调用destroySingleton方法销毁beanfor (int i = disposableBeanNames.length - 1; i >= 0; i--) {destroySingleton(disposableBeanNames[i]);}//清空以下几个集合this.containedBeanMap.clear();this.dependentBeanMap.clear();this.dependenciesForBeanMap.clear();clearSingletonCache();}/*** 调用clearSingletonCache方法清空单例的缓存*/protected void clearSingletonCache() {synchronized (this.singletonObjects) {this.singletonObjects.clear();this.singletonFactories.clear();this.earlySingletonObjects.clear();this.registeredSingletons.clear();this.singletonsCurrentlyInDestruction = false;}}
2.2 updateManualSingletonNames(Set::clear, set -> !set.isEmpty())
/*** 先判断manualSingletonNames是否为空,* 不为空则根据manualSingletonNames新建一个set,然后把这个set清空,然后在把manualSingletonNames指向这个set* @param action 一个消费型接口 这里是Set::clear 调用Set的clear方法* @param condition 一个断言型接口 这里是set -> !set.isEmpty() 判断set是否非空*/private void updateManualSingletonNames(Consumer<Set<String>> action, Predicate<Set<String>> condition) {if (hasBeanCreationStarted()) { //判断alreadyCreated是否非空synchronized (this.beanDefinitionMap) { //加锁if (condition.test(this.manualSingletonNames)) { //断言manualSingletonNames是否非空//根据manualSingletonNames新建一个LinkedHashSet updatedSingletonsSet<String> updatedSingletons = new LinkedHashSet<>(this.manualSingletonNames);action.accept(updatedSingletons); //对updatedSingletons进行消费 清空updatedSingletonsthis.manualSingletonNames = updatedSingletons;//将manualSingletonNames指向消费后的updatedSingletons 是一个空集合}}}else {//alreadyCreated为空if (condition.test(this.manualSingletonNames)) {//断言manualSingletonNames 如果manualSingletonNames非空action.accept(this.manualSingletonNames); //对manualSingletonNames进行消费 清空manualSingletonNames}}}
2.3 clearByTypeCache()
/*** 清空allBeanNamesByType与singletonBeanNamesByType两个集合*/private void clearByTypeCache() {this.allBeanNamesByType.clear();this.singletonBeanNamesByType.clear();}
3 closeBeanFactory 关闭 BeanFactory
/*** 关闭 BeanFactory*/@Overrideprotected final void closeBeanFactory() {synchronized (this.beanFactoryMonitor) { //加锁if (this.beanFactory != null) { //beanFactory非空this.beanFactory.setSerializationId(null); //清空集合序列化ID this.beanFactory = null; //置空beanFactory}}}
//==================================================================================/*** 设置集合序列化ID */public void setSerializationId(@Nullable String serializationId) {if (serializationId != null) { //serializationId非空serializableFactories.put(serializationId, new WeakReference<>(this)); //put}else if (this.serializationId != null) { //this.serializationId非空serializableFactories.remove(this.serializationId); //remove}this.serializationId = serializationId; //设置this.serializationId 为 serializationId}
1.1.2 创建一个新的BeanFactory并设置其属性
1.createBeanFactory创建BeanFactory
/*** 创建BeanFactory*/protected DefaultListableBeanFactory createBeanFactory() {return new DefaultListableBeanFactory(getInternalParentBeanFactory());}/*** 获取父BeanFactory */@Nullableprotected BeanFactory getInternalParentBeanFactory() {return (getParent() instanceof ConfigurableApplicationContext ?((ConfigurableApplicationContext) getParent()).getBeanFactory() : getParent());}
2.beanFactory.setSerializationId(getId()); // 用于 BeanFactory 的序列化
3.customizeBeanFactory设置 BeanFactory 的两个配置属性
/*** beanFactory配置*/protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {if (this.allowBeanDefinitionOverriding != null) {// 是否允许 Bean 定义覆盖beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);}if (this.allowCircularReferences != null) {// 是否允许 Bean 间的循环依赖beanFactory.setAllowCircularReferences(this.allowCircularReferences);}}
1.3 加载 bean 定义
/*** 加载 bean 定义*/@Overrideprotected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {// 1.为指定BeanFactory创建XmlBeanDefinitionReaderXmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);// 2.使用此上下文的资源加载环境配置 XmlBeanDefinitionReaderbeanDefinitionReader.setEnvironment(this.getEnvironment());// resourceLoader赋值为XmlWebApplicationContextbeanDefinitionReader.setResourceLoader(this);beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));// 初始化 BeanDefinitionReaderinitBeanDefinitionReader(beanDefinitionReader);// 3.加载 bean 定义loadBeanDefinitions(beanDefinitionReader);}
1.XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory)
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
//======================================================================public XmlBeanDefinitionReader(BeanDefinitionRegistry registry) {super(registry);}
//======================================================================protected AbstractBeanDefinitionReader(BeanDefinitionRegistry registry) {Assert.notNull(registry, "BeanDefinitionRegistry must not be null");this.registry = registry;// Determine ResourceLoader to use.if (this.registry instanceof ResourceLoader) {this.resourceLoader = (ResourceLoader) this.registry;}else {this.resourceLoader = new PathMatchingResourcePatternResolver();}// Inherit Environment if possibleif (this.registry instanceof EnvironmentCapable) {this.environment = ((EnvironmentCapable) this.registry).getEnvironment();}else {this.environment = new StandardEnvironment();}}
主要是初始化registry,resourceLoader和environment,我们这里new ClassPathXmlApplicationContext("spring.xml")启动容器的方式两个判断条件都会走到else里。
2.主要是对beanDefinitionReader进行各种配置
3.loadBeanDefinitions(beanDefinitionReader)加载 bean 定义,代码如下:
/*** 加载 bean 定义*/protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {//获取资源ResourceResource[] configResources = getConfigResources();if (configResources != null) {// 根据Resource加载 bean 定义reader.loadBeanDefinitions(configResources);}// 1.获取配置文件路径String[] configLocations = getConfigLocations();if (configLocations != null) {//2根据配置文件configLocations加载bean定义reader.loadBeanDefinitions(configLocations);}}/*** 这里直接返回null*/@Nullableprotected Resource[] getConfigResources() {return null;}@Nullableprotected String[] getConfigLocations() {return (this.configLocations != null ? this.configLocations : getDefaultConfigLocations());}
我们这里追一下reader.loadBeanDefinitions(String [] configLocations)的源码
/*** 根据配置文件路径加载*/@Overridepublic int loadBeanDefinitions(String... locations) throws BeanDefinitionStoreException {Assert.notNull(locations, "Location array must not be null"); //校验非nullint count = 0;for (String location : locations) { //遍历count += loadBeanDefinitions(location); //根据location加载bean定义}return count;}@Overridepublic int loadBeanDefinitions(String location) throws BeanDefinitionStoreException {return loadBeanDefinitions(location, null);}/*** 加载bean定义*/public int loadBeanDefinitions(String location, @Nullable Set<Resource> actualResources) throws BeanDefinitionStoreException {ResourceLoader resourceLoader = getResourceLoader(); //获取ResourceLoaderif (resourceLoader == null) {throw new BeanDefinitionStoreException("Cannot load bean definitions from location [" + location + "]: no ResourceLoader available");}if (resourceLoader instanceof ResourcePatternResolver) { //resourceLoader是否为ResourcePatternResolver类型try {//根据resourceLoader获取ResourceResource[] resources = ((ResourcePatternResolver) resourceLoader).getResources(location);int count = loadBeanDefinitions(resources); //调用loadBeanDefinitions(Resource[] resources)if (actualResources != null) {Collections.addAll(actualResources, resources); //将resources中数据添加到actualResources中}if (logger.isTraceEnabled()) {logger.trace("Loaded " + count + " bean definitions from location pattern [" + location + "]");}return count; //返回}catch (IOException ex) {throw new BeanDefinitionStoreException("Could not resolve bean definition resource pattern [" + location + "]", ex);}}else {Resource resource = resourceLoader.getResource(location); //获取Resourceint count = loadBeanDefinitions(resource); //加载bean定义if (actualResources != null) {actualResources.add(resource);//resource添加到actualResources中}if (logger.isTraceEnabled()) {logger.trace("Loaded " + count + " bean definitions from location [" + location + "]");}return count;//返回}}
这里我们发现会调用loadBeanDefinitions(resources);或loadBeanDefinitions(resource);参数是Resource类型或Resource[] 类型继续追源码
/*** 根据Resource加载bean定义*/@Overridepublic int loadBeanDefinitions(Resource... resources) throws BeanDefinitionStoreException {Assert.notNull(resources, "Resource array must not be null"); //null校验int count = 0;for (Resource resource : resources) { //遍历count += loadBeanDefinitions(resource); //根据resource加载bean定义}return count;}/*** 根据Resource加载bean定义*/@Overridepublic int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException {return loadBeanDefinitions(new EncodedResource(resource));}/*** 根据EncodedResource加载bean定义*/public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {Assert.notNull(encodedResource, "EncodedResource must not be null"); //null校验if (logger.isTraceEnabled()) {logger.trace("Loading XML bean definitions from " + encodedResource);}//从resourcesCurrentlyBeingLoaded中get数据Set<EncodedResource> currentResources = this.resourcesCurrentlyBeingLoaded.get();if (currentResources == null) {currentResources = new HashSet<>(4); //currentResources为空就初始化一个this.resourcesCurrentlyBeingLoaded.set(currentResources); //currentResources放入resourcesCurrentlyBeingLoaded中}if (!currentResources.add(encodedResource)) { //添加encodedResource 若添加失败 直接抛出异常throw new BeanDefinitionStoreException("Detected cyclic loading of " + encodedResource + " - check your import definitions!");}try {InputStream inputStream = encodedResource.getResource().getInputStream(); //获取输入流try {InputSource inputSource = new InputSource(inputStream); //包装成InputSourceif (encodedResource.getEncoding() != null) {inputSource.setEncoding(encodedResource.getEncoding()); //设置格式}return doLoadBeanDefinitions(inputSource, encodedResource.getResource());//加载操作}finally {inputStream.close();}}catch (IOException ex) {throw new BeanDefinitionStoreException("IOException parsing XML document from " + encodedResource.getResource(), ex);}finally {currentResources.remove(encodedResource);if (currentResources.isEmpty()) {this.resourcesCurrentlyBeingLoaded.remove();}}}/*** 加载bean定义*/protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)throws BeanDefinitionStoreException {try {Document doc = doLoadDocument(inputSource, resource); //转换成Document结构int count = registerBeanDefinitions(doc, resource); //加载数据if (logger.isDebugEnabled()) {logger.debug("Loaded " + count + " bean definitions from " + resource);}return count;}catch (BeanDefinitionStoreException ex) {throw ex;}catch (SAXParseException ex) {throw new XmlBeanDefinitionStoreException(resource.getDescription(),"Line " + ex.getLineNumber() + " in XML document from " + resource + " is invalid", ex);}catch (SAXException ex) {throw new XmlBeanDefinitionStoreException(resource.getDescription(),"XML document from " + resource + " is invalid", ex);}catch (ParserConfigurationException ex) {throw new BeanDefinitionStoreException(resource.getDescription(),"Parser configuration exception parsing XML from " + resource, ex);}catch (IOException ex) {throw new BeanDefinitionStoreException(resource.getDescription(),"IOException parsing XML document from " + resource, ex);}catch (Throwable ex) {throw new BeanDefinitionStoreException(resource.getDescription(),"Unexpected exception parsing XML document from " + resource, ex);}}
继续追溯源码吧
/*** 加载bean定义*/public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {//获取BeanDefinitionDocumentReaderBeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();//获取注册表中定义的bean的数目int countBefore = getRegistry().getBeanDefinitionCount();documentReader.registerBeanDefinitions(doc, createReaderContext(resource));return getRegistry().getBeanDefinitionCount() - countBefore; //计算成功加载数量}@Overridepublic void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {this.readerContext = readerContext;doRegisterBeanDefinitions(doc.getDocumentElement()); //加载操作}/*** 加载bean定义*/@SuppressWarnings("deprecation") // for Environment.acceptsProfiles(String...)protected void doRegisterBeanDefinitions(Element root) {BeanDefinitionParserDelegate parent = this.delegate;this.delegate = createDelegate(getReaderContext(), root, parent);if (this.delegate.isDefaultNamespace(root)) {String profileSpec = root.getAttribute(PROFILE_ATTRIBUTE);if (StringUtils.hasText(profileSpec)) {String[] specifiedProfiles = StringUtils.tokenizeToStringArray(profileSpec, BeanDefinitionParserDelegate.MULTI_VALUE_ATTRIBUTE_DELIMITERS);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;}}}preProcessXml(root); //空方法parseBeanDefinitions(root, this.delegate); //加载操作postProcessXml(root); //空方法this.delegate = parent;}/*** 加载操作*/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) { //子节点是ElementElement ele = (Element) node;if (delegate.isDefaultNamespace(ele)) {parseDefaultElement(ele, delegate); //默认的标签解析 根据节点类型不同进行不同操作}else {delegate.parseCustomElement(ele); //自定义标签的解析和注册}}}}else {delegate.parseCustomElement(root);//自定义标签的解析和注册}}/*** 根据节点类型不同进行不同操作*/private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {importBeanDefinitionResource(ele); //import节点处理}else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) {processAliasRegistration(ele); //alias节点处理}else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {processBeanDefinition(ele, delegate); //bean节点处理}else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) { //beans节点处理// recursedoRegisterBeanDefinitions(ele); //回调到doRegisterBeanDefinitions()处理bean节点}}
这里我们看一下bean节点的处理
/*** bean节点处理*/protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);if (bdHolder != null) {bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);try {// 注册bean定义BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());}catch (BeanDefinitionStoreException ex) {getReaderContext().error("Failed to register bean definition with name '" +bdHolder.getBeanName() + "'", ele, ex);}getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));}}/*** 注册bean*/public static void registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)throws BeanDefinitionStoreException {// Register bean definition under primary name.String beanName = definitionHolder.getBeanName();//registry注册器注册BeanDefinitionregistry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());// 别名注册String[] aliases = definitionHolder.getAliases();if (aliases != null) {for (String alias : aliases) {registry.registerAlias(beanName, alias);}}}
到这里,加载配置,生成bean定义就完成了让我们回到obtainFreshBeanFactory方法的:2.返回刷新后的 BeanFactory
2.getBeanFactory
这里没什么好说的,就是把第一步里创建的beanFactory返回
/*** 获取beanFactory*/@Overridepublic final ConfigurableListableBeanFactory getBeanFactory() {synchronized (this.beanFactoryMonitor) {//加锁if (this.beanFactory == null) { //判断是否为null 为null则抛出异常throw new IllegalStateException("BeanFactory not initialized or already closed - " +"call 'refresh' before accessing beans via the ApplicationContext");}return this.beanFactory; //返回beanFactory}}