去获取bean工厂
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 调用子类去刷新bean工厂
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
refreshBeanFactory();
return getBeanFactory();
}
refreshBeanFactory
首先去调用AbstractRefreshableApplicationContext下边的方法refreshBeanFactory(),次方法是一个抽象类的方法,来看下实现。
@Override
protected final void refreshBeanFactory() throws BeansException {
// beanFactory是不是存在
if (hasBeanFactory()) {
destroyBeans();
closeBeanFactory();
}
try {
// 创建beanFactory
DefaultListableBeanFactory beanFactory = createBeanFactory();
beanFactory.setSerializationId(getId());
// 配置beanFactory
customizeBeanFactory(beanFactory);
// 将bean的定义加载到context中
loadBeanDefinitions(beanFactory);
this.beanFactory = beanFactory;
}
catch (IOException ex) {
throw new ApplicationContextException("I/O error parsing bean definition source
for " + getDisplayName(), ex);
}
}
首先判断beanFactory是不是存在,存在就销毁掉。下一步去创建beanFactory.
1、createBeanFactory() 创建beanFactory
protected DefaultListableBeanFactory createBeanFactory() {
// 使用的是 DefaultListableBeanFactory,
// 初始化参数parent为null,不用管参数。
return new DefaultListableBeanFactory(getInternalParentBeanFactory());
}
2、customizeBeanFactory(beanFactory) 配置beanFactory
customizeBeanFactory为AbstractRefreshableApplicationContext下边的一个方法,为上下文的context配置beanFactory参数。
protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
if (this.allowBeanDefinitionOverriding != null) {
beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
}
if (this.allowCircularReferences != null) {
beanFactory.setAllowCircularReferences(this.allowCircularReferences);
}
}
该方法是交于context子类去实现的,如果子类的context实现了allowBeanDefinitionOverriding和allowCircularReferences参数,则设置给beanFactory。
3、loadBeanDefinitions(beanFactory)
loadBeanDefinitions方法为AbstractRefreshableApplicationContext下边的一个方法。目的是将bean的定义加载到context中。
以其中一个实现AbstractXmlApplicationContext为例。
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws
BeansException, IOException {
// 通过指定的beanFactory新建一个bean的定义类
XmlBeanDefinitionReader beanDefinitionReader = new
XmlBeanDefinitionReader(beanFactory);
// 使用一下配置,配置bean定义的reader
// 资源加载环境
beanDefinitionReader.setEnvironment(getEnvironment());
beanDefinitionReader.setResourceLoader(this);
beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
// 允许子类提供的reader进行初始化
// 然后继续加载实际上的bean定义
initBeanDefinitionReader(beanDefinitionReader);
loadBeanDefinitions(beanDefinitionReader);
}
loadbeanDefinitions(beanDefinitionReader)
重点看一下loadbeanDefinitions方法,进去方法看一下。
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);
}
}
其中究竟是走getConfigResources或者是使用getConfigLocations,根据最开始初始化时进行判断,以目前走的线路来看。
public ClassPathXmlApplicationContext(
String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
throws BeansException {
super(parent);
setConfigLocations(configLocations);
if (refresh) {
refresh();
}
}
初始化配置,设置的是configLocations,所以loadbeanDefinitions的方法走了getConfigLocations。
(setConfigLocations(configLocations)方法对AbstractRefreshableConfigApplicationContext类的configLocations初始化,后面调用getConfigLocations的时候,方法体中的configLocations的参数就是初始化类中初始化的configLocations)
protected String[] getConfigLocations() {
// this.configLocations 就是setConfigLocations(configLocations);
// 中的configLocations
return (this.configLocations != null ? this.configLocations :
getDefaultConfigLocations());
}
接下来看reader.loadBeanDefinitions这行代码。通过一个循环加载location
public int loadBeanDefinitions(String... locations) throws BeanDefinitionStoreException {
Assert.notNull(locations, "Location array must not be null");
int count = 0;
for (String location : locations) {
count += loadBeanDefinitions(location);
}
return count;
}
loadBeanDefinitions一直点进去
public int loadBeanDefinitions(String location, @Nullable Set<Resource>
actualResources)
throws BeanDefinitionStoreException {
// ResourceLoader 是在loadBeanDefinitions方法中
// beanDefinitionReader.setResourceLoader(this);进行的配置。this就是
// ClassPathXmlApplicationContext
ResourceLoader resourceLoader = getResourceLoader();
if (resourceLoader == null) {
throw new BeanDefinitionStoreException(
"Cannot load bean definitions from location [" + location + "]: no ResourceLoader available");
}
if (resourceLoader instanceof ResourcePatternResolver resourcePatternResolver) {
// Resource pattern matching available.
try {
// 获取resource
Resource[] resources = resourcePatternResolver.getResources(location);
// 解析资源,分析如下。
int count = loadBeanDefinitions(resources);
if (actualResources != null) {
Collections.addAll(actualResources, resources);
}
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 {
// Can only load single resources by absolute URL.
Resource resource = resourceLoader.getResource(location);
int count = loadBeanDefinitions(resource);
if (actualResources != null) {
actualResources.add(resource);
}
if (logger.isTraceEnabled()) {
logger.trace("Loaded " + count + " bean definitions from location [" + location + "]");
}
return count;
}
}
进入方法片段,getResourceLoader中的resource是ClassPathXmlApplicationContext 在(beanDefinitionReader.setResourceLoader(this))这行代码已给出。ClassPathXmlApplicationContext中最终继承了ResourcePatternResolver,所以没有走else,再获取到Resource[]的数组后,开始进行解析。调用loadBeanDefinitions()方法,dubug会发现,最终会走到XmlBeanDefinitionReader的loadBeanDefinitions(Resource resource)方法,然后会先制作Document对象,再调用registerBeanDefinitions方法
public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
// 创建对象,不用去看
BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
// getRegistry就是beanFactory
int countBefore = getRegistry().getBeanDefinitionCount();
// 进行注册beanDefinitions
documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
return getRegistry().getBeanDefinitionCount() - countBefore;
}
进入documentReader.registerBeanDefinitions进去看一下具体是怎么进行注册到beanDefinitionsMap的。
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;
}
可以看出,具体解析还在parseBeanDefinitions中进行。
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 ele) {
if (delegate.isDefaultNamespace(ele)) {
// 进行解析
parseDefaultElement(ele, delegate);
}
else {
delegate.parseCustomElement(ele);
}
}
}
}
else {
delegate.parseCustomElement(root);
}
}
首先会判断是否是默认空间。如果不是默认空间会去解析其他空间。咱们走默认空间。走到parseDefaultElement方法进行解析。那么哪些是默认空间呢-(Import、bean、alias)
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);
}
}
我得xml为bean,则进入到processBeanDefinition方法。
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele); // 封装了beanDefinition
if (bdHolder != null) {
bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
try {
// 注册最终的实例
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));
}
}
BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());的方法进行注册。
最终会看到一个this.beanDefinitionMap.put(beanName, beanDefinition);的操作,至此,beanDefinitions添加到了beanDefinitionMap中。
最终返回一个包含beanDefinitionMap的beanFactory