-
Notifications
You must be signed in to change notification settings - Fork 38k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement equals, hashCode, & toString in BeanMethod and *Metadata types
Prior to this commit, ConfigurationClass implemented equals(), hashCode(), and toString(), but BeanMethod did not. This commit introduces equals(), hashCode(), and toString() implementations in BeanMethod for consistency with ConfigurationClass to make it possible to use BeanMethod instances to index additional metadata as well. In order to properly implement equals() in BeanMethod, the method argument types are required, but these are not directly available in BeanMethod. However, they are available via ASM when processing @bean methods. This commit therefore implements equals(), hashCode(), and toString() in SimpleMethodMetadata which BeanMethod delegates to. For completeness, this commit also implements equals(), hashCode(), and toString() in StandardClassMetadata, StandardMethodMetadata, and SimpleAnnotationMetadata. Closes gh-27076
- Loading branch information
Showing
11 changed files
with
451 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
202 changes: 202 additions & 0 deletions
202
...est/java/org/springframework/context/annotation/ConfigurationClassAndBeanMethodTests.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,202 @@ | ||
/* | ||
* Copyright 2002-2021 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 | ||
* | ||
* https://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 java.util.Comparator; | ||
import java.util.List; | ||
import java.util.stream.Collectors; | ||
|
||
import org.junit.jupiter.api.Test; | ||
|
||
import org.springframework.beans.factory.parsing.FailFastProblemReporter; | ||
import org.springframework.beans.factory.support.DefaultListableBeanFactory; | ||
import org.springframework.core.env.StandardEnvironment; | ||
import org.springframework.core.io.DefaultResourceLoader; | ||
import org.springframework.core.type.classreading.CachingMetadataReaderFactory; | ||
|
||
import static org.assertj.core.api.Assertions.assertThat; | ||
|
||
/** | ||
* Integration tests for {@link ConfigurationClassParser}, {@link ConfigurationClass}, | ||
* and {@link BeanMethod}. | ||
* | ||
* @author Sam Brannen | ||
* @since 5.3.9 | ||
*/ | ||
class ConfigurationClassAndBeanMethodTests { | ||
|
||
@Test | ||
void verifyEquals() throws Exception { | ||
ConfigurationClass configurationClass1 = newConfigurationClass(Config1.class); | ||
ConfigurationClass configurationClass2 = newConfigurationClass(Config1.class); | ||
ConfigurationClass configurationClass3 = newConfigurationClass(Config2.class); | ||
|
||
assertThat(configurationClass1.equals(null)).isFalse(); | ||
assertThat(configurationClass1).isNotSameAs(configurationClass2); | ||
|
||
assertThat(configurationClass1.equals(configurationClass1)).isTrue(); | ||
assertThat(configurationClass2.equals(configurationClass2)).isTrue(); | ||
assertThat(configurationClass1.equals(configurationClass2)).isTrue(); | ||
assertThat(configurationClass2.equals(configurationClass1)).isTrue(); | ||
|
||
assertThat(configurationClass1.equals(configurationClass3)).isFalse(); | ||
assertThat(configurationClass3.equals(configurationClass2)).isFalse(); | ||
|
||
// --------------------------------------------------------------------- | ||
|
||
List<BeanMethod> beanMethods1 = getBeanMethods(configurationClass1); | ||
BeanMethod beanMethod_1_0 = beanMethods1.get(0); | ||
BeanMethod beanMethod_1_1 = beanMethods1.get(1); | ||
BeanMethod beanMethod_1_2 = beanMethods1.get(2); | ||
|
||
List<BeanMethod> beanMethods2 = getBeanMethods(configurationClass2); | ||
BeanMethod beanMethod_2_0 = beanMethods2.get(0); | ||
BeanMethod beanMethod_2_1 = beanMethods2.get(1); | ||
BeanMethod beanMethod_2_2 = beanMethods2.get(2); | ||
|
||
List<BeanMethod> beanMethods3 = getBeanMethods(configurationClass3); | ||
BeanMethod beanMethod_3_0 = beanMethods3.get(0); | ||
BeanMethod beanMethod_3_1 = beanMethods3.get(1); | ||
BeanMethod beanMethod_3_2 = beanMethods3.get(2); | ||
|
||
assertThat(beanMethod_1_0.equals(null)).isFalse(); | ||
assertThat(beanMethod_1_0).isNotSameAs(beanMethod_2_0); | ||
|
||
assertThat(beanMethod_1_0.equals(beanMethod_1_0)).isTrue(); | ||
assertThat(beanMethod_1_0.equals(beanMethod_2_0)).isTrue(); | ||
assertThat(beanMethod_1_1.equals(beanMethod_2_1)).isTrue(); | ||
assertThat(beanMethod_1_2.equals(beanMethod_2_2)).isTrue(); | ||
|
||
assertThat(beanMethod_1_0.getMetadata().getMethodName()).isEqualTo(beanMethod_3_0.getMetadata().getMethodName()); | ||
assertThat(beanMethod_1_0.equals(beanMethod_3_0)).isFalse(); | ||
assertThat(beanMethod_1_1.equals(beanMethod_3_1)).isFalse(); | ||
assertThat(beanMethod_1_2.equals(beanMethod_3_2)).isFalse(); | ||
} | ||
|
||
@Test | ||
void verifyHashCode() throws Exception { | ||
ConfigurationClass configurationClass1 = newConfigurationClass(Config1.class); | ||
ConfigurationClass configurationClass2 = newConfigurationClass(Config1.class); | ||
ConfigurationClass configurationClass3 = newConfigurationClass(Config2.class); | ||
|
||
assertThat(configurationClass1).hasSameHashCodeAs(configurationClass2); | ||
assertThat(configurationClass1).doesNotHaveSameHashCodeAs(configurationClass3); | ||
|
||
// --------------------------------------------------------------------- | ||
|
||
List<BeanMethod> beanMethods1 = getBeanMethods(configurationClass1); | ||
BeanMethod beanMethod_1_0 = beanMethods1.get(0); | ||
BeanMethod beanMethod_1_1 = beanMethods1.get(1); | ||
BeanMethod beanMethod_1_2 = beanMethods1.get(2); | ||
|
||
List<BeanMethod> beanMethods2 = getBeanMethods(configurationClass2); | ||
BeanMethod beanMethod_2_0 = beanMethods2.get(0); | ||
BeanMethod beanMethod_2_1 = beanMethods2.get(1); | ||
BeanMethod beanMethod_2_2 = beanMethods2.get(2); | ||
|
||
List<BeanMethod> beanMethods3 = getBeanMethods(configurationClass3); | ||
BeanMethod beanMethod_3_0 = beanMethods3.get(0); | ||
BeanMethod beanMethod_3_1 = beanMethods3.get(1); | ||
BeanMethod beanMethod_3_2 = beanMethods3.get(2); | ||
|
||
assertThat(beanMethod_1_0).hasSameHashCodeAs(beanMethod_2_0); | ||
assertThat(beanMethod_1_1).hasSameHashCodeAs(beanMethod_2_1); | ||
assertThat(beanMethod_1_2).hasSameHashCodeAs(beanMethod_2_2); | ||
|
||
assertThat(beanMethod_1_0).doesNotHaveSameHashCodeAs(beanMethod_3_0); | ||
assertThat(beanMethod_1_1).doesNotHaveSameHashCodeAs(beanMethod_3_1); | ||
assertThat(beanMethod_1_2).doesNotHaveSameHashCodeAs(beanMethod_3_2); | ||
} | ||
|
||
@Test | ||
void verifyToString() throws Exception { | ||
ConfigurationClass configurationClass = newConfigurationClass(Config1.class); | ||
assertThat(configurationClass.toString()) | ||
.startsWith("ConfigurationClass: beanName 'Config1', class path resource"); | ||
|
||
List<BeanMethod> beanMethods = getBeanMethods(configurationClass); | ||
String prefix = "BeanMethod: " + Config1.class.getName(); | ||
assertThat(beanMethods.get(0).toString()).isEqualTo(prefix + ".bean0()"); | ||
assertThat(beanMethods.get(1).toString()).isEqualTo(prefix + ".bean1(java.lang.String)"); | ||
assertThat(beanMethods.get(2).toString()).isEqualTo(prefix + ".bean2(java.lang.String,java.lang.Integer)"); | ||
} | ||
|
||
|
||
private static ConfigurationClass newConfigurationClass(Class<?> clazz) throws Exception { | ||
ConfigurationClassParser parser = newParser(); | ||
parser.parse(clazz.getName(), clazz.getSimpleName()); | ||
assertThat(parser.getConfigurationClasses()).hasSize(1); | ||
return parser.getConfigurationClasses().iterator().next(); | ||
} | ||
|
||
private static ConfigurationClassParser newParser() { | ||
return new ConfigurationClassParser( | ||
new CachingMetadataReaderFactory(), | ||
new FailFastProblemReporter(), | ||
new StandardEnvironment(), | ||
new DefaultResourceLoader(), | ||
new AnnotationBeanNameGenerator(), | ||
new DefaultListableBeanFactory()); | ||
} | ||
|
||
private static List<BeanMethod> getBeanMethods(ConfigurationClass configurationClass) { | ||
List<BeanMethod> beanMethods = configurationClass.getBeanMethods().stream() | ||
.sorted(Comparator.comparing(beanMethod -> beanMethod.getMetadata().getMethodName())) | ||
.collect(Collectors.toList()); | ||
assertThat(beanMethods).hasSize(3); | ||
return beanMethods; | ||
} | ||
|
||
static class Config1 { | ||
|
||
@Bean | ||
String bean0() { | ||
return ""; | ||
} | ||
|
||
@Bean | ||
String bean1(String text) { | ||
return ""; | ||
} | ||
|
||
@Bean | ||
String bean2(String text, Integer num) { | ||
return ""; | ||
} | ||
|
||
} | ||
|
||
static class Config2 { | ||
|
||
@Bean | ||
String bean0() { | ||
return ""; | ||
} | ||
|
||
@Bean | ||
String bean1(String text) { | ||
return ""; | ||
} | ||
|
||
@Bean | ||
String bean2(String text, Integer num) { | ||
return ""; | ||
} | ||
|
||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.