Browse Source

Polishing

pull/1392/head
Juergen Hoeller 9 years ago
parent
commit
91df0653fe
  1. 6
      spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassBeanDefinitionReader.java
  2. 37
      spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassParser.java
  3. 32
      spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassPostProcessor.java
  4. 6
      spring-context/src/test/java/org/springframework/aop/framework/CglibProxyTests.java
  5. 3
      spring-context/src/test/resources/log4j2-test.xml
  6. 24
      spring-core/src/main/java/org/springframework/util/ClassUtils.java

6
spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassBeanDefinitionReader.java

@ -247,7 +247,8 @@ class ConfigurationClassBeanDefinitionReader {
BeanDefinition beanDefToRegister = beanDef; BeanDefinition beanDefToRegister = beanDef;
if (proxyMode != ScopedProxyMode.NO) { if (proxyMode != ScopedProxyMode.NO) {
BeanDefinitionHolder proxyDef = ScopedProxyCreator.createScopedProxy( BeanDefinitionHolder proxyDef = ScopedProxyCreator.createScopedProxy(
new BeanDefinitionHolder(beanDef, beanName), this.registry, proxyMode == ScopedProxyMode.TARGET_CLASS); new BeanDefinitionHolder(beanDef, beanName), this.registry,
proxyMode == ScopedProxyMode.TARGET_CLASS);
beanDefToRegister = new ConfigurationClassBeanDefinition( beanDefToRegister = new ConfigurationClassBeanDefinition(
(RootBeanDefinition) proxyDef.getBeanDefinition(), configClass, metadata); (RootBeanDefinition) proxyDef.getBeanDefinition(), configClass, metadata);
} }
@ -272,7 +273,8 @@ class ConfigurationClassBeanDefinitionReader {
// preserve the existing bean definition. // preserve the existing bean definition.
if (existingBeanDef instanceof ConfigurationClassBeanDefinition) { if (existingBeanDef instanceof ConfigurationClassBeanDefinition) {
ConfigurationClassBeanDefinition ccbd = (ConfigurationClassBeanDefinition) existingBeanDef; ConfigurationClassBeanDefinition ccbd = (ConfigurationClassBeanDefinition) existingBeanDef;
return (ccbd.getMetadata().getClassName().equals(beanMethod.getConfigurationClass().getMetadata().getClassName())); return ccbd.getMetadata().getClassName().equals(
beanMethod.getConfigurationClass().getMetadata().getClassName());
} }
// A bean definition resulting from a component scan can be silently overridden // A bean definition resulting from a component scan can be silently overridden

37
spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassParser.java

@ -232,7 +232,7 @@ class ConfigurationClassParser {
// Explicit bean definition found, probably replacing an import. // Explicit bean definition found, probably replacing an import.
// Let's remove the old one and go with the new one. // Let's remove the old one and go with the new one.
this.configurationClasses.remove(configClass); this.configurationClasses.remove(configClass);
for (Iterator<ConfigurationClass> it = this.knownSuperclasses.values().iterator(); it.hasNext(); ) { for (Iterator<ConfigurationClass> it = this.knownSuperclasses.values().iterator(); it.hasNext();) {
if (configClass.equals(it.next())) { if (configClass.equals(it.next())) {
it.remove(); it.remove();
} }
@ -258,13 +258,16 @@ class ConfigurationClassParser {
* @param sourceClass a source class * @param sourceClass a source class
* @return the superclass, or {@code null} if none found or previously processed * @return the superclass, or {@code null} if none found or previously processed
*/ */
protected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass) throws IOException { protected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass)
throws IOException {
// Recursively process any member (nested) classes first // Recursively process any member (nested) classes first
processMemberClasses(configClass, sourceClass); processMemberClasses(configClass, sourceClass);
// Process any @PropertySource annotations // Process any @PropertySource annotations
for (AnnotationAttributes propertySource : AnnotationConfigUtils.attributesForRepeatable( for (AnnotationAttributes propertySource : AnnotationConfigUtils.attributesForRepeatable(
sourceClass.getMetadata(), PropertySources.class, org.springframework.context.annotation.PropertySource.class)) { sourceClass.getMetadata(), PropertySources.class,
org.springframework.context.annotation.PropertySource.class)) {
if (this.environment instanceof ConfigurableEnvironment) { if (this.environment instanceof ConfigurableEnvironment) {
processPropertySource(propertySource); processPropertySource(propertySource);
} }
@ -277,14 +280,16 @@ class ConfigurationClassParser {
// Process any @ComponentScan annotations // Process any @ComponentScan annotations
Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable( Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(
sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class); sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);
if (!componentScans.isEmpty() && !this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) { if (!componentScans.isEmpty() &&
!this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) {
for (AnnotationAttributes componentScan : componentScans) { for (AnnotationAttributes componentScan : componentScans) {
// The config class is annotated with @ComponentScan -> perform the scan immediately // The config class is annotated with @ComponentScan -> perform the scan immediately
Set<BeanDefinitionHolder> scannedBeanDefinitions = Set<BeanDefinitionHolder> scannedBeanDefinitions =
this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName()); this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());
// Check the set of scanned definitions for any further config classes and parse recursively if necessary // Check the set of scanned definitions for any further config classes and parse recursively if needed
for (BeanDefinitionHolder holder : scannedBeanDefinitions) { for (BeanDefinitionHolder holder : scannedBeanDefinitions) {
if (ConfigurationClassUtils.checkConfigurationClassCandidate(holder.getBeanDefinition(), this.metadataReaderFactory)) { if (ConfigurationClassUtils.checkConfigurationClassCandidate(
holder.getBeanDefinition(), this.metadataReaderFactory)) {
parse(holder.getBeanDefinition().getBeanClassName(), holder.getBeanName()); parse(holder.getBeanDefinition().getBeanClassName(), holder.getBeanName());
} }
} }
@ -514,7 +519,9 @@ class ConfigurationClassParser {
* @param visited used to track visited classes to prevent infinite recursion * @param visited used to track visited classes to prevent infinite recursion
* @throws IOException if there is any problem reading metadata from the named class * @throws IOException if there is any problem reading metadata from the named class
*/ */
private void collectImports(SourceClass sourceClass, Set<SourceClass> imports, Set<SourceClass> visited) throws IOException { private void collectImports(SourceClass sourceClass, Set<SourceClass> imports, Set<SourceClass> visited)
throws IOException {
if (visited.add(sourceClass)) { if (visited.add(sourceClass)) {
for (SourceClass annotation : sourceClass.getAnnotations()) { for (SourceClass annotation : sourceClass.getAnnotations()) {
String annName = annotation.getMetadata().getClassName(); String annName = annotation.getMetadata().getClassName();
@ -541,7 +548,8 @@ class ConfigurationClassParser {
throw ex; throw ex;
} }
catch (Throwable ex) { catch (Throwable ex) {
throw new BeanDefinitionStoreException("Failed to process import candidates for configuration class [" + throw new BeanDefinitionStoreException(
"Failed to process import candidates for configuration class [" +
configClass.getMetadata().getClassName() + "]", ex); configClass.getMetadata().getClassName() + "]", ex);
} }
} }
@ -600,7 +608,8 @@ class ConfigurationClassParser {
throw ex; throw ex;
} }
catch (Throwable ex) { catch (Throwable ex) {
throw new BeanDefinitionStoreException("Failed to process import candidates for configuration class [" + throw new BeanDefinitionStoreException(
"Failed to process import candidates for configuration class [" +
configClass.getMetadata().getClassName() + "]", ex); configClass.getMetadata().getClassName() + "]", ex);
} }
finally { finally {
@ -739,9 +748,9 @@ class ConfigurationClassParser {
private final DeferredImportSelector importSelector; private final DeferredImportSelector importSelector;
public DeferredImportSelectorHolder(ConfigurationClass configurationClass, DeferredImportSelector importSelector) { public DeferredImportSelectorHolder(ConfigurationClass configClass, DeferredImportSelector selector) {
this.configurationClass = configurationClass; this.configurationClass = configClass;
this.importSelector = importSelector; this.importSelector = selector;
} }
public ConfigurationClass getConfigurationClass() { public ConfigurationClass getConfigurationClass() {
@ -881,8 +890,8 @@ class ConfigurationClassParser {
return result; return result;
} }
public Collection<SourceClass> getAnnotationAttributes(String annotationType, String attribute) throws IOException { public Collection<SourceClass> getAnnotationAttributes(String annType, String attribute) throws IOException {
Map<String, Object> annotationAttributes = this.metadata.getAnnotationAttributes(annotationType, true); Map<String, Object> annotationAttributes = this.metadata.getAnnotationAttributes(annType, true);
if (annotationAttributes == null || !annotationAttributes.containsKey(attribute)) { if (annotationAttributes == null || !annotationAttributes.containsKey(attribute)) {
return Collections.emptySet(); return Collections.emptySet();
} }

32
spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassPostProcessor.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2016 the original author or authors. * Copyright 2002-2017 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -287,11 +287,11 @@ public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPo
}); });
// Detect any custom bean name generation strategy supplied through the enclosing application context // Detect any custom bean name generation strategy supplied through the enclosing application context
SingletonBeanRegistry singletonRegistry = null; SingletonBeanRegistry sbr = null;
if (registry instanceof SingletonBeanRegistry) { if (registry instanceof SingletonBeanRegistry) {
singletonRegistry = (SingletonBeanRegistry) registry; sbr = (SingletonBeanRegistry) registry;
if (!this.localBeanNameGeneratorSet && singletonRegistry.containsSingleton(CONFIGURATION_BEAN_NAME_GENERATOR)) { if (!this.localBeanNameGeneratorSet && sbr.containsSingleton(CONFIGURATION_BEAN_NAME_GENERATOR)) {
BeanNameGenerator generator = (BeanNameGenerator) singletonRegistry.getSingleton(CONFIGURATION_BEAN_NAME_GENERATOR); BeanNameGenerator generator = (BeanNameGenerator) sbr.getSingleton(CONFIGURATION_BEAN_NAME_GENERATOR);
this.componentScanBeanNameGenerator = generator; this.componentScanBeanNameGenerator = generator;
this.importBeanNameGenerator = generator; this.importBeanNameGenerator = generator;
} }
@ -330,10 +330,10 @@ public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPo
} }
for (String candidateName : newCandidateNames) { for (String candidateName : newCandidateNames) {
if (!oldCandidateNames.contains(candidateName)) { if (!oldCandidateNames.contains(candidateName)) {
BeanDefinition beanDef = registry.getBeanDefinition(candidateName); BeanDefinition bd = registry.getBeanDefinition(candidateName);
if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory) && if (ConfigurationClassUtils.checkConfigurationClassCandidate(bd, this.metadataReaderFactory) &&
!alreadyParsedClasses.contains(beanDef.getBeanClassName())) { !alreadyParsedClasses.contains(bd.getBeanClassName())) {
candidates.add(new BeanDefinitionHolder(beanDef, candidateName)); candidates.add(new BeanDefinitionHolder(bd, candidateName));
} }
} }
} }
@ -343,9 +343,9 @@ public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPo
while (!candidates.isEmpty()); while (!candidates.isEmpty());
// Register the ImportRegistry as a bean in order to support ImportAware @Configuration classes // Register the ImportRegistry as a bean in order to support ImportAware @Configuration classes
if (singletonRegistry != null) { if (sbr != null) {
if (!singletonRegistry.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) { if (!sbr.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) {
singletonRegistry.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry()); sbr.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry());
} }
} }
@ -417,7 +417,9 @@ public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPo
} }
@Override @Override
public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) { public PropertyValues postProcessPropertyValues(
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) {
// Inject the BeanFactory before AutowiredAnnotationBeanPostProcessor's // Inject the BeanFactory before AutowiredAnnotationBeanPostProcessor's
// postProcessPropertyValues method attempts to autowire other configuration beans. // postProcessPropertyValues method attempts to autowire other configuration beans.
if (bean instanceof EnhancedConfiguration) { if (bean instanceof EnhancedConfiguration) {
@ -429,8 +431,8 @@ public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPo
@Override @Override
public Object postProcessBeforeInitialization(Object bean, String beanName) { public Object postProcessBeforeInitialization(Object bean, String beanName) {
if (bean instanceof ImportAware) { if (bean instanceof ImportAware) {
ImportRegistry importRegistry = this.beanFactory.getBean(IMPORT_REGISTRY_BEAN_NAME, ImportRegistry.class); ImportRegistry ir = this.beanFactory.getBean(IMPORT_REGISTRY_BEAN_NAME, ImportRegistry.class);
AnnotationMetadata importingClass = importRegistry.getImportingClassFor(bean.getClass().getSuperclass().getName()); AnnotationMetadata importingClass = ir.getImportingClassFor(bean.getClass().getSuperclass().getName());
if (importingClass != null) { if (importingClass != null) {
((ImportAware) bean).setImportMetadata(importingClass); ((ImportAware) bean).setImportMetadata(importingClass);
} }

6
spring-context/src/test/java/org/springframework/aop/framework/CglibProxyTests.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2016 the original author or authors. * Copyright 2002-2017 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -270,9 +270,7 @@ public class CglibProxyTests extends AbstractAopProxyTests implements Serializab
aop.setConstructorArguments(new Object[] {"Rob Harrop", 22}, new Class<?>[] {String.class, int.class}); aop.setConstructorArguments(new Object[] {"Rob Harrop", 22}, new Class<?>[] {String.class, int.class});
NoArgCtorTestBean proxy = (NoArgCtorTestBean) aop.getProxy(); NoArgCtorTestBean proxy = (NoArgCtorTestBean) aop.getProxy();
proxy = (NoArgCtorTestBean) aop.getProxy(); assertNotNull(proxy);
assertNotNull("Proxy should be null", proxy);
} }
@Test @Test

3
spring-context/src/test/resources/log4j2-test.xml

@ -6,6 +6,9 @@
</Console> </Console>
</Appenders> </Appenders>
<Loggers> <Loggers>
<Logger name="org.springframework.aop" level="warn" />
<Logger name="org.springframework.beans" level="warn" />
<Logger name="org.springframework.context" level="warn" />
<Logger name="org.springframework.core" level="warn" /> <Logger name="org.springframework.core" level="warn" />
<Root level="error"> <Root level="error">
<AppenderRef ref="Console" /> <AppenderRef ref="Console" />

24
spring-core/src/main/java/org/springframework/util/ClassUtils.java

@ -1053,10 +1053,10 @@ public abstract class ClassUtils {
} }
/** /**
* Return all interfaces that the given instance implements as array, * Return all interfaces that the given instance implements as an array,
* including ones implemented by superclasses. * including ones implemented by superclasses.
* @param instance the instance to analyze for interfaces * @param instance the instance to analyze for interfaces
* @return all interfaces that the given instance implements as array * @return all interfaces that the given instance implements as an array
*/ */
public static Class<?>[] getAllInterfaces(Object instance) { public static Class<?>[] getAllInterfaces(Object instance) {
Assert.notNull(instance, "Instance must not be null"); Assert.notNull(instance, "Instance must not be null");
@ -1064,24 +1064,24 @@ public abstract class ClassUtils {
} }
/** /**
* Return all interfaces that the given class implements as array, * Return all interfaces that the given class implements as an array,
* including ones implemented by superclasses. * including ones implemented by superclasses.
* <p>If the class itself is an interface, it gets returned as sole interface. * <p>If the class itself is an interface, it gets returned as sole interface.
* @param clazz the class to analyze for interfaces * @param clazz the class to analyze for interfaces
* @return all interfaces that the given object implements as array * @return all interfaces that the given object implements as an array
*/ */
public static Class<?>[] getAllInterfacesForClass(Class<?> clazz) { public static Class<?>[] getAllInterfacesForClass(Class<?> clazz) {
return getAllInterfacesForClass(clazz, null); return getAllInterfacesForClass(clazz, null);
} }
/** /**
* Return all interfaces that the given class implements as array, * Return all interfaces that the given class implements as an array,
* including ones implemented by superclasses. * including ones implemented by superclasses.
* <p>If the class itself is an interface, it gets returned as sole interface. * <p>If the class itself is an interface, it gets returned as sole interface.
* @param clazz the class to analyze for interfaces * @param clazz the class to analyze for interfaces
* @param classLoader the ClassLoader that the interfaces need to be visible in * @param classLoader the ClassLoader that the interfaces need to be visible in
* (may be {@code null} when accepting all declared interfaces) * (may be {@code null} when accepting all declared interfaces)
* @return all interfaces that the given object implements as array * @return all interfaces that the given object implements as an array
*/ */
public static Class<?>[] getAllInterfacesForClass(Class<?> clazz, ClassLoader classLoader) { public static Class<?>[] getAllInterfacesForClass(Class<?> clazz, ClassLoader classLoader) {
Set<Class<?>> ifcs = getAllInterfacesForClassAsSet(clazz, classLoader); Set<Class<?>> ifcs = getAllInterfacesForClassAsSet(clazz, classLoader);
@ -1089,10 +1089,10 @@ public abstract class ClassUtils {
} }
/** /**
* Return all interfaces that the given instance implements as Set, * Return all interfaces that the given instance implements as a Set,
* including ones implemented by superclasses. * including ones implemented by superclasses.
* @param instance the instance to analyze for interfaces * @param instance the instance to analyze for interfaces
* @return all interfaces that the given instance implements as Set * @return all interfaces that the given instance implements as a Set
*/ */
public static Set<Class<?>> getAllInterfacesAsSet(Object instance) { public static Set<Class<?>> getAllInterfacesAsSet(Object instance) {
Assert.notNull(instance, "Instance must not be null"); Assert.notNull(instance, "Instance must not be null");
@ -1100,24 +1100,24 @@ public abstract class ClassUtils {
} }
/** /**
* Return all interfaces that the given class implements as Set, * Return all interfaces that the given class implements as a Set,
* including ones implemented by superclasses. * including ones implemented by superclasses.
* <p>If the class itself is an interface, it gets returned as sole interface. * <p>If the class itself is an interface, it gets returned as sole interface.
* @param clazz the class to analyze for interfaces * @param clazz the class to analyze for interfaces
* @return all interfaces that the given object implements as Set * @return all interfaces that the given object implements as a Set
*/ */
public static Set<Class<?>> getAllInterfacesForClassAsSet(Class<?> clazz) { public static Set<Class<?>> getAllInterfacesForClassAsSet(Class<?> clazz) {
return getAllInterfacesForClassAsSet(clazz, null); return getAllInterfacesForClassAsSet(clazz, null);
} }
/** /**
* Return all interfaces that the given class implements as Set, * Return all interfaces that the given class implements as a Set,
* including ones implemented by superclasses. * including ones implemented by superclasses.
* <p>If the class itself is an interface, it gets returned as sole interface. * <p>If the class itself is an interface, it gets returned as sole interface.
* @param clazz the class to analyze for interfaces * @param clazz the class to analyze for interfaces
* @param classLoader the ClassLoader that the interfaces need to be visible in * @param classLoader the ClassLoader that the interfaces need to be visible in
* (may be {@code null} when accepting all declared interfaces) * (may be {@code null} when accepting all declared interfaces)
* @return all interfaces that the given object implements as Set * @return all interfaces that the given object implements as a Set
*/ */
public static Set<Class<?>> getAllInterfacesForClassAsSet(Class<?> clazz, ClassLoader classLoader) { public static Set<Class<?>> getAllInterfacesForClassAsSet(Class<?> clazz, ClassLoader classLoader) {
Assert.notNull(clazz, "Class must not be null"); Assert.notNull(clazz, "Class must not be null");

Loading…
Cancel
Save