📄 abstractapplicationcontext.java
字号:
// Second, invoke all other BeanFactoryPostProcessors, one by one.
for (Iterator it = nonOrderedFactoryProcessorNames.iterator(); it.hasNext();) {
String factoryProcessorName = (String) it.next();
((BeanFactoryPostProcessor) getBean(factoryProcessorName)).postProcessBeanFactory(getBeanFactory());
}
}
/**
* Instantiate and invoke all registered BeanPostProcessor beans,
* respecting explicit order if given.
* <p>Must be called before any instantiation of application beans.
*/
private void registerBeanPostProcessors() throws BeansException {
// Register BeanPostProcessorChecker that logs an info message when
// a bean is created during BeanPostProcessor instantiation, i.e. when
// a bean is not eligible for getting processed by all BeanPostProcessors.
final int beanProcessorTargetCount = getBeanFactory().getBeanPostProcessorCount() + 1 +
getBeanNamesForType(BeanPostProcessor.class, true, false).length;
getBeanFactory().addBeanPostProcessor(new BeanPostProcessorChecker(beanProcessorTargetCount));
// Actually fetch and register the BeanPostProcessor beans.
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the bean post-processors apply to them!
Map beanProcessorMap = getBeansOfType(BeanPostProcessor.class, true, false);
List beanProcessors = new ArrayList(beanProcessorMap.values());
Collections.sort(beanProcessors, new OrderComparator());
for (Iterator it = beanProcessors.iterator(); it.hasNext();) {
getBeanFactory().addBeanPostProcessor((BeanPostProcessor) it.next());
}
}
/**
* Initialize the MessageSource.
* Use parent's if none defined in this context.
*/
private void initMessageSource() throws BeansException {
if (containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
this.messageSource = (MessageSource) getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
// Make MessageSource aware of parent MessageSource.
if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;
if (hms.getParentMessageSource() == null) {
// Only set parent context as parent MessageSource if no parent MessageSource
// registered already.
hms.setParentMessageSource(getInternalParentMessageSource());
}
}
if (logger.isInfoEnabled()) {
logger.info("Using MessageSource [" + this.messageSource + "]");
}
}
else {
// Use empty MessageSource to be able to accept getMessage calls.
DelegatingMessageSource dms = new DelegatingMessageSource();
dms.setParentMessageSource(getInternalParentMessageSource());
this.messageSource = dms;
if (logger.isInfoEnabled()) {
logger.info("Unable to locate MessageSource with name '" + MESSAGE_SOURCE_BEAN_NAME +
"': using default [" + this.messageSource + "]");
}
}
}
/**
* Initialize the ApplicationEventMulticaster.
* Uses SimpleApplicationEventMulticaster if none defined in the context.
* @see org.springframework.context.event.SimpleApplicationEventMulticaster
*/
private void initApplicationEventMulticaster() throws BeansException {
if (containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
this.applicationEventMulticaster = (ApplicationEventMulticaster)
getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
if (logger.isInfoEnabled()) {
logger.info("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
}
}
else {
this.applicationEventMulticaster = new SimpleApplicationEventMulticaster();
if (logger.isInfoEnabled()) {
logger.info("Unable to locate ApplicationEventMulticaster with name '" +
APPLICATION_EVENT_MULTICASTER_BEAN_NAME +
"': using default [" + this.applicationEventMulticaster + "]");
}
}
}
/**
* Template method which can be overridden to add context-specific refresh work.
* Called on initialization of special beans, before instantiation of singletons.
* @throws BeansException in case of errors during refresh
* @see #refresh
*/
protected void onRefresh() throws BeansException {
// For subclasses: do nothing by default.
}
/**
* Add beans that implement ApplicationListener as listeners.
* Doesn't affect other listeners, which can be added without being beans.
*/
private void registerListeners() throws BeansException {
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let post-processors apply to them!
Collection listeners = getBeansOfType(ApplicationListener.class, true, false).values();
for (Iterator it = listeners.iterator(); it.hasNext();) {
addListener((ApplicationListener) it.next());
}
}
/**
* Subclasses can invoke this method to register a listener.
* Any beans in the context that are listeners are automatically added.
* @param listener the listener to register
*/
protected void addListener(ApplicationListener listener) {
getApplicationEventMulticaster().addApplicationListener(listener);
}
/**
* Publishes a ContextClosedEvent and destroys the singletons
* in the bean factory of this application context.
* @see org.springframework.context.event.ContextClosedEvent
*/
public void close() {
if (logger.isInfoEnabled()) {
logger.info("Closing application context [" + getDisplayName() + "]");
}
try {
// Publish shutdown event.
publishEvent(new ContextClosedEvent(this));
}
finally {
// Destroy all cached singletons in this context, invoking
// DisposableBean.destroy and/or the specified "destroy-method".
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (beanFactory != null) {
beanFactory.destroySingletons();
}
}
}
/**
* DisposableBean callback for destruction of this instance.
* Only called when the ApplicationContext itself is running
* as a bean in another BeanFactory or ApplicationContext,
* which is rather unusual.
* <p>The <code>close</code> method is the native way to
* shut down an ApplicationContext.
* @see #close
* @see org.springframework.beans.factory.access.SingletonBeanFactoryLocator
*/
public void destroy() {
close();
}
//---------------------------------------------------------------------
// Implementation of BeanFactory interface
//---------------------------------------------------------------------
public Object getBean(String name) throws BeansException {
return getBeanFactory().getBean(name);
}
public Object getBean(String name, Class requiredType) throws BeansException {
return getBeanFactory().getBean(name, requiredType);
}
public boolean containsBean(String name) {
return getBeanFactory().containsBean(name);
}
public boolean isSingleton(String name) throws NoSuchBeanDefinitionException {
return getBeanFactory().isSingleton(name);
}
public Class getType(String name) throws NoSuchBeanDefinitionException {
return getBeanFactory().getType(name);
}
public String[] getAliases(String name) throws NoSuchBeanDefinitionException {
return getBeanFactory().getAliases(name);
}
//---------------------------------------------------------------------
// Implementation of ListableBeanFactory interface
//---------------------------------------------------------------------
public boolean containsBeanDefinition(String name) {
return getBeanFactory().containsBeanDefinition(name);
}
public int getBeanDefinitionCount() {
return getBeanFactory().getBeanDefinitionCount();
}
public String[] getBeanDefinitionNames() {
return getBeanFactory().getBeanDefinitionNames();
}
public String[] getBeanDefinitionNames(Class type) {
return getBeanFactory().getBeanDefinitionNames(type);
}
public String[] getBeanNamesForType(Class type) {
return getBeanFactory().getBeanNamesForType(type);
}
public String[] getBeanNamesForType(Class type, boolean includePrototypes, boolean includeFactoryBeans) {
return getBeanFactory().getBeanNamesForType(type, includePrototypes, includeFactoryBeans);
}
public Map getBeansOfType(Class type) throws BeansException {
return getBeanFactory().getBeansOfType(type);
}
public Map getBeansOfType(Class type, boolean includePrototypes, boolean includeFactoryBeans)
throws BeansException {
return getBeanFactory().getBeansOfType(type, includePrototypes, includeFactoryBeans);
}
//---------------------------------------------------------------------
// Implementation of HierarchicalBeanFactory interface
//---------------------------------------------------------------------
public BeanFactory getParentBeanFactory() {
return getParent();
}
public boolean containsLocalBean(String name) {
return getBeanFactory().containsLocalBean(name);
}
/**
* Return the internal bean factory of the parent context if it implements
* ConfigurableApplicationContext; else, return the parent context itself.
* @see org.springframework.context.ConfigurableApplicationContext#getBeanFactory
*/
protected BeanFactory getInternalParentBeanFactory() {
return (getParent() instanceof ConfigurableApplicationContext) ?
((ConfigurableApplicationContext) getParent()).getBeanFactory() : (BeanFactory) getParent();
}
//---------------------------------------------------------------------
// Implementation of MessageSource interface
//---------------------------------------------------------------------
public String getMessage(String code, Object args[], String defaultMessage, Locale locale) {
return getMessageSource().getMessage(code, args, defaultMessage, locale);
}
public String getMessage(String code, Object args[], Locale locale) throws NoSuchMessageException {
return getMessageSource().getMessage(code, args, locale);
}
public String getMessage(MessageSourceResolvable resolvable, Locale locale) throws NoSuchMessageException {
return getMessageSource().getMessage(resolvable, locale);
}
/**
* Return the internal MessageSource used by the context.
* @return the internal MessageSource (never <code>null</code>)
* @throws IllegalStateException if the context has not been initialized yet
*/
private MessageSource getMessageSource() throws IllegalStateException {
if (this.messageSource == null) {
throw new IllegalStateException("MessageSource not initialized - " +
"call 'refresh' before accessing messages via the context: " + this);
}
return this.messageSource;
}
/**
* Return the internal message source of the parent context if it is an
* AbstractApplicationContext too; else, return the parent context itself.
*/
protected MessageSource getInternalParentMessageSource() {
return (getParent() instanceof AbstractApplicationContext) ?
((AbstractApplicationContext) getParent()).messageSource : getParent();
}
//---------------------------------------------------------------------
// Implementation of ResourcePatternResolver interface
//---------------------------------------------------------------------
public Resource[] getResources(String locationPattern) throws IOException {
return this.resourcePatternResolver.getResources(locationPattern);
}
//---------------------------------------------------------------------
// Abstract methods that must be implemented by subclasses
//---------------------------------------------------------------------
/**
* Subclasses must implement this method to perform the actual configuration load.
* The method is invoked by refresh before any other initialization work.
* <p>A subclass will either create a new bean factory and hold a reference to it,
* or return a single bean factory instance that it holds. In the latter case, it will
* usually throw an IllegalStateException if refreshing the context more than once.
* @throws BeansException if initialization of the bean factory failed
* @throws IllegalStateException if already initialized and multiple refresh
* attempts are not supported
* @see #refresh
*/
protected abstract void refreshBeanFactory() throws BeansException, IllegalStateException;
/**
* Subclasses must return their internal bean factory here.
* They should implement the lookup efficiently, so that it can be called
* repeatedly without a performance penalty.
* @return this application context's internal bean factory
* @throws IllegalStateException if the context does not hold an internal
* bean factory yet (usually if <code>refresh</code> has never been called)
* @see #refresh
*/
public abstract ConfigurableListableBeanFactory getBeanFactory() throws IllegalStateException;
/**
* Return information about this context.
*/
public String toString() {
StringBuffer sb = new StringBuffer(getClass().getName());
sb.append(": ");
sb.append("display name [").append(this.displayName).append("]; ");
sb.append("startup date [").append(new Date(this.startupTime)).append("]; ");
if (this.parent == null) {
sb.append("root of context hierarchy");
}
else {
sb.append("child of [").append(this.parent).append(']');
}
return sb.toString();
}
/**
* BeanPostProcessor that logs an info message when a bean is created during
* BeanPostProcessor instantiation, i.e. when a bean is not eligible for
* getting processed by all BeanPostProcessors.
*/
private class BeanPostProcessorChecker implements BeanPostProcessor {
private final int beanPostProcessorTargetCount;
public BeanPostProcessorChecker(int beanPostProcessorTargetCount) {
this.beanPostProcessorTargetCount = beanPostProcessorTargetCount;
}
public Object postProcessBeforeInitialization(Object bean, String beanName) {
return bean;
}
public Object postProcessAfterInitialization(Object bean, String beanName) {
if (getBeanFactory().getBeanPostProcessorCount() < this.beanPostProcessorTargetCount) {
if (logger.isInfoEnabled()) {
logger.info("Bean '" + beanName + "' is not eligible for getting processed by all " +
"BeanPostProcessors (for example: not eligible for auto-proxying)");
}
}
return bean;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -