spring源码解析之ioc-BeanDefinition的加载

BeanDefinition的加载

beanDefination的加载主要分为三种

1、基于xml配置文件的beanDefinition的加载

1、配置文件的读取

public static void main(String[] args) {
		创建ioc容器
        ApplicationContext context = new ClassPathXmlApplicationContext("classpath:app1.xml");
        Student student =(Student)context.getBean("mym");

        System.out.println(student.getTeacher().getId());
    }

在下面这一块来创建ioc容器

public ClassPathXmlApplicationContext(String configLocation) throws BeansException {
		继续往下看
        this(new String[]{configLocation}, true, (ApplicationContext)null);
    }

创建ioc容器

public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, @Nullable ApplicationContext parent) throws BeansException {
        super(parent);
        //加载配置文件  主要解析出配置文件的路径 放入在数组中保存  
        //这里有解析的规则,比如为什么需要classpath:开头等
        this.setConfigLocations(configLocations);
        if (refresh) {
        	//往下看
            this.refresh();
        }
    }

这一块是核心的几个方法 以后所有的解读都是围绕这一块去进行

public void refresh() throws BeansException, IllegalStateException {
        synchronized(this.startupShutdownMonitor) {
            this.prepareRefresh();
            ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
            this.prepareBeanFactory(beanFactory);

            try {
                this.postProcessBeanFactory(beanFactory);
                this.invokeBeanFactoryPostProcessors(beanFactory);
                this.registerBeanPostProcessors(beanFactory);
                this.initMessageSource();
                this.initApplicationEventMulticaster();
                this.onRefresh();
                this.registerListeners();
                this.finishBeanFactoryInitialization(beanFactory);
                this.finishRefresh();
            } catch (BeansException var9) {
                if (this.logger.isWarnEnabled()) {
                    this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
                }

                this.destroyBeans();
                this.cancelRefresh(var9);
                throw var9;
            } finally {
                this.resetCommonCaches();
            }
        }
    }

还是回到我们本章的重点 beanDefinition的加载

//创建beanFactory  以后所有的数据都会保存这里面  我们的ioc会持有一个beanFactory的引用
ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();

创建beanFactory

AbstractApplicationContext   319 line

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
		//继续往下看
        this.refreshBeanFactory();
        return this.getBeanFactory();
    }
AbstractRefreshableApplicationContext  39 line

protected final void refreshBeanFactory() throws BeansException {
        ......
        try {
            //这里我们可以看到 beanFactory的原貌
            DefaultListableBeanFactory beanFactory = this.createBeanFactory();
            beanFactory.setSerializationId(this.getId());
            //设置ioc中的bean是否允许bean的覆盖以及循环引用
            this.customizeBeanFactory(beanFactory);
            //加载beanDefination  这里是重点咯  继续往下看
            this.loadBeanDefinitions(beanFactory);
        ......
    }

加载beanDefinition

AbstractXmlApplicationContext  31 line

protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
		//xml的解析器  因为我们是解析xml文件,然后去加载bean的
        XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
        //设置各式各样的信息  属性  略过吧
        ......
        //加载beanDefination  继续往下看
        this.loadBeanDefinitions(beanDefinitionReader);
    }

根据路径获取资源流

protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
        ......
		//拿到路径  然后去加载资源流
        String[] configLocations = this.getConfigLocations();
        if (configLocations != null) {
        	//下面这一块 最终会将路径包装成资源数组(执行我注释起来的方法)
        	//然后走到上面的哪一块
        	//Resource[] resources = ((ResourcePatternResolver) resourceLoader).getResources(location);
            reader.loadBeanDefinitions(configLocations);
        }
    }

加载资源

AbstractBeanDefinitionReader  184 line
public int loadBeanDefinitions(Resource... resources) throws BeanDefinitionStoreException {
		int count = 0;
		for (Resource resource : resources) {
			//往下看
			count += loadBeanDefinitions(resource);
		}
		return count;
	}
XmlBeanDefinitionReader  320 line

public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
		......
		//获取流  设置编码
		try (InputStream inputStream = encodedResource.getResource().getInputStream()) {
			InputSource inputSource = new InputSource(inputStream);
			if (encodedResource.getEncoding() != null) {
				inputSource.setEncoding(encodedResource.getEncoding());
			}
			//流的处理  往下看
			return doLoadBeanDefinitions(inputSource, encodedResource.getResource());
		}
		......
	}

处理流

XmlBeanDefinitionReader  386  line

protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
			throws BeanDefinitionStoreException {

		try {
			//流的处理  最终会将xml解析成为一个doc  
			//至于解析就不是重点了 我们是看ioc流程  不是扣细节的  下面有doc的结果截图
			Document doc = doLoadDocument(inputSource, resource);
			//处理doc文档   继续往下看
			int count = registerBeanDefinitions(doc, resource);
			return count;
		}
		......
	}

spring源码解析之ioc-BeanDefinition的加载_第1张图片
处理doc文档

XmlBeanDifinitionReader  508 line

public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
		//doc的解析器
		BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
		//已经解析好的beanDefinition的数量  因为配置文件可多个 然后去循环一个一个解析
		int countBefore = getRegistry().getBeanDefinitionCount();
		//解析 doc  往下看
		documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
		//返回本次加载的beanDefinition的数量
		return getRegistry().getBeanDefinitionCount() - countBefore;
	}

DefaultBeanDefinitionDocumentReader  94 line
public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
		this.readerContext = readerContext;
		//注意看 这里获取了doc的结点   入参截图在下面 
		doRegisterBeanDefinitions(doc.getDocumentElement());
	}

spring源码解析之ioc-BeanDefinition的加载_第2张图片
由上我们可以看到 入参就是我们xml里面配置的beans结点咯

接着往下走

defaultBeanDefinitionDocumentReader 121 line

protected void doRegisterBeanDefinitions(Element root) {
		//由于beans里面也可以定义beans 
		//如果是内部的beans,那么如果他没定义某些信息,就会直接用外部的beans的
		//什么是某些信息  感兴趣可以去看看delegate的创建那块 里面有
		BeanDefinitionParserDelegate parent = this.delegate;
		this.delegate = createDelegate(getReaderContext(), root, parent);
		if (this.delegate.isDefaultNamespace(root)) {
			//拿到profile  我们都知道spring可设置激活环境 这一块判断是否需要加载这个结点
			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)) {
				    //环境没激活  直接返回  也就代表一个xml文件解析结束
					return;
				}
			}
		}
        //模板方法  需要的一些细节子类可以去实现
		preProcessXml(root);
		//解析beans标签
		parseBeanDefinitions(root, this.delegate);
		postProcessXml(root);

		this.delegate = parent;
	}

解析beans标签

DefaultBeanDefinitionDocumentReader 168 line

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)) {
					    //去解析  还是默认的几个标签  其他标签走esle  往下看
						parseDefaultElement(ele, delegate);
					}
					else {
						delegate.parseCustomElement(ele);
					}
				}
			}
		}
		else {
			delegate.parseCustomElement(root);
		}
	}

子标签的解析

defaultBeanDefinitionDocumentReader  189 line

private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
		//import标签的解析
		if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {
			importBeanDefinitionResource(ele);
		}
		//alias标签的解析
		else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) {
			processAliasRegistration(ele);
		}
		//bean标签的解析
		else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {
			//处理bean标签  往下看
			processBeanDefinition(ele, delegate);
		}
		//beans标签的解析
		else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {
			//这一块 最终还是会像我们解析外层beans一样的流程
			doRegisterBeanDefinitions(ele);
		}
	}

处理bean标签

defaultBeanDefinitionDocumentReader  305 line

protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
		//解析ele结点
		BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
		if (bdHolder != null) {
		    //装饰一些其他的必要的信息  略过吧
			bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
			try {
				//注册beanDefinition 
				BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
			}
			......
			getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
		}
	}

解析ele结点

BeanDefinitionParserDelegate  414 line

public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, @Nullable BeanDefinition containingBean) {
		//拿到bean标签中的name  id 值
		String id = ele.getAttribute(ID_ATTRIBUTE);
		String nameAttr = ele.getAttribute(NAME_ATTRIBUTE);
		//别名 配置时以,; 分割  注意 空格也是可以的
		List<String> aliases = new ArrayList<>();
		if (StringUtils.hasLength(nameAttr)) {
			String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, MULTI_VALUE_ATTRIBUTE_DELIMITERS);
			aliases.addAll(Arrays.asList(nameArr));
		}
		//将id设置为bean的名字
		String beanName = id;
		
		......
		
		//检验beanName是否已存在  内部用一个set来存放所有的beanName  也就是bean的id
		if (containingBean == null) {
			checkNameUniqueness(beanName, aliases, ele);
		}
		//创建BeanDefinition
		AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean);
		
		......
		
			String[] aliasesArray = StringUtils.toStringArray(aliases);
			//包装一下 
			return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray);
		}

		return null;
	}

终于来到了创建BeanDefinition

BeanDefinitionParserDelegate  414 line

public AbstractBeanDefinition parseBeanDefinitionElement(
			Element ele, String beanName, @Nullable BeanDefinition containingBean) {

		......

		try {
			//创建bd   GenericBeanDefinition
			AbstractBeanDefinition bd = createBeanDefinition(className, parent);
			//获取bean的singleton、scope、abstract、lazy-init、autowire、depends-on、
			//autowire-		candidate、primary、init-method、destroy-method、
			//factory-method、factory-bean属性的值,并存入GenericBeanDefinition对应的字段
			parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);
			//bean标签存在子标签 那么将其内容存储在bd中
			bd.setDescription(DomUtils.getChildElementValueByTagName(ele, DESCRIPTION_ELEMENT));
			//bean标签存在子标签 将其解析存储在bd中(bd中使用BeanMetadataAttribute存储)
			parseMetaElements(ele, bd);
			//bean标签存在子标签 将其解析存储 (MethodOverrides是bd的一个字段,
			//MethodOverrides内部维护一个CopyOnWriteArraySet,
			//CopyOnWriteArraySet中定义了存储类型为MethodOverride)
			parseLookupOverrideSubElements(ele, bd.getMethodOverrides());
			//bean标签存在子标签 将其解析存储 也是放在MethodOverrides
			parseReplacedMethodSubElements(ele, bd.getMethodOverrides());
			//bean标签存在子标签 解析存储在bd的ConstructorArgumentValues字段
			parseConstructorArgElements(ele, bd);
			//bean标签存在子标签 解析存储在bd的MutablePropertyValues字段
			parsePropertyElements(ele, bd);
			//bean标签存在子标签 解析存储在bd中的AutowireCandidateQualifier中的map中
			parseQualifierElements(ele, bd);
			bd.setResource(this.readerContext.getResource());
			bd.setSource(extractSource(ele));
			return bd;
		......

		return null;
	}

我们来分析property标签的解析
bean标签存在子标签 解析存储在bd的MutablePropertyValues字段
获取property标签的name 因为值是唯一的 多个property标签name相同直接抛异常
如果标签存在value字段,则使用TypedStringValue存储值
如果是ref,则使用RuntimeBeanReference存值
如果两个都存在,报错
如果存在子标签 则继续解析子标签 此时会根据标签类型去做对应的解析
我这一块是一个list 所以他会解析并封装 最后的结果如下图
spring源码解析之ioc-BeanDefinition的加载_第3张图片
ManagedList也就是我们常用的集合,它里面封装了我们集合中每一个索引指向的bean的名字
将上述存值的对象封装成PropertyValue存储在MutablePropertyValues中的List中

最后将创建的bd返回

接着就到注册beanDefinition

beanDefinitionReaderUtils  158 line

public static void registerBeanDefinition(
			BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
			throws BeanDefinitionStoreException {
		//拿到bean的名字
		String beanName = definitionHolder.getBeanName();
		//bean的注册
		registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
		String[] aliases = definitionHolder.getAliases();
		if (aliases != null) {
			for (String alias : aliases) {
				//有别名的话  绑定别名  别名是与beanName绑定的
				registry.registerAlias(beanName, alias);
			}
		}
	}

DefaultListableBeanFactory  926 line 

public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
			throws BeanDefinitionStoreException {
		......
		//根据beanName获取beanDefinition
		BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
		//已存在beanDefinition  判断是否可以覆盖
		if (existingDefinition != null) {
			if (!isAllowBeanDefinitionOverriding()) {
				throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);
			}
			
			......  覆盖bean的日志
			//进行beanDefinition的注册  其实是保存在beanDefinitionMap中
			this.beanDefinitionMap.put(beanName, beanDefinition);
		}
		else {
			//判断是否已经有其他bean开始初始化了
			if (hasBeanCreationStarted()) {
				//这一块没调试  我们走的是流程 不是抠细节 
				synchronized (this.beanDefinitionMap) {
					this.beanDefinitionMap.put(beanName, beanDefinition);
					List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);
					updatedDefinitions.addAll(this.beanDefinitionNames);
					updatedDefinitions.add(beanName);
					this.beanDefinitionNames = updatedDefinitions;
					removeManualSingletonName(beanName);
				}
			}
			else {
				//注册beanDefinition  也就是保存在map中
				this.beanDefinitionMap.put(beanName, beanDefinition);
				this.beanDefinitionNames.add(beanName);
				removeManualSingletonName(beanName);
			}
			this.frozenBeanDefinitionNames = null;
		}

		......
	}

至此,一个beanDefinition已经注册成功 后面都是循环去注册所有xml文件中定义的bean

再来看看我们走到了哪里

protected final void refreshBeanFactory() throws BeansException {
     ......
        try {
            DefaultListableBeanFactory beanFactory = this.createBeanFactory();
            beanFactory.setSerializationId(this.getId());
            this.customizeBeanFactory(beanFactory);
        	//加载beanDefinition
            this.loadBeanDefinitions(beanFactory);
            //然后将创建好的beanFacorty返回
            this.beanFactory = beanFactory;
        ...
    }

最后在返回到这里

ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();

到此 基于xml文件的BeanDefinition已经加载到了beanFactory中了

2、基于配置类的配置类的加载

还是从配置开始

public static void main(String[] args) {
		//创建ioc容器
        AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContext(MainConfig.class);
        Student student = app.getBean("student", Student.class);
        System.out.println(student.getTeacher().getName());
        app.close();
    }

创建ioc容器

public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
		//这个里面还是有非常丰富的内容  spring给我们注册了很多的beanDefinition,以供ioc正常运行
		//核心重点 创建了beanFacroty 
		//DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
        this();
        //加载配置类  也就是将配置类解析成beanDefinition
        this.register(componentClasses);
        //这一块就跟xml解析的哪一块一样的refresh  
        this.refresh();
    }

来看我们的重点 加载配置类

public void register(Class<?>... componentClasses) {
        //往下看
        this.reader.register(componentClasses);
    }
public void register(Class<?>... componentClasses) {
        Class[] var2 = componentClasses;
        int var3 = componentClasses.length;

        for(int var4 = 0; var4 < var3; ++var4) {
            Class<?> componentClass = var2[var4];
            //继续往下看
            this.registerBean(componentClass);
        }
    }
看这个名字我们也知道这是来注册  但不是注册bean!!!是注册beanDefinitation

private <T> void doRegisterBean(Class<T> beanClass, @Nullable String name, @Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier, @Nullable BeanDefinitionCustomizer[] customizers) {
		//人狠话不多  直接搞了一个beanDefinition
        AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
        //判断是不是需要跳过 也就是加载的配置类有没有@Condition 注解
        //confitional里面配置的类来确定标注了该注解的配置类是否生效 
        //不理解的可百度这个注解使用方式  就一目了然了
        if (!this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
            abd.setInstanceSupplier(supplier);
            //解析 abd的scope类型
            ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
            //设置abd为单例的  默认就是单例 如果有@Scope注解,则按照注解的来设置
            abd.setScope(scopeMetadata.getScopeName());
            //bean的名字
            String beanName = name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry);
            //解析bean的一些注解值  往后面看
            AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
            int var10;
            int var11;
            //qualifiers注解处理  我们这里为null   在注入其他bean的时候分析
            if (qualifiers != null) {
                Class[] var9 = qualifiers;
                var10 = qualifiers.length;

                for(var11 = 0; var11 < var10; ++var11) {
                    Class<? extends Annotation> qualifier = var9[var11];
                    if (Primary.class == qualifier) {
                        abd.setPrimary(true);
                    } else if (Lazy.class == qualifier) {
                        abd.setLazyInit(true);
                    } else {
                        abd.addQualifier(new AutowireCandidateQualifier(qualifier));
                    }
                }
            }
			//对bean的个性化处理  前提是bean实现了BeanDefinitionCustomizer接口  这个也很有用哦
            if (customizers != null) {
                BeanDefinitionCustomizer[] var13 = customizers;
                var10 = customizers.length;

                for(var11 = 0; var11 < var10; ++var11) {
                    BeanDefinitionCustomizer customizer = var13[var11];
                    customizer.customize(abd);
                }
            }

			//包装
            BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
            //一个简单的包装  但是这里不符合条件,也就是没包装  怎么包装?分析其他的bean的时候来看
            definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
            //注册beanDefinition  也就是将其放入map,并将别名与bean的名字绑定
            BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
        }
    }

解析设置bean的注解

static void processCommonDefinitionAnnotations(AnnotatedBeanDefinition abd, AnnotatedTypeMetadata metadata) {
		//解析@Lazy注解的值
        AnnotationAttributes lazy = attributesFor(metadata, Lazy.class);
        if (lazy != null) {
            abd.setLazyInit(lazy.getBoolean("value"));
        } else if (abd.getMetadata() != metadata) {
            lazy = attributesFor(abd.getMetadata(), (Class)Lazy.class);
            if (lazy != null) {
                abd.setLazyInit(lazy.getBoolean("value"));
            }
        }
		//解析设置@Primary注解的值
        if (metadata.isAnnotated(Primary.class.getName())) {
            abd.setPrimary(true);
        }
		//解析设置DependOn注解的值   这个注解之间的bean不能循环依赖!!!
		//也就是说  不能A标注这个注解,值是B   B也标注这个注解  值是A  这样直接报错
        AnnotationAttributes dependsOn = attributesFor(metadata, DependsOn.class);
        if (dependsOn != null) {
            abd.setDependsOn(dependsOn.getStringArray("value"));
        }
		//解析设置@Role注解   这个注解有啥用???
        AnnotationAttributes role = attributesFor(metadata, Role.class);
        if (role != null) {
            abd.setRole(role.getNumber("value").intValue());
        }
		//解析设置@Descript注解
        AnnotationAttributes description = attributesFor(metadata, Description.class);
        if (description != null) {
            abd.setDescription(description.getString("value"));
        }
    }

再来看看我们走到了哪里 没错 我们走到了refresh

public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
        this();
        //注册beanDifinition
        this.register(componentClasses);
        this.refresh();
    }

继续看refresh 没错哦 跟xml解析的那个refresh是一个方法

public void refresh() throws BeansException, IllegalStateException {
        synchronized(this.startupShutdownMonitor) {
            this.prepareRefresh();
            ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
            this.prepareBeanFactory(beanFactory);

            try {
                this.postProcessBeanFactory(beanFactory);
                this.invokeBeanFactoryPostProcessors(beanFactory);
                this.registerBeanPostProcessors(beanFactory);
                this.initMessageSource();
                this.initApplicationEventMulticaster();
                this.onRefresh();
                this.registerListeners();
                this.finishBeanFactoryInitialization(beanFactory);
                this.finishRefresh();
            } catch (BeansException var9) {
                if (this.logger.isWarnEnabled()) {
                    this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
                }

                this.destroyBeans();
                this.cancelRefresh(var9);
                throw var9;
            } finally {
                this.resetCommonCaches();
            }

        }
    }

对比一下 ,我们看下注解版是怎么获取beanFactory的,他在这其中又做了什么

//往下看
ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();

//继续往下看
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
        this.refreshBeanFactory();
        return this.getBeanFactory();
    }

GenericApplicationContext 95 line
protected final void refreshBeanFactory() throws IllegalStateException {
        if (!this.refreshed.compareAndSet(false, true)) {
            throw new IllegalStateException("GenericApplicationContext does not support multiple refresh attempts: just call 'refresh' once");
        } else {
        	//设置了id 
            this.beanFactory.setSerializationId(this.getId());
        }
    }

由上我们可以看到,注解版的beanFactory在这里只设置了id,然后就将其返回了
而xml版,在这里来解析xml文件,注册beanDefinition等信息

3、invokeBeanFactoryPostProcessors中加载beanDefinition

看后续的分析哦 这一块也是一个很大的内容点!!!

你可能感兴趣的:(spring源码解析之ioc-BeanDefinition的加载)