obtainFreshBeanFactory方法实现代码如下:
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
// 1.刷新 BeanFactory --具体实现见AbstractRefreshableApplicationContext
refreshBeanFactory();
// 2.返回刷新后的 BeanFactory
return getBeanFactory();
}
1 refreshBeanFactory方法
/**
* 刷新 BeanFactory
*/
@Override
protected final void refreshBeanFactory() throws BeansException {
// 1.判断是否已经存在 BeanFactory,如果存在则先销毁、关闭该 BeanFactory
// 注意,应用中 BeanFactory 本来就是可以多个的,这里可不是说应用全局是否有 BeanFactory,而是当前
// ApplicationContext 是否有 BeanFactory
if (hasBeanFactory()) {
destroyBeans(); //销毁所有 Bean
closeBeanFactory();//关闭 BeanFactory
}
try {
// 2.创建一个新的BeanFactory
DefaultListableBeanFactory 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
*/
@Override
public 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
*/
@Override
public void destroySingletons() {
super.destroySingletons(); //调用父类方法销毁Singletons的Bean
//更新ManualSingletonNames
updateManualSingletonNames(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; //所有待销毁的beanName
synchronized (this.disposableBeans) { //加锁
//拿出disposableBeans中的所有key,放入disposableBeanNames数组中
disposableBeanNames = StringUtils.toStringArray(this.disposableBeans.keySet());
}
//遍历disposableBeanNames数组 调用destroySingleton方法销毁bean
for (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 updatedSingletons
Set<String> updatedSingletons = new LinkedHashSet<>(this.manualSingletonNames);
action.accept(updatedSingletons); //对updatedSingletons进行消费 清空updatedSingletons
this.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
*/
@Override
protected 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
*/
@Nullable
protected 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 定义
*/
@Override
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
// 1.为指定BeanFactory创建XmlBeanDefinitionReader
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
// 2.使用此上下文的资源加载环境配置 XmlBeanDefinitionReader
beanDefinitionReader.setEnvironment(this.getEnvironment());
// resourceLoader赋值为XmlWebApplicationContext
beanDefinitionReader.setResourceLoader(this);
beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
// 初始化 BeanDefinitionReader
initBeanDefinitionReader(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 possible
if (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 {
//获取资源Resource
Resource[] configResources = getConfigResources();
if (configResources != null) {
// 根据Resource加载 bean 定义
reader.loadBeanDefinitions(configResources);
}
// 1.获取配置文件路径
String[] configLocations = getConfigLocations();
if (configLocations != null) {
//2根据配置文件configLocations加载bean定义
reader.loadBeanDefinitions(configLocations);
}
}
/**
* 这里直接返回null
*/
@Nullable
protected Resource[] getConfigResources() {
return null;
}
@Nullable
protected String[] getConfigLocations() {
return (this.configLocations != null ? this.configLocations : getDefaultConfigLocations());
}
我们这里追一下reader.loadBeanDefinitions(String [] configLocations)的源码
/**
* 根据配置文件路径加载
*/
@Override
public int loadBeanDefinitions(String... locations) throws BeanDefinitionStoreException {
Assert.notNull(locations, "Location array must not be null"); //校验非null
int count = 0;
for (String location : locations) { //遍历
count += loadBeanDefinitions(location); //根据location加载bean定义
}
return count;
}
@Override
public 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(); //获取ResourceLoader
if (resourceLoader == null) {
throw new BeanDefinitionStoreException(
"Cannot load bean definitions from location [" + location + "]: no ResourceLoader available");
}
if (resourceLoader instanceof ResourcePatternResolver) { //resourceLoader是否为ResourcePatternResolver类型
try {
//根据resourceLoader获取Resource
Resource[] 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); //获取Resource
int 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定义
*/
@Override
public 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定义
*/
@Override
public 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); //包装成InputSource
if (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 {
//获取BeanDefinitionDocumentReader
BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
//获取注册表中定义的bean的数目
int countBefore = getRegistry().getBeanDefinitionCount();
documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
return getRegistry().getBeanDefinitionCount() - countBefore; //计算成功加载数量
}
@Override
public 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) { //子节点是Element
Element 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节点处理
// recurse
doRegisterBeanDefinitions(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注册器注册BeanDefinition
registry.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
*/
@Override
public 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
}
}