Skip to content

Commit

Permalink
Polish DefaultListableBeanFactoryTests
Browse files Browse the repository at this point in the history
  • Loading branch information
sbrannen committed Jun 14, 2022
1 parent 57db73d commit e47cc44
Showing 1 changed file with 76 additions and 109 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
import java.security.PrivilegedAction;
import java.text.NumberFormat;
import java.text.ParseException;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
Expand Down Expand Up @@ -95,6 +94,7 @@
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
import static org.assertj.core.api.Assertions.assertThatNoException;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.isNull;
Expand Down Expand Up @@ -178,10 +178,8 @@ void prototypeFactoryBeanIgnoredByNonEagerTypeMatching() {
registerBeanDefinitions(p);

assertThat(!DummyFactory.wasPrototypeCreated()).as("prototype not instantiated").isTrue();
String[] beanNames = lbf.getBeanNamesForType(TestBean.class, true, false);
assertThat(beanNames).hasSize(0);
beanNames = lbf.getBeanNamesForAnnotation(SuppressWarnings.class);
assertThat(beanNames).hasSize(0);
assertBeanNamesForType(TestBean.class, false, false);
assertThat(lbf.getBeanNamesForAnnotation(SuppressWarnings.class)).isEmpty();

assertThat(lbf.containsSingleton("x1")).isFalse();
assertThat(lbf.containsBean("x1")).isTrue();
Expand Down Expand Up @@ -212,10 +210,8 @@ void singletonFactoryBeanIgnoredByNonEagerTypeMatching() {
registerBeanDefinitions(p);

assertThat(!DummyFactory.wasPrototypeCreated()).as("prototype not instantiated").isTrue();
String[] beanNames = lbf.getBeanNamesForType(TestBean.class, true, false);
assertThat(beanNames).hasSize(0);
beanNames = lbf.getBeanNamesForAnnotation(SuppressWarnings.class);
assertThat(beanNames).hasSize(0);
assertBeanNamesForType(TestBean.class, false, false);
assertThat(lbf.getBeanNamesForAnnotation(SuppressWarnings.class)).isEmpty();

assertThat(lbf.containsSingleton("x1")).isFalse();
assertThat(lbf.containsBean("x1")).isTrue();
Expand Down Expand Up @@ -245,10 +241,8 @@ void nonInitializedFactoryBeanIgnoredByNonEagerTypeMatching() {
registerBeanDefinitions(p);

assertThat(!DummyFactory.wasPrototypeCreated()).as("prototype not instantiated").isTrue();
String[] beanNames = lbf.getBeanNamesForType(TestBean.class, true, false);
assertThat(beanNames).hasSize(0);
beanNames = lbf.getBeanNamesForAnnotation(SuppressWarnings.class);
assertThat(beanNames).hasSize(0);
assertBeanNamesForType(TestBean.class, false, false);
assertThat(lbf.getBeanNamesForAnnotation(SuppressWarnings.class)).isEmpty();

assertThat(lbf.containsSingleton("x1")).isFalse();
assertThat(lbf.containsBean("x1")).isTrue();
Expand Down Expand Up @@ -278,10 +272,8 @@ void initializedFactoryBeanFoundByNonEagerTypeMatching() {
registerBeanDefinitions(p);
lbf.preInstantiateSingletons();

assertThat(!DummyFactory.wasPrototypeCreated()).as("prototype not instantiated").isTrue();
String[] beanNames = lbf.getBeanNamesForType(TestBean.class, true, false);
assertThat(beanNames).hasSize(1);
assertThat(beanNames[0]).isEqualTo("x1");
assertThat(DummyFactory.wasPrototypeCreated()).as("prototype not instantiated").isFalse();
assertBeanNamesForType(TestBean.class, true, false, "x1");
assertThat(lbf.containsSingleton("x1")).isTrue();
assertThat(lbf.containsBean("x1")).isTrue();
assertThat(lbf.containsBean("&x1")).isTrue();
Expand Down Expand Up @@ -316,14 +308,10 @@ void initializedFactoryBeanFoundByNonEagerTypeMatching() {
assertThat(lbf.isTypeMatch("&x2", Object.class)).isTrue();
assertThat(lbf.getType("x2")).isEqualTo(TestBean.class);
assertThat(lbf.getType("&x2")).isEqualTo(DummyFactory.class);
assertThat(lbf.getAliases("x1").length).isEqualTo(1);
assertThat(lbf.getAliases("x1")[0]).isEqualTo("x2");
assertThat(lbf.getAliases("&x1").length).isEqualTo(1);
assertThat(lbf.getAliases("&x1")[0]).isEqualTo("&x2");
assertThat(lbf.getAliases("x2").length).isEqualTo(1);
assertThat(lbf.getAliases("x2")[0]).isEqualTo("x1");
assertThat(lbf.getAliases("&x2").length).isEqualTo(1);
assertThat(lbf.getAliases("&x2")[0]).isEqualTo("&x1");
assertThat(lbf.getAliases("x1")).containsExactly("x2");
assertThat(lbf.getAliases("&x1")).containsExactly("&x2");
assertThat(lbf.getAliases("x2")).containsExactly("x1");
assertThat(lbf.getAliases("&x2")).containsExactly("&x1");
}

@Test
Expand All @@ -333,9 +321,7 @@ void staticFactoryMethodFoundByNonEagerTypeMatching() {
lbf.registerBeanDefinition("x1", rbd);

TestBeanFactory.initialized = false;
String[] beanNames = lbf.getBeanNamesForType(TestBean.class, true, false);
assertThat(beanNames).hasSize(1);
assertThat(beanNames[0]).isEqualTo("x1");
assertBeanNamesForType(TestBean.class, true, false, "x1");
assertThat(lbf.containsSingleton("x1")).isFalse();
assertThat(lbf.containsBean("x1")).isTrue();
assertThat(lbf.containsBean("&x1")).isFalse();
Expand All @@ -358,9 +344,7 @@ void staticPrototypeFactoryMethodFoundByNonEagerTypeMatching() {
lbf.registerBeanDefinition("x1", rbd);

TestBeanFactory.initialized = false;
String[] beanNames = lbf.getBeanNamesForType(TestBean.class, true, false);
assertThat(beanNames).hasSize(1);
assertThat(beanNames[0]).isEqualTo("x1");
assertBeanNamesForType(TestBean.class, true, false, "x1");
assertThat(lbf.containsSingleton("x1")).isFalse();
assertThat(lbf.containsBean("x1")).isTrue();
assertThat(lbf.containsBean("&x1")).isFalse();
Expand All @@ -385,9 +369,7 @@ void nonStaticFactoryMethodFoundByNonEagerTypeMatching() {
lbf.registerBeanDefinition("x1", rbd);

TestBeanFactory.initialized = false;
String[] beanNames = lbf.getBeanNamesForType(TestBean.class, true, false);
assertThat(beanNames).hasSize(1);
assertThat(beanNames[0]).isEqualTo("x1");
assertBeanNamesForType(TestBean.class, true, false, "x1");
assertThat(lbf.containsSingleton("x1")).isFalse();
assertThat(lbf.containsBean("x1")).isTrue();
assertThat(lbf.containsBean("&x1")).isFalse();
Expand All @@ -413,9 +395,7 @@ void nonStaticPrototypeFactoryMethodFoundByNonEagerTypeMatching() {
lbf.registerBeanDefinition("x1", rbd);

TestBeanFactory.initialized = false;
String[] beanNames = lbf.getBeanNamesForType(TestBean.class, true, false);
assertThat(beanNames).hasSize(1);
assertThat(beanNames[0]).isEqualTo("x1");
assertBeanNamesForType(TestBean.class, true, false, "x1");
assertThat(lbf.containsSingleton("x1")).isFalse();
assertThat(lbf.containsBean("x1")).isTrue();
assertThat(lbf.containsBean("&x1")).isFalse();
Expand Down Expand Up @@ -448,14 +428,10 @@ void nonStaticPrototypeFactoryMethodFoundByNonEagerTypeMatching() {
assertThat(lbf.isTypeMatch("&x2", Object.class)).isFalse();
assertThat(lbf.getType("x2")).isEqualTo(TestBean.class);
assertThat(lbf.getType("&x2")).isNull();
assertThat(lbf.getAliases("x1").length).isEqualTo(1);
assertThat(lbf.getAliases("x1")[0]).isEqualTo("x2");
assertThat(lbf.getAliases("&x1").length).isEqualTo(1);
assertThat(lbf.getAliases("&x1")[0]).isEqualTo("&x2");
assertThat(lbf.getAliases("x2").length).isEqualTo(1);
assertThat(lbf.getAliases("x2")[0]).isEqualTo("x1");
assertThat(lbf.getAliases("&x2").length).isEqualTo(1);
assertThat(lbf.getAliases("&x2")[0]).isEqualTo("&x1");
assertThat(lbf.getAliases("x1")).containsExactly("x2");
assertThat(lbf.getAliases("&x1")).containsExactly("&x2");
assertThat(lbf.getAliases("x2")).containsExactly("x1");
assertThat(lbf.getAliases("&x2")).containsExactly("&x1");
}

@Test
Expand Down Expand Up @@ -619,8 +595,7 @@ void arrayReferenceByName() {
lbf.registerSingleton("string", "A");

TestBean self = (TestBean) lbf.getBean("self");
assertThat(self.getStringArray()).hasSize(1);
assertThat(self.getStringArray()).contains("A");
assertThat(self.getStringArray()).containsExactly("A");
}

@Test
Expand All @@ -633,8 +608,7 @@ void arrayReferenceByType() {
lbf.registerSingleton("string", "A");

TestBean self = (TestBean) lbf.getBean("self");
assertThat(self.getStringArray()).hasSize(1);
assertThat(self.getStringArray()).contains("A");
assertThat(self.getStringArray()).containsExactly("A");
}

@Test
Expand Down Expand Up @@ -666,8 +640,7 @@ void possibleMatches() {
.withCauseInstanceOf(NotWritablePropertyException.class)
.satisfies(ex -> {
NotWritablePropertyException cause = (NotWritablePropertyException) ex.getCause();
assertThat(cause.getPossibleMatches()).hasSize(1);
assertThat(cause.getPossibleMatches()[0]).isEqualTo("age");
assertThat(cause.getPossibleMatches()).containsExactly("age");
});
}

Expand All @@ -685,7 +658,7 @@ void prototype() {
lbf = new DefaultListableBeanFactory();
p = new Properties();
p.setProperty("kerry.(class)", TestBean.class.getName());
p.setProperty("kerry.(scope)", "prototype");
p.setProperty("kerry.(scope)", BeanDefinition.SCOPE_PROTOTYPE);
p.setProperty("kerry.age", "35");
registerBeanDefinitions(p);
kerry1 = (TestBean) lbf.getBean("kerry");
Expand Down Expand Up @@ -1145,7 +1118,7 @@ void registerExistingSingletonWithAutowire() {
assertThat(lbf.containsBean("singletonObject")).isTrue();
assertThat(lbf.isSingleton("singletonObject")).isTrue();
assertThat(lbf.getType("singletonObject")).isEqualTo(TestBean.class);
assertThat(lbf.getAliases("singletonObject").length).isEqualTo(0);
assertThat(lbf.getAliases("singletonObject")).isEmpty();
DependenciesBean test = (DependenciesBean) lbf.getBean("test");
assertThat(lbf.getBean("singletonObject")).isEqualTo(singletonObject);
assertThat(test.getSpouse()).isEqualTo(singletonObject);
Expand Down Expand Up @@ -1791,12 +1764,12 @@ void getBeanWithArgsNotCreatedForFactoryBeanChecking() {
assertThat(bean.beanName).isEqualTo("bd1");
assertThat(bean.spouseAge).isEqualTo(42);

assertThat(lbf.getBeanNamesForType(ConstructorDependency.class).length).isEqualTo(1);
assertThat(lbf.getBeanNamesForType(ConstructorDependencyFactoryBean.class).length).isEqualTo(1);
assertThat(lbf.getBeanNamesForType(ResolvableType.forClassWithGenerics(FactoryBean.class, Object.class)).length).isEqualTo(1);
assertThat(lbf.getBeanNamesForType(ResolvableType.forClassWithGenerics(FactoryBean.class, String.class)).length).isEqualTo(0);
assertThat(lbf.getBeanNamesForType(ResolvableType.forClassWithGenerics(FactoryBean.class, Object.class), true, true).length).isEqualTo(1);
assertThat(lbf.getBeanNamesForType(ResolvableType.forClassWithGenerics(FactoryBean.class, String.class), true, true).length).isEqualTo(0);
assertThat(lbf.getBeanNamesForType(ConstructorDependency.class)).hasSize(1);
assertThat(lbf.getBeanNamesForType(ConstructorDependencyFactoryBean.class)).hasSize(1);
assertThat(lbf.getBeanNamesForType(ResolvableType.forClassWithGenerics(FactoryBean.class, Object.class))).hasSize(1);
assertThat(lbf.getBeanNamesForType(ResolvableType.forClassWithGenerics(FactoryBean.class, String.class))).isEmpty();
assertThat(lbf.getBeanNamesForType(ResolvableType.forClassWithGenerics(FactoryBean.class, Object.class), true, true)).hasSize(1);
assertThat(lbf.getBeanNamesForType(ResolvableType.forClassWithGenerics(FactoryBean.class, String.class), true, true)).isEmpty();
}

private RootBeanDefinition createConstructorDependencyBeanDefinition(int age) {
Expand Down Expand Up @@ -1861,46 +1834,29 @@ void getTypeForAbstractFactoryBean() {

@Test
void getBeanNamesForTypeBeforeFactoryBeanCreation() {
FactoryBeanThatShouldntBeCalled.instantiated = false;
lbf.registerBeanDefinition("factoryBean", new RootBeanDefinition(FactoryBeanThatShouldntBeCalled.class));
assertThat(lbf.containsSingleton("factoryBean")).isFalse();
assertThat(FactoryBeanThatShouldntBeCalled.instantiated).isFalse();

String[] beanNames = lbf.getBeanNamesForType(Runnable.class, false, false);
assertThat(beanNames.length).isEqualTo(1);
assertThat(beanNames[0]).isEqualTo("&factoryBean");

beanNames = lbf.getBeanNamesForType(Callable.class, false, false);
assertThat(beanNames.length).isEqualTo(1);
assertThat(beanNames[0]).isEqualTo("&factoryBean");

beanNames = lbf.getBeanNamesForType(RepositoryFactoryInformation.class, false, false);
assertThat(beanNames.length).isEqualTo(1);
assertThat(beanNames[0]).isEqualTo("&factoryBean");

beanNames = lbf.getBeanNamesForType(FactoryBean.class, false, false);
assertThat(beanNames.length).isEqualTo(1);
assertThat(beanNames[0]).isEqualTo("&factoryBean");
assertBeanNamesForType(Runnable.class, false, false, "&factoryBean");
assertBeanNamesForType(Callable.class, false, false, "&factoryBean");
assertBeanNamesForType(RepositoryFactoryInformation.class, false, false, "&factoryBean");
assertBeanNamesForType(FactoryBean.class, false, false, "&factoryBean");
}

@Test
void getBeanNamesForTypeAfterFactoryBeanCreation() {
FactoryBeanThatShouldntBeCalled.instantiated = false;
lbf.registerBeanDefinition("factoryBean", new RootBeanDefinition(FactoryBeanThatShouldntBeCalled.class));
lbf.getBean("&factoryBean");
assertThat(FactoryBeanThatShouldntBeCalled.instantiated).isTrue();
assertThat(lbf.containsSingleton("factoryBean")).isTrue();

String[] beanNames = lbf.getBeanNamesForType(Runnable.class, false, false);
assertThat(beanNames.length).isEqualTo(1);
assertThat(beanNames[0]).isEqualTo("&factoryBean");

beanNames = lbf.getBeanNamesForType(Callable.class, false, false);
assertThat(beanNames.length).isEqualTo(1);
assertThat(beanNames[0]).isEqualTo("&factoryBean");

beanNames = lbf.getBeanNamesForType(RepositoryFactoryInformation.class, false, false);
assertThat(beanNames.length).isEqualTo(1);
assertThat(beanNames[0]).isEqualTo("&factoryBean");

beanNames = lbf.getBeanNamesForType(FactoryBean.class, false, false);
assertThat(beanNames.length).isEqualTo(1);
assertThat(beanNames[0]).isEqualTo("&factoryBean");
assertBeanNamesForType(Runnable.class, false, false, "&factoryBean");
assertBeanNamesForType(Callable.class, false, false, "&factoryBean");
assertBeanNamesForType(RepositoryFactoryInformation.class, false, false, "&factoryBean");
assertBeanNamesForType(FactoryBean.class, false, false, "&factoryBean");
}

/**
Expand Down Expand Up @@ -2165,26 +2121,23 @@ void circularReferenceThroughAutowiring() {
RootBeanDefinition bd = new RootBeanDefinition(ConstructorDependencyBean.class);
bd.setAutowireMode(RootBeanDefinition.AUTOWIRE_CONSTRUCTOR);
lbf.registerBeanDefinition("test", bd);
assertThatExceptionOfType(UnsatisfiedDependencyException.class).isThrownBy(
lbf::preInstantiateSingletons);
assertThatExceptionOfType(UnsatisfiedDependencyException.class).isThrownBy(lbf::preInstantiateSingletons);
}

@Test
void circularReferenceThroughFactoryBeanAutowiring() {
RootBeanDefinition bd = new RootBeanDefinition(ConstructorDependencyFactoryBean.class);
bd.setAutowireMode(RootBeanDefinition.AUTOWIRE_CONSTRUCTOR);
lbf.registerBeanDefinition("test", bd);
assertThatExceptionOfType(UnsatisfiedDependencyException.class).isThrownBy(
lbf::preInstantiateSingletons);
assertThatExceptionOfType(UnsatisfiedDependencyException.class).isThrownBy(lbf::preInstantiateSingletons);
}

@Test
void circularReferenceThroughFactoryBeanTypeCheck() {
RootBeanDefinition bd = new RootBeanDefinition(ConstructorDependencyFactoryBean.class);
bd.setAutowireMode(RootBeanDefinition.AUTOWIRE_CONSTRUCTOR);
lbf.registerBeanDefinition("test", bd);
assertThatExceptionOfType(UnsatisfiedDependencyException.class).isThrownBy(() ->
lbf.getBeansOfType(String.class));
assertThatExceptionOfType(UnsatisfiedDependencyException.class).isThrownBy(() -> lbf.getBeansOfType(String.class));
}

@Test
Expand All @@ -2211,8 +2164,7 @@ void constructorDependencyWithUnresolvableClass() {
RootBeanDefinition bd = new RootBeanDefinition(ConstructorDependencyWithClassResolution.class);
bd.getConstructorArgumentValues().addGenericArgumentValue("java.lang.Strin");
lbf.registerBeanDefinition("test", bd);
assertThatExceptionOfType(UnsatisfiedDependencyException.class).isThrownBy(
lbf::preInstantiateSingletons);
assertThatExceptionOfType(UnsatisfiedDependencyException.class).isThrownBy(lbf::preInstantiateSingletons);
}

@Test
Expand All @@ -2236,7 +2188,13 @@ void beanDefinitionWithAbstractClass() {
@Test
void prototypeFactoryBeanNotEagerlyCalled() {
lbf.registerBeanDefinition("test", new RootBeanDefinition(FactoryBeanThatShouldntBeCalled.class));
lbf.preInstantiateSingletons();
assertThatNoException().isThrownBy(lbf::preInstantiateSingletons);
}

@Test
void prototypeFactoryBeanNotEagerlyCalledInCaseOfBeanClassName() {
lbf.registerBeanDefinition("test", new RootBeanDefinition(FactoryBeanThatShouldntBeCalled.class.getName(), null, null));
assertThatNoException().isThrownBy(lbf::preInstantiateSingletons);
}

@Test
Expand Down Expand Up @@ -2276,13 +2234,6 @@ void smartInitFactory() {
assertThat(factory.initialized).isTrue();
}

@Test
void prototypeFactoryBeanNotEagerlyCalledInCaseOfBeanClassName() {
lbf.registerBeanDefinition("test",
new RootBeanDefinition(FactoryBeanThatShouldntBeCalled.class.getName(), null, null));
lbf.preInstantiateSingletons();
}

@Test
void prototypeStringCreatedRepeatedly() {
RootBeanDefinition stringDef = new RootBeanDefinition(String.class);
Expand Down Expand Up @@ -2462,10 +2413,7 @@ private void findTypeOfPrototypeFactoryMethodOnBeanInstance(boolean singleton) {
lbf.registerBeanDefinition("fmWithArgs", factoryMethodDefinitionWithArgs);

assertThat(lbf.getBeanDefinitionCount()).isEqualTo(4);
List<String> tbNames = Arrays.asList(lbf.getBeanNamesForType(TestBean.class));
assertThat(tbNames.contains("fmWithProperties")).isTrue();
assertThat(tbNames.contains("fmWithArgs")).isTrue();
assertThat(tbNames.size()).isEqualTo(2);
assertBeanNamesForType(TestBean.class, true, true, "fmWithProperties", "fmWithArgs");

TestBean tb = (TestBean) lbf.getBean("fmWithProperties");
TestBean second = (TestBean) lbf.getBean("fmWithProperties");
Expand Down Expand Up @@ -2669,6 +2617,19 @@ private int registerBeanDefinitions(Properties p, String prefix) {
return (new org.springframework.beans.factory.support.PropertiesBeanDefinitionReader(lbf)).registerBeanDefinitions(p, prefix);
}

private void assertBeanNamesForType(Class<?> type, boolean includeNonSingletons, boolean allowEagerInit, String... names) {
if (names.length == 0) {
assertThat(lbf.getBeanNamesForType(type, includeNonSingletons, allowEagerInit))
.as("bean names for type " + type.getName())
.isEmpty();
}
else {
assertThat(lbf.getBeanNamesForType(type, includeNonSingletons, allowEagerInit))
.as("bean names for type " + type.getName())
.containsExactly(names);
}
}


public static class NoDependencies {

Expand Down Expand Up @@ -2859,6 +2820,12 @@ public static abstract class RepositoryFactoryBeanSupport<T extends Repository<S
public static class FactoryBeanThatShouldntBeCalled<T extends Repository<S, ID>, S, ID extends Serializable>
extends RepositoryFactoryBeanSupport<T, S, ID> implements Runnable, Callable<T> {

static boolean instantiated = false;

{
instantiated = true;
}

@Override
public T getObject() {
throw new IllegalStateException();
Expand Down

0 comments on commit e47cc44

Please sign in to comment.