diff --git a/spring-context/src/main/java/org/springframework/context/annotation/ClassPathScanningCandidateComponentProvider.java b/spring-context/src/main/java/org/springframework/context/annotation/ClassPathScanningCandidateComponentProvider.java index e9599b9f94fc..debb4c99c6b0 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/ClassPathScanningCandidateComponentProvider.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/ClassPathScanningCandidateComponentProvider.java @@ -386,6 +386,7 @@ private Set addCandidateComponentsFromIndex(CandidateComponentsI MetadataReader metadataReader = getMetadataReaderFactory().getMetadataReader(type); if (isCandidateComponent(metadataReader)) { ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader); + sbd.setSource(metadataReader.getResource()); if (isCandidateComponent(sbd)) { if (debugEnabled) { logger.debug("Using candidate component class from index: " + type); @@ -428,7 +429,6 @@ private Set scanCandidateComponents(String basePackage) { MetadataReader metadataReader = getMetadataReaderFactory().getMetadataReader(resource); if (isCandidateComponent(metadataReader)) { ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader); - sbd.setResource(resource); sbd.setSource(resource); if (isCandidateComponent(sbd)) { if (debugEnabled) { diff --git a/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassBeanDefinitionReader.java b/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassBeanDefinitionReader.java index fbb00895b6e7..34c510294d51 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassBeanDefinitionReader.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassBeanDefinitionReader.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * 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. @@ -209,7 +209,6 @@ private void loadBeanDefinitionsForBeanMethod(BeanMethod beanMethod) { } ConfigurationClassBeanDefinition beanDef = new ConfigurationClassBeanDefinition(configClass, metadata); - beanDef.setResource(configClass.getResource()); beanDef.setSource(this.sourceExtractor.extractSource(metadata, configClass.getResource())); if (metadata.isStatic()) { @@ -375,6 +374,7 @@ private static class ConfigurationClassBeanDefinition extends RootBeanDefinition public ConfigurationClassBeanDefinition(ConfigurationClass configClass, MethodMetadata beanMethodMetadata) { this.annotationMetadata = configClass.getMetadata(); this.factoryMethodMetadata = beanMethodMetadata; + setResource(configClass.getResource()); setLenientConstructorResolution(false); } diff --git a/spring-context/src/main/java/org/springframework/context/annotation/ScannedGenericBeanDefinition.java b/spring-context/src/main/java/org/springframework/context/annotation/ScannedGenericBeanDefinition.java index 71174fd23d4e..26e603bbf259 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/ScannedGenericBeanDefinition.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/ScannedGenericBeanDefinition.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * 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. @@ -60,6 +60,7 @@ public ScannedGenericBeanDefinition(MetadataReader metadataReader) { Assert.notNull(metadataReader, "MetadataReader must not be null"); this.metadata = metadataReader.getAnnotationMetadata(); setBeanClassName(this.metadata.getClassName()); + setResource(metadataReader.getResource()); } diff --git a/spring-context/src/test/java/org/springframework/context/annotation/ClassPathBeanDefinitionScannerTests.java b/spring-context/src/test/java/org/springframework/context/annotation/ClassPathBeanDefinitionScannerTests.java index 85f4e63a72af..9e67e4612649 100644 --- a/spring-context/src/test/java/org/springframework/context/annotation/ClassPathBeanDefinitionScannerTests.java +++ b/spring-context/src/test/java/org/springframework/context/annotation/ClassPathBeanDefinitionScannerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * 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. @@ -28,16 +28,18 @@ import org.springframework.beans.factory.BeanCreationException; import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.beans.factory.support.AbstractBeanDefinition; import org.springframework.beans.factory.support.BeanDefinitionRegistry; import org.springframework.beans.factory.support.RootBeanDefinition; import org.springframework.beans.factory.support.StaticListableBeanFactory; import org.springframework.context.MessageSource; import org.springframework.context.annotation2.NamedStubDao2; +import org.springframework.context.index.CandidateComponentsTestClassLoader; import org.springframework.context.support.GenericApplicationContext; +import org.springframework.core.io.ClassPathResource; import org.springframework.core.type.filter.AnnotationTypeFilter; import org.springframework.core.type.filter.AssignableTypeFilter; import org.springframework.stereotype.Component; -import org.springframework.tests.sample.beans.TestBean; import static org.junit.Assert.*; @@ -103,10 +105,66 @@ public void testSimpleScanWithDefaultFiltersAndPrimaryLazyBean() { @Test public void testDoubleScan() { GenericApplicationContext context = new GenericApplicationContext(); + ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(context); int beanCount = scanner.scan(BASE_PACKAGE); assertEquals(13, beanCount); - scanner.scan(BASE_PACKAGE); + + ClassPathBeanDefinitionScanner scanner2 = new ClassPathBeanDefinitionScanner(context) { + @Override + protected void postProcessBeanDefinition(AbstractBeanDefinition beanDefinition, String beanName) { + super.postProcessBeanDefinition(beanDefinition, beanName); + beanDefinition.setAttribute("someDifference", "someValue"); + } + }; + scanner2.scan(BASE_PACKAGE); + + assertTrue(context.containsBean("serviceInvocationCounter")); + assertTrue(context.containsBean("fooServiceImpl")); + assertTrue(context.containsBean("stubFooDao")); + assertTrue(context.containsBean("myNamedComponent")); + assertTrue(context.containsBean("myNamedDao")); + assertTrue(context.containsBean("thoreau")); + } + + @Test + public void testWithIndex() { + GenericApplicationContext context = new GenericApplicationContext(); + context.setClassLoader(CandidateComponentsTestClassLoader.index( + ClassPathScanningCandidateComponentProviderTests.class.getClassLoader(), + new ClassPathResource("spring.components", FooServiceImpl.class))); + + ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(context); + int beanCount = scanner.scan(BASE_PACKAGE); + assertEquals(13, beanCount); + + assertTrue(context.containsBean("serviceInvocationCounter")); + assertTrue(context.containsBean("fooServiceImpl")); + assertTrue(context.containsBean("stubFooDao")); + assertTrue(context.containsBean("myNamedComponent")); + assertTrue(context.containsBean("myNamedDao")); + assertTrue(context.containsBean("thoreau")); + } + + @Test + public void testDoubleScanWithIndex() { + GenericApplicationContext context = new GenericApplicationContext(); + context.setClassLoader(CandidateComponentsTestClassLoader.index( + ClassPathScanningCandidateComponentProviderTests.class.getClassLoader(), + new ClassPathResource("spring.components", FooServiceImpl.class))); + + ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(context); + int beanCount = scanner.scan(BASE_PACKAGE); + assertEquals(13, beanCount); + + ClassPathBeanDefinitionScanner scanner2 = new ClassPathBeanDefinitionScanner(context) { + @Override + protected void postProcessBeanDefinition(AbstractBeanDefinition beanDefinition, String beanName) { + super.postProcessBeanDefinition(beanDefinition, beanName); + beanDefinition.setAttribute("someDifference", "someValue"); + } + }; + scanner2.scan(BASE_PACKAGE); assertTrue(context.containsBean("serviceInvocationCounter")); assertTrue(context.containsBean("fooServiceImpl"));