diff --git a/org.springframework.context/src/main/java/org/springframework/context/support/AbstractApplicationContext.java b/org.springframework.context/src/main/java/org/springframework/context/support/AbstractApplicationContext.java index 6b150325d50..ef52fd34649 100644 --- a/org.springframework.context/src/main/java/org/springframework/context/support/AbstractApplicationContext.java +++ b/org.springframework.context/src/main/java/org/springframework/context/support/AbstractApplicationContext.java @@ -22,7 +22,9 @@ import java.security.AccessControlException; import java.util.ArrayList; import java.util.Collection; import java.util.Date; +import java.util.HashSet; import java.util.LinkedHashSet; +import java.util.LinkedList; import java.util.List; import java.util.Locale; import java.util.Map; @@ -571,22 +573,40 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader */ protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) { // Invoke BeanDefinitionRegistryPostProcessors first, if any. + Set processedBeans = new HashSet(); if (beanFactory instanceof BeanDefinitionRegistry) { BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory; - Collection registryPostProcessors = - beanFactory.getBeansOfType(BeanDefinitionRegistryPostProcessor.class, true, false).values(); - for (BeanDefinitionRegistryPostProcessor postProcessor : registryPostProcessors) { - postProcessor.postProcessBeanFactory(beanFactory); - } + List regularPostProcessors = new LinkedList(); + List registryPostProcessors = + new LinkedList(); for (BeanFactoryPostProcessor postProcessor : getBeanFactoryPostProcessors()) { if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) { - ((BeanDefinitionRegistryPostProcessor) postProcessor).postProcessBeanDefinitionRegistry(registry); + BeanDefinitionRegistryPostProcessor registryPostProcessor = + (BeanDefinitionRegistryPostProcessor) postProcessor; + registryPostProcessor.postProcessBeanDefinitionRegistry(registry); + registryPostProcessors.add(registryPostProcessor); + } + else { + regularPostProcessors.add(postProcessor); } } + Map beanMap = + beanFactory.getBeansOfType(BeanDefinitionRegistryPostProcessor.class, true, false); + List registryPostProcessorBeans = + new ArrayList(beanMap.values()); + OrderComparator.sort(registryPostProcessorBeans); + for (BeanDefinitionRegistryPostProcessor postProcessor : registryPostProcessorBeans) { + postProcessor.postProcessBeanDefinitionRegistry(registry); + } + invokeBeanFactoryPostProcessors(registryPostProcessors, beanFactory); + invokeBeanFactoryPostProcessors(registryPostProcessorBeans, beanFactory); + invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory); + processedBeans.addAll(beanMap.keySet()); + } + else { + // Invoke factory processors registered with the context instance. + invokeBeanFactoryPostProcessors(getBeanFactoryPostProcessors(), beanFactory); } - - // Invoke factory processors registered with the context instance. - invokeBeanFactoryPostProcessors(getBeanFactoryPostProcessors(), beanFactory); // Do not initialize FactoryBeans here: We need to leave all regular beans // uninitialized to let the bean factory post-processors apply to them! @@ -599,7 +619,10 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader List orderedPostProcessorNames = new ArrayList(); List nonOrderedPostProcessorNames = new ArrayList(); for (String ppName : postProcessorNames) { - if (isTypeMatch(ppName, PriorityOrdered.class)) { + if (processedBeans.contains(ppName)) { + // skip - already processed in first phase above + } + else if (isTypeMatch(ppName, PriorityOrdered.class)) { priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class)); } else if (isTypeMatch(ppName, Ordered.class)) { @@ -634,7 +657,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader * Invoke the given BeanFactoryPostProcessor beans. */ private void invokeBeanFactoryPostProcessors( - List postProcessors, ConfigurableListableBeanFactory beanFactory) { + Collection postProcessors, ConfigurableListableBeanFactory beanFactory) { for (BeanFactoryPostProcessor postProcessor : postProcessors) { postProcessor.postProcessBeanFactory(beanFactory); @@ -996,7 +1019,9 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader // Close the state of this context itself. closeBeanFactory(); + // Let subclasses do some final clean-up if they wish... onClose(); + synchronized (this.activeMonitor) { this.active = false; } diff --git a/org.springframework.context/src/test/java/org/springframework/context/annotation/configuration/Spr7167Tests.java b/org.springframework.context/src/test/java/org/springframework/context/annotation/configuration/Spr7167Tests.java index 11ec4af5814..99ac3619b60 100644 --- a/org.springframework.context/src/test/java/org/springframework/context/annotation/configuration/Spr7167Tests.java +++ b/org.springframework.context/src/test/java/org/springframework/context/annotation/configuration/Spr7167Tests.java @@ -1,10 +1,25 @@ -package org.springframework.context.annotation.configuration; +/* + * Copyright 2002-2010 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 + * + * http://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. + */ -import static org.hamcrest.CoreMatchers.equalTo; -import static org.junit.Assert.assertThat; -import static org.junit.Assert.assertTrue; +package org.springframework.context.annotation.configuration; +import static org.hamcrest.CoreMatchers.*; +import static org.junit.Assert.*; import org.junit.Test; + import org.springframework.aop.support.AopUtils; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanFactoryPostProcessor; @@ -55,4 +70,4 @@ class MyPostProcessor implements BeanFactoryPostProcessor { AbstractBeanDefinition bd = (AbstractBeanDefinition) beanFactory.getBeanDefinition("someDependency"); bd.setDescription("post processed by MyPostProcessor"); } -} \ No newline at end of file +}