All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.springframework.context.support.AbstractRefreshableApplicationContext Maven / Gradle / Ivy

There is a newer version: 6.1.6
Show newest version
/*
 * Copyright 2002-2020 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.context.support;

import java.io.IOException;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextException;
import org.springframework.lang.Nullable;

/**
 * Base class for {@link org.springframework.context.ApplicationContext}
 * implementations which are supposed to support multiple calls to {@link #refresh()},
 * creating a new internal bean factory instance every time.
 * Typically (but not necessarily), such a context will be driven by
 * a set of config locations to load bean definitions from.
 *
 * 

The only method to be implemented by subclasses is {@link #loadBeanDefinitions}, * which gets invoked on each refresh. A concrete implementation is supposed to load * bean definitions into the given * {@link org.springframework.beans.factory.support.DefaultListableBeanFactory}, * typically delegating to one or more specific bean definition readers. * *

Note that there is a similar base class for WebApplicationContexts. * {@link org.springframework.web.context.support.AbstractRefreshableWebApplicationContext} * provides the same subclassing strategy, but additionally pre-implements * all context functionality for web environments. There is also a * pre-defined way to receive config locations for a web context. * *

Concrete standalone subclasses of this base class, reading in a * specific bean definition format, are {@link ClassPathXmlApplicationContext} * and {@link FileSystemXmlApplicationContext}, which both derive from the * common {@link AbstractXmlApplicationContext} base class; * {@link org.springframework.context.annotation.AnnotationConfigApplicationContext} * supports {@code @Configuration}-annotated classes as a source of bean definitions. * * @author Juergen Hoeller * @author Chris Beams * @since 1.1.3 * @see #loadBeanDefinitions * @see org.springframework.beans.factory.support.DefaultListableBeanFactory * @see org.springframework.web.context.support.AbstractRefreshableWebApplicationContext * @see AbstractXmlApplicationContext * @see ClassPathXmlApplicationContext * @see FileSystemXmlApplicationContext * @see org.springframework.context.annotation.AnnotationConfigApplicationContext */ public abstract class AbstractRefreshableApplicationContext extends AbstractApplicationContext { @Nullable private Boolean allowBeanDefinitionOverriding; @Nullable private Boolean allowCircularReferences; /** Bean factory for this context. */ @Nullable private volatile DefaultListableBeanFactory beanFactory; /** * Create a new AbstractRefreshableApplicationContext with no parent. */ public AbstractRefreshableApplicationContext() { } /** * Create a new AbstractRefreshableApplicationContext with the given parent context. * @param parent the parent context */ public AbstractRefreshableApplicationContext(@Nullable ApplicationContext parent) { super(parent); } /** * Set whether it should be allowed to override bean definitions by registering * a different definition with the same name, automatically replacing the former. * If not, an exception will be thrown. Default is "true". * @see org.springframework.beans.factory.support.DefaultListableBeanFactory#setAllowBeanDefinitionOverriding */ public void setAllowBeanDefinitionOverriding(boolean allowBeanDefinitionOverriding) { this.allowBeanDefinitionOverriding = allowBeanDefinitionOverriding; } /** * Set whether to allow circular references between beans - and automatically * try to resolve them. *

Default is "true". Turn this off to throw an exception when encountering * a circular reference, disallowing them completely. * @see org.springframework.beans.factory.support.DefaultListableBeanFactory#setAllowCircularReferences */ public void setAllowCircularReferences(boolean allowCircularReferences) { this.allowCircularReferences = allowCircularReferences; } /** * This implementation performs an actual refresh of this context's underlying * bean factory, shutting down the previous bean factory (if any) and * initializing a fresh bean factory for the next phase of the context's lifecycle. */ @Override protected final void refreshBeanFactory() throws BeansException { if (hasBeanFactory()) { destroyBeans(); closeBeanFactory(); } try { DefaultListableBeanFactory beanFactory = createBeanFactory(); beanFactory.setSerializationId(getId()); customizeBeanFactory(beanFactory); loadBeanDefinitions(beanFactory); this.beanFactory = beanFactory; } catch (IOException ex) { throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex); } } @Override protected void cancelRefresh(BeansException ex) { DefaultListableBeanFactory beanFactory = this.beanFactory; if (beanFactory != null) { beanFactory.setSerializationId(null); } super.cancelRefresh(ex); } @Override protected final void closeBeanFactory() { DefaultListableBeanFactory beanFactory = this.beanFactory; if (beanFactory != null) { beanFactory.setSerializationId(null); this.beanFactory = null; } } /** * Determine whether this context currently holds a bean factory, * i.e. has been refreshed at least once and not been closed yet. */ protected final boolean hasBeanFactory() { return (this.beanFactory != null); } @Override public final ConfigurableListableBeanFactory getBeanFactory() { DefaultListableBeanFactory beanFactory = this.beanFactory; if (beanFactory == null) { throw new IllegalStateException("BeanFactory not initialized or already closed - " + "call 'refresh' before accessing beans via the ApplicationContext"); } return beanFactory; } /** * Overridden to turn it into a no-op: With AbstractRefreshableApplicationContext, * {@link #getBeanFactory()} serves a strong assertion for an active context anyway. */ @Override protected void assertBeanFactoryActive() { } /** * Create an internal bean factory for this context. * Called for each {@link #refresh()} attempt. *

The default implementation creates a * {@link org.springframework.beans.factory.support.DefaultListableBeanFactory} * with the {@linkplain #getInternalParentBeanFactory() internal bean factory} of this * context's parent as parent bean factory. Can be overridden in subclasses, * for example to customize DefaultListableBeanFactory's settings. * @return the bean factory for this context * @see org.springframework.beans.factory.support.DefaultListableBeanFactory#setAllowBeanDefinitionOverriding * @see org.springframework.beans.factory.support.DefaultListableBeanFactory#setAllowEagerClassLoading * @see org.springframework.beans.factory.support.DefaultListableBeanFactory#setAllowCircularReferences * @see org.springframework.beans.factory.support.DefaultListableBeanFactory#setAllowRawInjectionDespiteWrapping */ protected DefaultListableBeanFactory createBeanFactory() { return new DefaultListableBeanFactory(getInternalParentBeanFactory()); } /** * Customize the internal bean factory used by this context. * Called for each {@link #refresh()} attempt. *

The default implementation applies this context's * {@linkplain #setAllowBeanDefinitionOverriding "allowBeanDefinitionOverriding"} * and {@linkplain #setAllowCircularReferences "allowCircularReferences"} settings, * if specified. Can be overridden in subclasses to customize any of * {@link DefaultListableBeanFactory}'s settings. * @param beanFactory the newly created bean factory for this context * @see DefaultListableBeanFactory#setAllowBeanDefinitionOverriding * @see DefaultListableBeanFactory#setAllowCircularReferences * @see DefaultListableBeanFactory#setAllowRawInjectionDespiteWrapping * @see DefaultListableBeanFactory#setAllowEagerClassLoading */ protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) { if (this.allowBeanDefinitionOverriding != null) { beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding); } if (this.allowCircularReferences != null) { beanFactory.setAllowCircularReferences(this.allowCircularReferences); } } /** * Load bean definitions into the given bean factory, typically through * delegating to one or more bean definition readers. * @param beanFactory the bean factory to load bean definitions into * @throws BeansException if parsing of the bean definitions failed * @throws IOException if loading of bean definition files failed * @see org.springframework.beans.factory.support.PropertiesBeanDefinitionReader * @see org.springframework.beans.factory.xml.XmlBeanDefinitionReader */ protected abstract void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException; }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy