From 09a0615df03446147ceee24d6a48d6c9a11445fa Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Tue, 13 Sep 2016 21:49:24 +0200 Subject: [PATCH] Consistent callbacks for TypeFilters, ImportSelectors and ImportBeanDefinitionRegistrars Issue: SPR-14686 (cherry picked from commit 0c2e8a6) --- .../beans/factory/BeanFactory.java | 25 +++---- .../ComponentScanAnnotationParser.java | 43 ++---------- .../annotation/ConfigurationClassParser.java | 32 ++------- .../annotation/ParserStrategyUtils.java | 65 +++++++++++++++++++ 4 files changed, 91 insertions(+), 74 deletions(-) create mode 100644 spring-context/src/main/java/org/springframework/context/annotation/ParserStrategyUtils.java diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/BeanFactory.java b/spring-beans/src/main/java/org/springframework/beans/factory/BeanFactory.java index 49d235a6595..ba0d0b9db93 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/BeanFactory.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/BeanFactory.java @@ -67,24 +67,27 @@ import org.springframework.core.ResolvableType; * 1. BeanNameAware's {@code setBeanName}
* 2. BeanClassLoaderAware's {@code setBeanClassLoader}
* 3. BeanFactoryAware's {@code setBeanFactory}
- * 4. ResourceLoaderAware's {@code setResourceLoader} + * 4. EnvironmentAware's {@code setEnvironment} + * 5. EmbeddedValueResolverAware's {@code setEmbeddedValueResolver} + * 6. ResourceLoaderAware's {@code setResourceLoader} * (only applicable when running in an application context)
- * 5. ApplicationEventPublisherAware's {@code setApplicationEventPublisher} + * 7. ApplicationEventPublisherAware's {@code setApplicationEventPublisher} * (only applicable when running in an application context)
- * 6. MessageSourceAware's {@code setMessageSource} + * 8. MessageSourceAware's {@code setMessageSource} * (only applicable when running in an application context)
- * 7. ApplicationContextAware's {@code setApplicationContext} + * 9. ApplicationContextAware's {@code setApplicationContext} * (only applicable when running in an application context)
- * 8. ServletContextAware's {@code setServletContext} + * 10. ServletContextAware's {@code setServletContext} * (only applicable when running in a web application context)
- * 9. {@code postProcessBeforeInitialization} methods of BeanPostProcessors
- * 10. InitializingBean's {@code afterPropertiesSet}
- * 11. a custom init-method definition
- * 12. {@code postProcessAfterInitialization} methods of BeanPostProcessors + * 11. {@code postProcessBeforeInitialization} methods of BeanPostProcessors
+ * 12. InitializingBean's {@code afterPropertiesSet}
+ * 13. a custom init-method definition
+ * 14. {@code postProcessAfterInitialization} methods of BeanPostProcessors * *

On shutdown of a bean factory, the following lifecycle methods apply:
- * 1. DisposableBean's {@code destroy}
- * 2. a custom destroy-method definition + * 1. {@code postProcessBeforeDestruction} methods of DestructionAwareBeanPostProcessors + * 2. DisposableBean's {@code destroy}
+ * 3. a custom destroy-method definition * * @author Rod Johnson * @author Juergen Hoeller diff --git a/spring-context/src/main/java/org/springframework/context/annotation/ComponentScanAnnotationParser.java b/spring-context/src/main/java/org/springframework/context/annotation/ComponentScanAnnotationParser.java index 247c5838db7..6a8fba7b367 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/ComponentScanAnnotationParser.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/ComponentScanAnnotationParser.java @@ -25,17 +25,10 @@ import java.util.Set; import java.util.regex.Pattern; import org.springframework.beans.BeanUtils; -import org.springframework.beans.factory.Aware; -import org.springframework.beans.factory.BeanClassLoaderAware; -import org.springframework.beans.factory.BeanFactory; -import org.springframework.beans.factory.BeanFactoryAware; import org.springframework.beans.factory.config.BeanDefinitionHolder; -import org.springframework.beans.factory.config.ConfigurableBeanFactory; import org.springframework.beans.factory.support.BeanDefinitionRegistry; import org.springframework.beans.factory.support.BeanNameGenerator; import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.context.EnvironmentAware; -import org.springframework.context.ResourceLoaderAware; import org.springframework.core.annotation.AnnotationAttributes; import org.springframework.core.env.Environment; import org.springframework.core.io.ResourceLoader; @@ -61,16 +54,16 @@ import org.springframework.util.StringUtils; */ class ComponentScanAnnotationParser { - private final ResourceLoader resourceLoader; - private final Environment environment; - private final BeanDefinitionRegistry registry; + private final ResourceLoader resourceLoader; private final BeanNameGenerator beanNameGenerator; + private final BeanDefinitionRegistry registry; + - public ComponentScanAnnotationParser(ResourceLoader resourceLoader, Environment environment, + public ComponentScanAnnotationParser(Environment environment, ResourceLoader resourceLoader, BeanNameGenerator beanNameGenerator, BeanDefinitionRegistry registry) { this.resourceLoader = resourceLoader; @@ -90,7 +83,7 @@ class ComponentScanAnnotationParser { scanner.setResourceLoader(this.resourceLoader); Class generatorClass = componentScan.getClass("nameGenerator"); - boolean useInheritedGenerator = BeanNameGenerator.class == generatorClass; + boolean useInheritedGenerator = (BeanNameGenerator.class == generatorClass); scanner.setBeanNameGenerator(useInheritedGenerator ? this.beanNameGenerator : BeanUtils.instantiateClass(generatorClass)); @@ -164,7 +157,8 @@ class ComponentScanAnnotationParser { Assert.isAssignable(TypeFilter.class, filterClass, "An error occurred while processing a @ComponentScan CUSTOM type filter: "); TypeFilter filter = BeanUtils.instantiateClass(filterClass, TypeFilter.class); - invokeAwareMethods(filter); + ParserStrategyUtils.invokeAwareMethods( + filter, this.environment, this.resourceLoader, this.registry); typeFilters.add(filter); break; default: @@ -188,27 +182,4 @@ class ComponentScanAnnotationParser { return typeFilters; } - /** - * Invoke {@link ResourceLoaderAware}, {@link BeanClassLoaderAware} and - * {@link BeanFactoryAware} contracts if implemented by the given {@code filter}. - */ - private void invokeAwareMethods(TypeFilter filter) { - if (filter instanceof Aware) { - if (filter instanceof EnvironmentAware) { - ((EnvironmentAware) filter).setEnvironment(this.environment); - } - if (filter instanceof ResourceLoaderAware) { - ((ResourceLoaderAware) filter).setResourceLoader(this.resourceLoader); - } - if (filter instanceof BeanClassLoaderAware) { - ClassLoader classLoader = (this.registry instanceof ConfigurableBeanFactory ? - ((ConfigurableBeanFactory) this.registry).getBeanClassLoader() : - this.resourceLoader.getClassLoader()); - ((BeanClassLoaderAware) filter).setBeanClassLoader(classLoader); - } - if (filter instanceof BeanFactoryAware && this.registry instanceof BeanFactory) { - ((BeanFactoryAware) filter).setBeanFactory((BeanFactory) this.registry); - } - } - } } diff --git a/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassParser.java b/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassParser.java index 46d9863426a..c4c5483288d 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassParser.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassParser.java @@ -158,7 +158,7 @@ class ConfigurationClassParser { this.resourceLoader = resourceLoader; this.registry = registry; this.componentScanParser = new ComponentScanAnnotationParser( - resourceLoader, environment, componentScanBeanNameGenerator, registry); + environment, resourceLoader, componentScanBeanNameGenerator, registry); this.conditionEvaluator = new ConditionEvaluator(registry, environment, resourceLoader); } @@ -509,7 +509,8 @@ class ConfigurationClassParser { // Candidate class is an ImportSelector -> delegate to it to determine imports Class candidateClass = candidate.loadClass(); ImportSelector selector = BeanUtils.instantiateClass(candidateClass, ImportSelector.class); - invokeAwareMethods(selector); + ParserStrategyUtils.invokeAwareMethods( + selector, this.environment, this.resourceLoader, this.registry); if (this.deferredImportSelectors != null && selector instanceof DeferredImportSelector) { this.deferredImportSelectors.add( new DeferredImportSelectorHolder(configClass, (DeferredImportSelector) selector)); @@ -526,7 +527,8 @@ class ConfigurationClassParser { Class candidateClass = candidate.loadClass(); ImportBeanDefinitionRegistrar registrar = BeanUtils.instantiateClass(candidateClass, ImportBeanDefinitionRegistrar.class); - invokeAwareMethods(registrar); + ParserStrategyUtils.invokeAwareMethods( + registrar, this.environment, this.resourceLoader, this.registry); configClass.addImportBeanDefinitionRegistrar(registrar, currentSourceClass.getMetadata()); } else { @@ -565,30 +567,6 @@ class ConfigurationClassParser { return false; } - /** - * Invoke {@link ResourceLoaderAware}, {@link BeanClassLoaderAware} and - * {@link BeanFactoryAware} contracts if implemented by the given {@code bean}. - */ - private void invokeAwareMethods(Object importStrategyBean) { - if (importStrategyBean instanceof Aware) { - if (importStrategyBean instanceof EnvironmentAware) { - ((EnvironmentAware) importStrategyBean).setEnvironment(this.environment); - } - if (importStrategyBean instanceof ResourceLoaderAware) { - ((ResourceLoaderAware) importStrategyBean).setResourceLoader(this.resourceLoader); - } - if (importStrategyBean instanceof BeanClassLoaderAware) { - ClassLoader classLoader = (this.registry instanceof ConfigurableBeanFactory ? - ((ConfigurableBeanFactory) this.registry).getBeanClassLoader() : - this.resourceLoader.getClassLoader()); - ((BeanClassLoaderAware) importStrategyBean).setBeanClassLoader(classLoader); - } - if (importStrategyBean instanceof BeanFactoryAware && this.registry instanceof BeanFactory) { - ((BeanFactoryAware) importStrategyBean).setBeanFactory((BeanFactory) this.registry); - } - } - } - /** * Validate each {@link ConfigurationClass} object. diff --git a/spring-context/src/main/java/org/springframework/context/annotation/ParserStrategyUtils.java b/spring-context/src/main/java/org/springframework/context/annotation/ParserStrategyUtils.java new file mode 100644 index 00000000000..f1ced5158fd --- /dev/null +++ b/spring-context/src/main/java/org/springframework/context/annotation/ParserStrategyUtils.java @@ -0,0 +1,65 @@ +/* + * Copyright 2002-2016 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. + */ + +package org.springframework.context.annotation; + +import org.springframework.beans.factory.Aware; +import org.springframework.beans.factory.BeanClassLoaderAware; +import org.springframework.beans.factory.BeanFactory; +import org.springframework.beans.factory.BeanFactoryAware; +import org.springframework.beans.factory.config.ConfigurableBeanFactory; +import org.springframework.beans.factory.support.BeanDefinitionRegistry; +import org.springframework.context.EnvironmentAware; +import org.springframework.context.ResourceLoaderAware; +import org.springframework.core.env.Environment; +import org.springframework.core.io.ResourceLoader; + +/** + * Common delegate code for the handling of parser strategies, e.g. + * {@code TypeFilter}, {@code ImportSelector}, {@code ImportBeanDefinitionRegistrar} + * + * @author Juergen Hoeller + * @since 4.3.3 + */ +abstract class ParserStrategyUtils { + + /** + * Invoke {@link BeanClassLoaderAware}, {@link BeanFactoryAware}, + * {@link EnvironmentAware}, and {@link ResourceLoaderAware} contracts + * if implemented by the given object. + */ + public static void invokeAwareMethods(Object parserStrategyBean, Environment environment, + ResourceLoader resourceLoader, BeanDefinitionRegistry registry) { + + if (parserStrategyBean instanceof Aware) { + if (parserStrategyBean instanceof BeanClassLoaderAware) { + ClassLoader classLoader = (registry instanceof ConfigurableBeanFactory ? + ((ConfigurableBeanFactory) registry).getBeanClassLoader() : resourceLoader.getClassLoader()); + ((BeanClassLoaderAware) parserStrategyBean).setBeanClassLoader(classLoader); + } + if (parserStrategyBean instanceof BeanFactoryAware && registry instanceof BeanFactory) { + ((BeanFactoryAware) parserStrategyBean).setBeanFactory((BeanFactory) registry); + } + if (parserStrategyBean instanceof EnvironmentAware) { + ((EnvironmentAware) parserStrategyBean).setEnvironment(environment); + } + if (parserStrategyBean instanceof ResourceLoaderAware) { + ((ResourceLoaderAware) parserStrategyBean).setResourceLoader(resourceLoader); + } + } + } + +}