diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/ScalableDefaultListableBeanFactory.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/ScalableDefaultListableBeanFactory.java
new file mode 100644
index 000000000000..8cbeb50a75e8
--- /dev/null
+++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/ScalableDefaultListableBeanFactory.java
@@ -0,0 +1,175 @@
+/*
+ * Copyright 2002-2018 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.beans.factory.support;
+
+import java.util.ArrayDeque;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Queue;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.TimeUnit;
+
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.BeanFactory;
+import org.springframework.lang.Nullable;
+
+/**
+ * Extends the behavior of {@link DefaultListableBeanFactory} by providing a type to bean name index.
+ *
+ * Since the configuration is frozen, bean definitions do not change and hence
+ * we can build the mapping by going through all the beans in the registry once.
+ *
+ * Spring's current implementation is O(N * M) where N is number of beans in
+ * registry and M is the number of beans that get loaded during the
+ * startup phase. To find the bean names, Spring computes the types for each of
+ * the bean and matches that with the given type. It would do this against all
+ * the N beans in the registry for every type that is being wired.
+ *
+ * Instead the type is extracted once for all the beans and stored in a local
+ * cache. The beans can then be retrieved in O(1) using the cache for all future
+ * wiring of that type. Additionally we gather all the super types for our
+ * bean-types for type match to satisfy wirings by parent types. If a given type
+ * is not found in our cache, we revert to using Spring's default resolution
+ * mechanism.
+ *
+ * @author Rahul Shinde
+ */
+public class ScalableDefaultListableBeanFactory extends DefaultListableBeanFactory {
+
+ /**
+ * Mapping of Class to 1..* bean names.
+ */
+ private final Map, String[]> beanNamesByTypeMappings;
+
+ /**
+ * Create a new ScalableDefaultListableBeanFactory.
+ */
+ public ScalableDefaultListableBeanFactory() {
+ this.beanNamesByTypeMappings = new ConcurrentHashMap<>();
+ }
+
+ /**
+ * Create a new DefaultListableBeanFactory with the given parent.
+ *
+ * @param parentBeanFactory the parent BeanFactory
+ */
+ public ScalableDefaultListableBeanFactory(@Nullable BeanFactory parentBeanFactory) {
+ super(parentBeanFactory);
+ this.beanNamesByTypeMappings = new ConcurrentHashMap<>();
+ }
+
+ /**
+ * Looks for the mapping inside our local cache first,
+ * else delegates to the super class method {@link DefaultListableBeanFactory#getBeansOfType(Class, boolean, boolean)}.
+ */
+ @Override
+ public String[] getBeanNamesForType(@Nullable Class> type, boolean includeNonSingletons, boolean allowEagerInit) {
+ String[] resolvedBeanNames = null;
+ if (type != null) {
+ resolvedBeanNames = this.beanNamesByTypeMappings.get(type);
+ }
+ return resolvedBeanNames != null ? resolvedBeanNames : super.getBeanNamesForType(type, includeNonSingletons, allowEagerInit);
+ }
+
+ /**
+ * Acts as a hook to populates our cache just before creating the eager beans.
+ * The configuration should already be frozen as per Spring's implementation.
+ */
+ @Override
+ public void preInstantiateSingletons() throws BeansException {
+ populateBeanTypeToNameMappings();
+ super.preInstantiateSingletons();
+ }
+
+ /**
+ * Create mapping for types to bean-names using all the available bean definitions.
+ * Additionally we gather all the parent Class(es) for the given bean type as part of the mappings.
+ */
+ private void populateBeanTypeToNameMappings() {
+ Map, List> localBeanTypeMappings = new HashMap<>();
+ long startNanos = System.nanoTime();
+ Arrays.stream(this.getBeanDefinitionNames())
+ // Filter bean definitions names that are alias as these are redundant
+ .filter(beanName -> !isAlias(beanName))
+ .forEach(beanName -> {
+ try {
+ // Use's Spring implementation to identify the target class for a given bean name.
+ Class> targetClass = getType(beanName);
+ if (targetClass != null) {
+ // fetch all the super types as well for this targetClass
+ Set> classTypes = getSuperTypes(targetClass);
+ // add the current type as well to the mapping
+ classTypes.add(targetClass);
+ classTypes.forEach(clazz -> localBeanTypeMappings.compute(clazz, (k, v) -> {
+ v = v == null ? new ArrayList<>() : v;
+ v.add(beanName);
+ return v;
+ }));
+ }
+ }
+ catch (Exception ex) {
+ // ignore the missing bean
+ if (logger.isTraceEnabled()) {
+ logger.trace("No bean named '" + beanName + "' found ");
+ }
+ }
+ });
+
+ // Convert values from List to String[] as expected by getBeanNamesForType(...) API
+ localBeanTypeMappings.forEach((k, v) -> {
+ this.beanNamesByTypeMappings.put(k, v.toArray(new String[0]));
+ });
+
+ if (logger.isDebugEnabled()) {
+ logger.debug(String.format("DefaultListableBeanFactory beanNamesByType mappings populated with total records=%d in %d millis",
+ this.beanNamesByTypeMappings.size(), TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startNanos)));
+ }
+ }
+
+ /**
+ * Finds all the super types for the given {@link Class}.
+ *
+ * @param givenClazz input class
+ * @return set of all super types that it inherits from
+ */
+ static Set> getSuperTypes(Class> givenClazz) {
+ final Set> superTypeSet = new LinkedHashSet<>();
+ final Queue> possibleCandidates = new ArrayDeque<>();
+ possibleCandidates.add(givenClazz);
+ if (givenClazz.isInterface()) {
+ possibleCandidates.add(Object.class);
+ }
+ while (!possibleCandidates.isEmpty()) {
+ Class> clz = possibleCandidates.remove();
+ // skip the input class as we are only interested in parent types
+ if (!clz.equals(givenClazz)) {
+ superTypeSet.add(clz);
+ }
+ Class> superClz = clz.getSuperclass();
+ if (superClz != null) {
+ possibleCandidates.add(superClz);
+ }
+ possibleCandidates.addAll(Arrays.asList(clz.getInterfaces()));
+ }
+ return superTypeSet;
+ }
+
+}
diff --git a/spring-beans/src/test/java/org/springframework/beans/factory/AbstractDefaultListableBeanFactoryTests.java b/spring-beans/src/test/java/org/springframework/beans/factory/AbstractDefaultListableBeanFactoryTests.java
new file mode 100644
index 000000000000..e5242a75b256
--- /dev/null
+++ b/spring-beans/src/test/java/org/springframework/beans/factory/AbstractDefaultListableBeanFactoryTests.java
@@ -0,0 +1,3550 @@
+/*
+ * Copyright 2002-2018 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.beans.factory;
+
+import java.io.Closeable;
+import java.io.Serializable;
+import java.lang.reflect.Field;
+import java.net.MalformedURLException;
+import java.security.AccessControlContext;
+import java.security.AccessController;
+import java.security.Principal;
+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;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.Properties;
+import java.util.Set;
+import java.util.concurrent.Callable;
+import java.util.stream.Collectors;
+import javax.annotation.Priority;
+import javax.security.auth.Subject;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.junit.Ignore;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.mockito.ArgumentMatchers;
+
+import org.springframework.beans.BeansException;
+import org.springframework.beans.MutablePropertyValues;
+import org.springframework.beans.NotWritablePropertyException;
+import org.springframework.beans.PropertyEditorRegistrar;
+import org.springframework.beans.PropertyEditorRegistry;
+import org.springframework.beans.PropertyValue;
+import org.springframework.beans.TypeConverter;
+import org.springframework.beans.TypeMismatchException;
+import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.beans.factory.config.BeanExpressionContext;
+import org.springframework.beans.factory.config.BeanExpressionResolver;
+import org.springframework.beans.factory.config.BeanPostProcessor;
+import org.springframework.beans.factory.config.ConfigurableBeanFactory;
+import org.springframework.beans.factory.config.ConstructorArgumentValues;
+import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter;
+import org.springframework.beans.factory.config.PropertiesFactoryBean;
+import org.springframework.beans.factory.config.RuntimeBeanReference;
+import org.springframework.beans.factory.config.TypedStringValue;
+import org.springframework.beans.factory.support.AbstractBeanDefinition;
+import org.springframework.beans.factory.support.AbstractBeanFactory;
+import org.springframework.beans.factory.support.BeanDefinitionBuilder;
+import org.springframework.beans.factory.support.BeanDefinitionOverrideException;
+import org.springframework.beans.factory.support.ChildBeanDefinition;
+import org.springframework.beans.factory.support.DefaultListableBeanFactory;
+import org.springframework.beans.factory.support.ManagedList;
+import org.springframework.beans.factory.support.PropertiesBeanDefinitionReader;
+import org.springframework.beans.factory.support.RootBeanDefinition;
+import org.springframework.beans.factory.xml.ConstructorDependenciesBean;
+import org.springframework.beans.propertyeditors.CustomNumberEditor;
+import org.springframework.core.MethodParameter;
+import org.springframework.core.ResolvableType;
+import org.springframework.core.annotation.AnnotationAwareOrderComparator;
+import org.springframework.core.convert.converter.Converter;
+import org.springframework.core.convert.support.DefaultConversionService;
+import org.springframework.core.convert.support.GenericConversionService;
+import org.springframework.core.io.Resource;
+import org.springframework.core.io.UrlResource;
+import org.springframework.lang.Nullable;
+import org.springframework.tests.Assume;
+import org.springframework.tests.TestGroup;
+import org.springframework.tests.sample.beans.DependenciesBean;
+import org.springframework.tests.sample.beans.DerivedTestBean;
+import org.springframework.tests.sample.beans.ITestBean;
+import org.springframework.tests.sample.beans.LifecycleBean;
+import org.springframework.tests.sample.beans.NestedTestBean;
+import org.springframework.tests.sample.beans.SideEffectBean;
+import org.springframework.tests.sample.beans.TestBean;
+import org.springframework.tests.sample.beans.factory.DummyFactory;
+import org.springframework.util.SerializationTestUtils;
+import org.springframework.util.StopWatch;
+import org.springframework.util.StringValueResolver;
+
+import static org.hamcrest.Matchers.containsString;
+import static org.hamcrest.Matchers.equalTo;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.mockito.BDDMockito.eq;
+import static org.mockito.BDDMockito.given;
+import static org.mockito.BDDMockito.isNull;
+import static org.mockito.BDDMockito.mock;
+import static org.mockito.BDDMockito.never;
+import static org.mockito.BDDMockito.verify;
+import static org.mockito.BDDMockito.when;
+
+/**
+ * Tests properties population and autowire behavior.
+ *
+ * @author Rod Johnson
+ * @author Juergen Hoeller
+ * @author Rick Evans
+ * @author Sam Brannen
+ * @author Chris Beams
+ * @author Phillip Webb
+ * @author Stephane Nicoll
+ */
+public abstract class AbstractDefaultListableBeanFactoryTests {
+
+ private static final Log factoryLog = LogFactory.getLog(DefaultListableBeanFactory.class);
+
+ public abstract DefaultListableBeanFactory getInstance();
+
+ public abstract DefaultListableBeanFactory getInstance(@Nullable BeanFactory parentBeanFactory);
+
+ @Rule
+ public ExpectedException thrown = ExpectedException.none();
+
+
+ @Test
+ public void testUnreferencedSingletonWasInstantiated() {
+ KnowsIfInstantiated.clearInstantiationRecord();
+ DefaultListableBeanFactory lbf = getInstance();
+ Properties p = new Properties();
+ p.setProperty("x1.(class)", KnowsIfInstantiated.class.getName());
+ assertTrue("singleton not instantiated", !KnowsIfInstantiated.wasInstantiated());
+ (new PropertiesBeanDefinitionReader(lbf)).registerBeanDefinitions(p);
+ lbf.preInstantiateSingletons();
+ assertTrue("singleton was instantiated", KnowsIfInstantiated.wasInstantiated());
+ }
+
+ @Test
+ public void testLazyInitialization() {
+ KnowsIfInstantiated.clearInstantiationRecord();
+ DefaultListableBeanFactory lbf = getInstance();
+ Properties p = new Properties();
+ p.setProperty("x1.(class)", KnowsIfInstantiated.class.getName());
+ p.setProperty("x1.(lazy-init)", "true");
+ assertTrue("singleton not instantiated", !KnowsIfInstantiated.wasInstantiated());
+ (new PropertiesBeanDefinitionReader(lbf)).registerBeanDefinitions(p);
+ assertTrue("singleton not instantiated", !KnowsIfInstantiated.wasInstantiated());
+ lbf.preInstantiateSingletons();
+
+ assertTrue("singleton not instantiated", !KnowsIfInstantiated.wasInstantiated());
+ lbf.getBean("x1");
+ assertTrue("singleton was instantiated", KnowsIfInstantiated.wasInstantiated());
+ }
+
+ @Test
+ public void testFactoryBeanDidNotCreatePrototype() {
+ DefaultListableBeanFactory lbf = getInstance();
+ Properties p = new Properties();
+ p.setProperty("x1.(class)", DummyFactory.class.getName());
+ // Reset static state
+ DummyFactory.reset();
+ p.setProperty("x1.singleton", "false");
+ assertTrue("prototype not instantiated", !DummyFactory.wasPrototypeCreated());
+ (new PropertiesBeanDefinitionReader(lbf)).registerBeanDefinitions(p);
+ assertTrue("prototype not instantiated", !DummyFactory.wasPrototypeCreated());
+ assertEquals(TestBean.class, lbf.getType("x1"));
+ lbf.preInstantiateSingletons();
+
+ assertTrue("prototype not instantiated", !DummyFactory.wasPrototypeCreated());
+ lbf.getBean("x1");
+ assertEquals(TestBean.class, lbf.getType("x1"));
+ assertTrue(lbf.containsBean("x1"));
+ assertTrue(lbf.containsBean("&x1"));
+ assertTrue("prototype was instantiated", DummyFactory.wasPrototypeCreated());
+ }
+
+ @Test
+ public void testPrototypeFactoryBeanIgnoredByNonEagerTypeMatching() {
+ DefaultListableBeanFactory lbf = getInstance();
+ Properties p = new Properties();
+ p.setProperty("x1.(class)", DummyFactory.class.getName());
+ // Reset static state
+ DummyFactory.reset();
+ p.setProperty("x1.(singleton)", "false");
+ p.setProperty("x1.singleton", "false");
+ (new PropertiesBeanDefinitionReader(lbf)).registerBeanDefinitions(p);
+
+ assertTrue("prototype not instantiated", !DummyFactory.wasPrototypeCreated());
+ String[] beanNames = lbf.getBeanNamesForType(TestBean.class, true, false);
+ assertEquals(0, beanNames.length);
+ beanNames = lbf.getBeanNamesForAnnotation(SuppressWarnings.class);
+ assertEquals(0, beanNames.length);
+
+ assertFalse(lbf.containsSingleton("x1"));
+ assertTrue(lbf.containsBean("x1"));
+ assertTrue(lbf.containsBean("&x1"));
+ assertFalse(lbf.isSingleton("x1"));
+ assertFalse(lbf.isSingleton("&x1"));
+ assertTrue(lbf.isPrototype("x1"));
+ assertTrue(lbf.isPrototype("&x1"));
+ assertTrue(lbf.isTypeMatch("x1", TestBean.class));
+ assertFalse(lbf.isTypeMatch("&x1", TestBean.class));
+ assertTrue(lbf.isTypeMatch("&x1", DummyFactory.class));
+ assertTrue(lbf.isTypeMatch("&x1", ResolvableType.forClass(DummyFactory.class)));
+ assertTrue(lbf.isTypeMatch("&x1", ResolvableType.forClassWithGenerics(FactoryBean.class, Object.class)));
+ assertFalse(lbf.isTypeMatch("&x1", ResolvableType.forClassWithGenerics(FactoryBean.class, String.class)));
+ assertEquals(TestBean.class, lbf.getType("x1"));
+ assertEquals(DummyFactory.class, lbf.getType("&x1"));
+ assertTrue("prototype not instantiated", !DummyFactory.wasPrototypeCreated());
+ }
+
+ @Test
+ public void testSingletonFactoryBeanIgnoredByNonEagerTypeMatching() {
+ DefaultListableBeanFactory lbf = getInstance();
+ Properties p = new Properties();
+ p.setProperty("x1.(class)", DummyFactory.class.getName());
+ // Reset static state
+ DummyFactory.reset();
+ p.setProperty("x1.(singleton)", "false");
+ p.setProperty("x1.singleton", "true");
+ (new PropertiesBeanDefinitionReader(lbf)).registerBeanDefinitions(p);
+
+ assertTrue("prototype not instantiated", !DummyFactory.wasPrototypeCreated());
+ String[] beanNames = lbf.getBeanNamesForType(TestBean.class, true, false);
+ assertEquals(0, beanNames.length);
+ beanNames = lbf.getBeanNamesForAnnotation(SuppressWarnings.class);
+ assertEquals(0, beanNames.length);
+
+ assertFalse(lbf.containsSingleton("x1"));
+ assertTrue(lbf.containsBean("x1"));
+ assertTrue(lbf.containsBean("&x1"));
+ assertFalse(lbf.isSingleton("x1"));
+ assertFalse(lbf.isSingleton("&x1"));
+ assertTrue(lbf.isPrototype("x1"));
+ assertTrue(lbf.isPrototype("&x1"));
+ assertTrue(lbf.isTypeMatch("x1", TestBean.class));
+ assertFalse(lbf.isTypeMatch("&x1", TestBean.class));
+ assertTrue(lbf.isTypeMatch("&x1", DummyFactory.class));
+ assertTrue(lbf.isTypeMatch("&x1", ResolvableType.forClass(DummyFactory.class)));
+ assertTrue(lbf.isTypeMatch("&x1", ResolvableType.forClassWithGenerics(FactoryBean.class, Object.class)));
+ assertFalse(lbf.isTypeMatch("&x1", ResolvableType.forClassWithGenerics(FactoryBean.class, String.class)));
+ assertEquals(TestBean.class, lbf.getType("x1"));
+ assertEquals(DummyFactory.class, lbf.getType("&x1"));
+ assertTrue("prototype not instantiated", !DummyFactory.wasPrototypeCreated());
+ }
+
+ @Test
+ public void testNonInitializedFactoryBeanIgnoredByNonEagerTypeMatching() {
+ DefaultListableBeanFactory lbf = getInstance();
+ Properties p = new Properties();
+ p.setProperty("x1.(class)", DummyFactory.class.getName());
+ // Reset static state
+ DummyFactory.reset();
+ p.setProperty("x1.singleton", "false");
+ (new PropertiesBeanDefinitionReader(lbf)).registerBeanDefinitions(p);
+
+ assertTrue("prototype not instantiated", !DummyFactory.wasPrototypeCreated());
+ String[] beanNames = lbf.getBeanNamesForType(TestBean.class, true, false);
+ assertEquals(0, beanNames.length);
+ beanNames = lbf.getBeanNamesForAnnotation(SuppressWarnings.class);
+ assertEquals(0, beanNames.length);
+
+ assertFalse(lbf.containsSingleton("x1"));
+ assertTrue(lbf.containsBean("x1"));
+ assertTrue(lbf.containsBean("&x1"));
+ assertFalse(lbf.isSingleton("x1"));
+ assertTrue(lbf.isSingleton("&x1"));
+ assertTrue(lbf.isPrototype("x1"));
+ assertFalse(lbf.isPrototype("&x1"));
+ assertTrue(lbf.isTypeMatch("x1", TestBean.class));
+ assertFalse(lbf.isTypeMatch("&x1", TestBean.class));
+ assertTrue(lbf.isTypeMatch("&x1", DummyFactory.class));
+ assertTrue(lbf.isTypeMatch("&x1", ResolvableType.forClass(DummyFactory.class)));
+ assertTrue(lbf.isTypeMatch("&x1", ResolvableType.forClassWithGenerics(FactoryBean.class, Object.class)));
+ assertFalse(lbf.isTypeMatch("&x1", ResolvableType.forClassWithGenerics(FactoryBean.class, String.class)));
+ assertEquals(TestBean.class, lbf.getType("x1"));
+ assertEquals(DummyFactory.class, lbf.getType("&x1"));
+ assertTrue("prototype not instantiated", !DummyFactory.wasPrototypeCreated());
+ }
+
+ @Test
+ public void testInitializedFactoryBeanFoundByNonEagerTypeMatching() {
+ DefaultListableBeanFactory lbf = getInstance();
+ Properties p = new Properties();
+ p.setProperty("x1.(class)", DummyFactory.class.getName());
+ // Reset static state
+ DummyFactory.reset();
+ p.setProperty("x1.singleton", "false");
+ (new PropertiesBeanDefinitionReader(lbf)).registerBeanDefinitions(p);
+ lbf.preInstantiateSingletons();
+
+ assertTrue("prototype not instantiated", !DummyFactory.wasPrototypeCreated());
+ String[] beanNames = lbf.getBeanNamesForType(TestBean.class, true, false);
+ assertEquals(1, beanNames.length);
+ assertEquals("x1", beanNames[0]);
+ assertTrue(lbf.containsSingleton("x1"));
+ assertTrue(lbf.containsBean("x1"));
+ assertTrue(lbf.containsBean("&x1"));
+ assertTrue(lbf.containsLocalBean("x1"));
+ assertTrue(lbf.containsLocalBean("&x1"));
+ assertFalse(lbf.isSingleton("x1"));
+ assertTrue(lbf.isSingleton("&x1"));
+ assertTrue(lbf.isPrototype("x1"));
+ assertFalse(lbf.isPrototype("&x1"));
+ assertTrue(lbf.isTypeMatch("x1", TestBean.class));
+ assertFalse(lbf.isTypeMatch("&x1", TestBean.class));
+ assertTrue(lbf.isTypeMatch("&x1", DummyFactory.class));
+ assertTrue(lbf.isTypeMatch("x1", Object.class));
+ assertTrue(lbf.isTypeMatch("&x1", Object.class));
+ assertEquals(TestBean.class, lbf.getType("x1"));
+ assertEquals(DummyFactory.class, lbf.getType("&x1"));
+ assertTrue("prototype not instantiated", !DummyFactory.wasPrototypeCreated());
+
+ lbf.registerAlias("x1", "x2");
+ assertTrue(lbf.containsBean("x2"));
+ assertTrue(lbf.containsBean("&x2"));
+ assertTrue(lbf.containsLocalBean("x2"));
+ assertTrue(lbf.containsLocalBean("&x2"));
+ assertFalse(lbf.isSingleton("x2"));
+ assertTrue(lbf.isSingleton("&x2"));
+ assertTrue(lbf.isPrototype("x2"));
+ assertFalse(lbf.isPrototype("&x2"));
+ assertTrue(lbf.isTypeMatch("x2", TestBean.class));
+ assertFalse(lbf.isTypeMatch("&x2", TestBean.class));
+ assertTrue(lbf.isTypeMatch("&x2", DummyFactory.class));
+ assertTrue(lbf.isTypeMatch("x2", Object.class));
+ assertTrue(lbf.isTypeMatch("&x2", Object.class));
+ assertEquals(TestBean.class, lbf.getType("x2"));
+ assertEquals(DummyFactory.class, lbf.getType("&x2"));
+ assertEquals(1, lbf.getAliases("x1").length);
+ assertEquals("x2", lbf.getAliases("x1")[0]);
+ assertEquals(1, lbf.getAliases("&x1").length);
+ assertEquals("&x2", lbf.getAliases("&x1")[0]);
+ assertEquals(1, lbf.getAliases("x2").length);
+ assertEquals("x1", lbf.getAliases("x2")[0]);
+ assertEquals(1, lbf.getAliases("&x2").length);
+ assertEquals("&x1", lbf.getAliases("&x2")[0]);
+ }
+
+ @Test
+ public void testStaticFactoryMethodFoundByNonEagerTypeMatching() {
+ DefaultListableBeanFactory lbf = getInstance();
+ RootBeanDefinition rbd = new RootBeanDefinition(TestBeanFactory.class);
+ rbd.setFactoryMethodName("createTestBean");
+ lbf.registerBeanDefinition("x1", rbd);
+
+ TestBeanFactory.initialized = false;
+ String[] beanNames = lbf.getBeanNamesForType(TestBean.class, true, false);
+ assertEquals(1, beanNames.length);
+ assertEquals("x1", beanNames[0]);
+ assertFalse(lbf.containsSingleton("x1"));
+ assertTrue(lbf.containsBean("x1"));
+ assertFalse(lbf.containsBean("&x1"));
+ assertTrue(lbf.isSingleton("x1"));
+ assertFalse(lbf.isSingleton("&x1"));
+ assertFalse(lbf.isPrototype("x1"));
+ assertFalse(lbf.isPrototype("&x1"));
+ assertTrue(lbf.isTypeMatch("x1", TestBean.class));
+ assertFalse(lbf.isTypeMatch("&x1", TestBean.class));
+ assertEquals(TestBean.class, lbf.getType("x1"));
+ assertEquals(null, lbf.getType("&x1"));
+ assertFalse(TestBeanFactory.initialized);
+ }
+
+ @Test
+ public void testStaticPrototypeFactoryMethodFoundByNonEagerTypeMatching() {
+ DefaultListableBeanFactory lbf = getInstance();
+ RootBeanDefinition rbd = new RootBeanDefinition(TestBeanFactory.class);
+ rbd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
+ rbd.setFactoryMethodName("createTestBean");
+ lbf.registerBeanDefinition("x1", rbd);
+
+ TestBeanFactory.initialized = false;
+ String[] beanNames = lbf.getBeanNamesForType(TestBean.class, true, false);
+ assertEquals(1, beanNames.length);
+ assertEquals("x1", beanNames[0]);
+ assertFalse(lbf.containsSingleton("x1"));
+ assertTrue(lbf.containsBean("x1"));
+ assertFalse(lbf.containsBean("&x1"));
+ assertFalse(lbf.isSingleton("x1"));
+ assertFalse(lbf.isSingleton("&x1"));
+ assertTrue(lbf.isPrototype("x1"));
+ assertFalse(lbf.isPrototype("&x1"));
+ assertTrue(lbf.isTypeMatch("x1", TestBean.class));
+ assertFalse(lbf.isTypeMatch("&x1", TestBean.class));
+ assertEquals(TestBean.class, lbf.getType("x1"));
+ assertEquals(null, lbf.getType("&x1"));
+ assertFalse(TestBeanFactory.initialized);
+ }
+
+ @Test
+ public void testNonStaticFactoryMethodFoundByNonEagerTypeMatching() {
+ DefaultListableBeanFactory lbf = getInstance();
+ RootBeanDefinition factoryBd = new RootBeanDefinition(TestBeanFactory.class);
+ lbf.registerBeanDefinition("factory", factoryBd);
+ RootBeanDefinition rbd = new RootBeanDefinition(TestBeanFactory.class);
+ rbd.setFactoryBeanName("factory");
+ rbd.setFactoryMethodName("createTestBeanNonStatic");
+ lbf.registerBeanDefinition("x1", rbd);
+
+ TestBeanFactory.initialized = false;
+ String[] beanNames = lbf.getBeanNamesForType(TestBean.class, true, false);
+ assertEquals(1, beanNames.length);
+ assertEquals("x1", beanNames[0]);
+ assertFalse(lbf.containsSingleton("x1"));
+ assertTrue(lbf.containsBean("x1"));
+ assertFalse(lbf.containsBean("&x1"));
+ assertTrue(lbf.isSingleton("x1"));
+ assertFalse(lbf.isSingleton("&x1"));
+ assertFalse(lbf.isPrototype("x1"));
+ assertFalse(lbf.isPrototype("&x1"));
+ assertTrue(lbf.isTypeMatch("x1", TestBean.class));
+ assertFalse(lbf.isTypeMatch("&x1", TestBean.class));
+ assertEquals(TestBean.class, lbf.getType("x1"));
+ assertEquals(null, lbf.getType("&x1"));
+ assertFalse(TestBeanFactory.initialized);
+ }
+
+ @Test
+ public void testNonStaticPrototypeFactoryMethodFoundByNonEagerTypeMatching() {
+ DefaultListableBeanFactory lbf = getInstance();
+ RootBeanDefinition factoryBd = new RootBeanDefinition(TestBeanFactory.class);
+ lbf.registerBeanDefinition("factory", factoryBd);
+ RootBeanDefinition rbd = new RootBeanDefinition();
+ rbd.setFactoryBeanName("factory");
+ rbd.setFactoryMethodName("createTestBeanNonStatic");
+ rbd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
+ lbf.registerBeanDefinition("x1", rbd);
+
+ TestBeanFactory.initialized = false;
+ String[] beanNames = lbf.getBeanNamesForType(TestBean.class, true, false);
+ assertEquals(1, beanNames.length);
+ assertEquals("x1", beanNames[0]);
+ assertFalse(lbf.containsSingleton("x1"));
+ assertTrue(lbf.containsBean("x1"));
+ assertFalse(lbf.containsBean("&x1"));
+ assertTrue(lbf.containsLocalBean("x1"));
+ assertFalse(lbf.containsLocalBean("&x1"));
+ assertFalse(lbf.isSingleton("x1"));
+ assertFalse(lbf.isSingleton("&x1"));
+ assertTrue(lbf.isPrototype("x1"));
+ assertFalse(lbf.isPrototype("&x1"));
+ assertTrue(lbf.isTypeMatch("x1", TestBean.class));
+ assertFalse(lbf.isTypeMatch("&x1", TestBean.class));
+ assertTrue(lbf.isTypeMatch("x1", Object.class));
+ assertFalse(lbf.isTypeMatch("&x1", Object.class));
+ assertEquals(TestBean.class, lbf.getType("x1"));
+ assertEquals(null, lbf.getType("&x1"));
+ assertFalse(TestBeanFactory.initialized);
+
+ lbf.registerAlias("x1", "x2");
+ assertTrue(lbf.containsBean("x2"));
+ assertFalse(lbf.containsBean("&x2"));
+ assertTrue(lbf.containsLocalBean("x2"));
+ assertFalse(lbf.containsLocalBean("&x2"));
+ assertFalse(lbf.isSingleton("x2"));
+ assertFalse(lbf.isSingleton("&x2"));
+ assertTrue(lbf.isPrototype("x2"));
+ assertFalse(lbf.isPrototype("&x2"));
+ assertTrue(lbf.isTypeMatch("x2", TestBean.class));
+ assertFalse(lbf.isTypeMatch("&x2", TestBean.class));
+ assertTrue(lbf.isTypeMatch("x2", Object.class));
+ assertFalse(lbf.isTypeMatch("&x2", Object.class));
+ assertEquals(TestBean.class, lbf.getType("x2"));
+ assertEquals(null, lbf.getType("&x2"));
+ assertEquals(1, lbf.getAliases("x1").length);
+ assertEquals("x2", lbf.getAliases("x1")[0]);
+ assertEquals(1, lbf.getAliases("&x1").length);
+ assertEquals("&x2", lbf.getAliases("&x1")[0]);
+ assertEquals(1, lbf.getAliases("x2").length);
+ assertEquals("x1", lbf.getAliases("x2")[0]);
+ assertEquals(1, lbf.getAliases("&x2").length);
+ assertEquals("&x1", lbf.getAliases("&x2")[0]);
+ }
+
+ @Test
+ public void testEmpty() {
+ ListableBeanFactory lbf = getInstance();
+ assertTrue("No beans defined --> array != null", lbf.getBeanDefinitionNames() != null);
+ assertTrue("No beans defined after no arg constructor", lbf.getBeanDefinitionNames().length == 0);
+ assertTrue("No beans defined after no arg constructor", lbf.getBeanDefinitionCount() == 0);
+ }
+
+ @Test
+ public void testEmptyPropertiesPopulation() {
+ DefaultListableBeanFactory lbf = getInstance();
+ Properties p = new Properties();
+ (new PropertiesBeanDefinitionReader(lbf)).registerBeanDefinitions(p);
+ assertTrue("No beans defined after ignorable invalid", lbf.getBeanDefinitionCount() == 0);
+ }
+
+ @Test
+ public void testHarmlessIgnorableRubbish() {
+ DefaultListableBeanFactory lbf = getInstance();
+ Properties p = new Properties();
+ p.setProperty("foo", "bar");
+ p.setProperty("qwert", "er");
+ (new PropertiesBeanDefinitionReader(lbf)).registerBeanDefinitions(p, "test");
+ assertTrue("No beans defined after harmless ignorable rubbish", lbf.getBeanDefinitionCount() == 0);
+ }
+
+ @Test
+ public void testPropertiesPopulationWithNullPrefix() {
+ DefaultListableBeanFactory lbf = getInstance();
+ Properties p = new Properties();
+ p.setProperty("test.(class)", TestBean.class.getName());
+ p.setProperty("test.name", "Tony");
+ p.setProperty("test.age", "48");
+ int count = (new PropertiesBeanDefinitionReader(lbf)).registerBeanDefinitions(p);
+ assertTrue("1 beans registered, not " + count, count == 1);
+ testSingleTestBean(lbf);
+ }
+
+ @Test
+ public void testPropertiesPopulationWithPrefix() {
+ String PREFIX = "beans.";
+ DefaultListableBeanFactory lbf = getInstance();
+ Properties p = new Properties();
+ p.setProperty(PREFIX + "test.(class)", TestBean.class.getName());
+ p.setProperty(PREFIX + "test.name", "Tony");
+ p.setProperty(PREFIX + "test.age", "0x30");
+ int count = (new PropertiesBeanDefinitionReader(lbf)).registerBeanDefinitions(p, PREFIX);
+ assertTrue("1 beans registered, not " + count, count == 1);
+ testSingleTestBean(lbf);
+ }
+
+ @Test
+ public void testSimpleReference() {
+ String PREFIX = "beans.";
+ DefaultListableBeanFactory lbf = getInstance();
+ Properties p = new Properties();
+
+ p.setProperty(PREFIX + "rod.(class)", TestBean.class.getName());
+ p.setProperty(PREFIX + "rod.name", "Rod");
+
+ p.setProperty(PREFIX + "kerry.(class)", TestBean.class.getName());
+ p.setProperty(PREFIX + "kerry.name", "Kerry");
+ p.setProperty(PREFIX + "kerry.age", "35");
+ p.setProperty(PREFIX + "kerry.spouse(ref)", "rod");
+
+ int count = (new PropertiesBeanDefinitionReader(lbf)).registerBeanDefinitions(p, PREFIX);
+ assertTrue("2 beans registered, not " + count, count == 2);
+
+ TestBean kerry = lbf.getBean("kerry", TestBean.class);
+ assertTrue("Kerry name is Kerry", "Kerry".equals(kerry.getName()));
+ ITestBean spouse = kerry.getSpouse();
+ assertTrue("Kerry spouse is non null", spouse != null);
+ assertTrue("Kerry spouse name is Rod", "Rod".equals(spouse.getName()));
+ }
+
+ @Test
+ public void testPropertiesWithDotsInKey() {
+ DefaultListableBeanFactory lbf = getInstance();
+ Properties p = new Properties();
+
+ p.setProperty("tb.(class)", TestBean.class.getName());
+ p.setProperty("tb.someMap[my.key]", "my.value");
+
+ int count = (new PropertiesBeanDefinitionReader(lbf)).registerBeanDefinitions(p);
+ assertTrue("1 beans registered, not " + count, count == 1);
+ assertEquals(1, lbf.getBeanDefinitionCount());
+
+ TestBean tb = lbf.getBean("tb", TestBean.class);
+ assertEquals("my.value", tb.getSomeMap().get("my.key"));
+ }
+
+ @Test
+ public void testUnresolvedReference() {
+ String PREFIX = "beans.";
+ DefaultListableBeanFactory lbf = getInstance();
+ Properties p = new Properties();
+
+ try {
+ p.setProperty(PREFIX + "kerry.(class)", TestBean.class.getName());
+ p.setProperty(PREFIX + "kerry.name", "Kerry");
+ p.setProperty(PREFIX + "kerry.age", "35");
+ p.setProperty(PREFIX + "kerry.spouse(ref)", "rod");
+
+ (new PropertiesBeanDefinitionReader(lbf)).registerBeanDefinitions(p, PREFIX);
+
+ lbf.getBean("kerry");
+ fail("Unresolved reference should have been detected");
+ }
+ catch (BeansException ex) {
+ // cool
+ }
+ }
+
+ @Test
+ public void testSelfReference() {
+ DefaultListableBeanFactory lbf = getInstance();
+ MutablePropertyValues pvs = new MutablePropertyValues();
+ pvs.add("spouse", new RuntimeBeanReference("self"));
+ RootBeanDefinition bd = new RootBeanDefinition(TestBean.class);
+ bd.setPropertyValues(pvs);
+ lbf.registerBeanDefinition("self", bd);
+ TestBean self = (TestBean) lbf.getBean("self");
+ assertEquals(self, self.getSpouse());
+ }
+
+ @Test
+ public void testPossibleMatches() {
+ try {
+ DefaultListableBeanFactory lbf = getInstance();
+ MutablePropertyValues pvs = new MutablePropertyValues();
+ pvs.add("ag", "foobar");
+ RootBeanDefinition bd = new RootBeanDefinition(TestBean.class);
+ bd.setPropertyValues(pvs);
+ lbf.registerBeanDefinition("tb", bd);
+ lbf.getBean("tb");
+ fail("Should throw exception on invalid property");
+ }
+ catch (BeanCreationException ex) {
+ assertTrue(ex.getCause() instanceof NotWritablePropertyException);
+ NotWritablePropertyException cause = (NotWritablePropertyException) ex.getCause();
+ // expected
+ assertEquals(1, cause.getPossibleMatches().length);
+ assertEquals("age", cause.getPossibleMatches()[0]);
+ }
+ }
+
+ @Test
+ public void testPrototype() {
+ DefaultListableBeanFactory lbf = getInstance();
+ Properties p = new Properties();
+ p.setProperty("kerry.(class)", TestBean.class.getName());
+ p.setProperty("kerry.age", "35");
+ (new PropertiesBeanDefinitionReader(lbf)).registerBeanDefinitions(p);
+ TestBean kerry1 = (TestBean) lbf.getBean("kerry");
+ TestBean kerry2 = (TestBean) lbf.getBean("kerry");
+ assertTrue("Non null", kerry1 != null);
+ assertTrue("Singletons equal", kerry1 == kerry2);
+
+ lbf = getInstance();
+ p = new Properties();
+ p.setProperty("kerry.(class)", TestBean.class.getName());
+ p.setProperty("kerry.(scope)", "prototype");
+ p.setProperty("kerry.age", "35");
+ (new PropertiesBeanDefinitionReader(lbf)).registerBeanDefinitions(p);
+ kerry1 = (TestBean) lbf.getBean("kerry");
+ kerry2 = (TestBean) lbf.getBean("kerry");
+ assertTrue("Non null", kerry1 != null);
+ assertTrue("Prototypes NOT equal", kerry1 != kerry2);
+
+ lbf = getInstance();
+ p = new Properties();
+ p.setProperty("kerry.(class)", TestBean.class.getName());
+ p.setProperty("kerry.(scope)", "singleton");
+ p.setProperty("kerry.age", "35");
+ (new PropertiesBeanDefinitionReader(lbf)).registerBeanDefinitions(p);
+ kerry1 = (TestBean) lbf.getBean("kerry");
+ kerry2 = (TestBean) lbf.getBean("kerry");
+ assertTrue("Non null", kerry1 != null);
+ assertTrue("Specified singletons equal", kerry1 == kerry2);
+ }
+
+ @Test
+ public void testPrototypeCircleLeadsToException() {
+ DefaultListableBeanFactory lbf = getInstance();
+ Properties p = new Properties();
+ p.setProperty("kerry.(class)", TestBean.class.getName());
+ p.setProperty("kerry.(singleton)", "false");
+ p.setProperty("kerry.age", "35");
+ p.setProperty("kerry.spouse", "*rod");
+ p.setProperty("rod.(class)", TestBean.class.getName());
+ p.setProperty("rod.(singleton)", "false");
+ p.setProperty("rod.age", "34");
+ p.setProperty("rod.spouse", "*kerry");
+
+ (new PropertiesBeanDefinitionReader(lbf)).registerBeanDefinitions(p);
+ try {
+ lbf.getBean("kerry");
+ fail("Should have thrown BeanCreationException");
+ }
+ catch (BeanCreationException ex) {
+ // expected
+ assertTrue(ex.contains(BeanCurrentlyInCreationException.class));
+ }
+ }
+
+ @Test
+ public void testPrototypeExtendsPrototype() {
+ DefaultListableBeanFactory lbf = getInstance();
+ Properties p = new Properties();
+ p.setProperty("wife.(class)", TestBean.class.getName());
+ p.setProperty("wife.name", "kerry");
+
+ p.setProperty("kerry.(parent)", "wife");
+ p.setProperty("kerry.age", "35");
+ (new PropertiesBeanDefinitionReader(lbf)).registerBeanDefinitions(p);
+ TestBean kerry1 = (TestBean) lbf.getBean("kerry");
+ TestBean kerry2 = (TestBean) lbf.getBean("kerry");
+ assertEquals("kerry", kerry1.getName());
+ assertNotNull("Non null", kerry1);
+ assertTrue("Singletons equal", kerry1 == kerry2);
+
+ lbf = getInstance();
+ p = new Properties();
+ p.setProperty("wife.(class)", TestBean.class.getName());
+ p.setProperty("wife.name", "kerry");
+ p.setProperty("wife.(singleton)", "false");
+ p.setProperty("kerry.(parent)", "wife");
+ p.setProperty("kerry.(singleton)", "false");
+ p.setProperty("kerry.age", "35");
+ (new PropertiesBeanDefinitionReader(lbf)).registerBeanDefinitions(p);
+ assertFalse(lbf.isSingleton("kerry"));
+ kerry1 = (TestBean) lbf.getBean("kerry");
+ kerry2 = (TestBean) lbf.getBean("kerry");
+ assertTrue("Non null", kerry1 != null);
+ assertTrue("Prototypes NOT equal", kerry1 != kerry2);
+
+ lbf = getInstance();
+ p = new Properties();
+ p.setProperty("kerry.(class)", TestBean.class.getName());
+ p.setProperty("kerry.(singleton)", "true");
+ p.setProperty("kerry.age", "35");
+ (new PropertiesBeanDefinitionReader(lbf)).registerBeanDefinitions(p);
+ kerry1 = (TestBean) lbf.getBean("kerry");
+ kerry2 = (TestBean) lbf.getBean("kerry");
+ assertTrue("Non null", kerry1 != null);
+ assertTrue("Specified singletons equal", kerry1 == kerry2);
+ }
+
+ @Test
+ public void testCanReferenceParentBeanFromChildViaAlias() {
+ final String EXPECTED_NAME = "Juergen";
+ final int EXPECTED_AGE = 41;
+
+ RootBeanDefinition parentDefinition = new RootBeanDefinition(TestBean.class);
+ parentDefinition.setAbstract(true);
+ parentDefinition.getPropertyValues().add("name", EXPECTED_NAME);
+ parentDefinition.getPropertyValues().add("age", EXPECTED_AGE);
+
+ ChildBeanDefinition childDefinition = new ChildBeanDefinition("alias");
+
+ DefaultListableBeanFactory factory = getInstance();
+ factory.registerBeanDefinition("parent", parentDefinition);
+ factory.registerBeanDefinition("child", childDefinition);
+ factory.registerAlias("parent", "alias");
+
+ TestBean child = (TestBean) factory.getBean("child");
+ assertEquals(EXPECTED_NAME, child.getName());
+ assertEquals(EXPECTED_AGE, child.getAge());
+
+ assertEquals("Use cached merged bean definition",
+ factory.getMergedBeanDefinition("child"), factory.getMergedBeanDefinition("child"));
+ }
+
+ @Test
+ public void testGetTypeWorksAfterParentChildMerging() {
+ RootBeanDefinition parentDefinition = new RootBeanDefinition(TestBean.class);
+ ChildBeanDefinition childDefinition = new ChildBeanDefinition("parent", DerivedTestBean.class, null, null);
+
+ DefaultListableBeanFactory factory = getInstance();
+ factory.registerBeanDefinition("parent", parentDefinition);
+ factory.registerBeanDefinition("child", childDefinition);
+ factory.freezeConfiguration();
+
+ assertEquals(TestBean.class, factory.getType("parent"));
+ assertEquals(DerivedTestBean.class, factory.getType("child"));
+ }
+
+ @Test
+ public void testNameAlreadyBound() {
+ DefaultListableBeanFactory lbf = getInstance();
+ Properties p = new Properties();
+ p.setProperty("kerry.(class)", TestBean.class.getName());
+ p.setProperty("kerry.age", "35");
+ (new PropertiesBeanDefinitionReader(lbf)).registerBeanDefinitions(p);
+ try {
+ (new PropertiesBeanDefinitionReader(lbf)).registerBeanDefinitions(p);
+ }
+ catch (BeanDefinitionStoreException ex) {
+ assertEquals("kerry", ex.getBeanName());
+ // expected
+ }
+ }
+
+ private void testSingleTestBean(ListableBeanFactory lbf) {
+ assertTrue("1 beans defined", lbf.getBeanDefinitionCount() == 1);
+ String[] names = lbf.getBeanDefinitionNames();
+ assertTrue(names != lbf.getBeanDefinitionNames());
+ assertTrue("Array length == 1", names.length == 1);
+ assertTrue("0th element == test", names[0].equals("test"));
+ TestBean tb = (TestBean) lbf.getBean("test");
+ assertTrue("Test is non null", tb != null);
+ assertTrue("Test bean name is Tony", "Tony".equals(tb.getName()));
+ assertTrue("Test bean age is 48", tb.getAge() == 48);
+ }
+
+ @Test
+ public void testAliasCircle() {
+ DefaultListableBeanFactory lbf = getInstance();
+ lbf.registerAlias("test", "test2");
+ lbf.registerAlias("test2", "test3");
+
+ try {
+ lbf.registerAlias("test3", "test2");
+ fail("Should have thrown IllegalStateException");
+ }
+ catch (IllegalStateException ex) {
+ // expected
+ }
+
+ try {
+ lbf.registerAlias("test3", "test");
+ fail("Should have thrown IllegalStateException");
+ }
+ catch (IllegalStateException ex) {
+ // expected
+ }
+
+ lbf.registerAlias("test", "test3");
+ }
+
+ @Test
+ public void testBeanDefinitionOverriding() {
+ DefaultListableBeanFactory lbf = getInstance();
+ lbf.registerBeanDefinition("test", new RootBeanDefinition(TestBean.class));
+ lbf.registerBeanDefinition("test", new RootBeanDefinition(NestedTestBean.class));
+ lbf.registerAlias("otherTest", "test2");
+ lbf.registerAlias("test", "test2");
+ assertTrue(lbf.getBean("test") instanceof NestedTestBean);
+ assertTrue(lbf.getBean("test2") instanceof NestedTestBean);
+ }
+
+ @Test
+ public void testBeanDefinitionRemoval() {
+ DefaultListableBeanFactory lbf = getInstance();
+ lbf.setAllowBeanDefinitionOverriding(false);
+ lbf.registerBeanDefinition("test", new RootBeanDefinition(TestBean.class));
+ lbf.registerAlias("test", "test2");
+ lbf.preInstantiateSingletons();
+ lbf.removeBeanDefinition("test");
+ lbf.removeAlias("test2");
+ lbf.registerBeanDefinition("test", new RootBeanDefinition(NestedTestBean.class));
+ lbf.registerAlias("test", "test2");
+ assertTrue(lbf.getBean("test") instanceof NestedTestBean);
+ assertTrue(lbf.getBean("test2") instanceof NestedTestBean);
+ }
+
+ @Test
+ public void testBeanDefinitionOverridingNotAllowed() {
+ DefaultListableBeanFactory lbf = getInstance();
+ lbf.setAllowBeanDefinitionOverriding(false);
+ BeanDefinition oldDef = new RootBeanDefinition(TestBean.class);
+ BeanDefinition newDef = new RootBeanDefinition(NestedTestBean.class);
+ lbf.registerBeanDefinition("test", oldDef);
+ try {
+ lbf.registerBeanDefinition("test", newDef);
+ fail("Should have thrown BeanDefinitionOverrideException");
+ }
+ catch (BeanDefinitionOverrideException ex) {
+ assertEquals("test", ex.getBeanName());
+ assertSame(newDef, ex.getBeanDefinition());
+ assertSame(oldDef, ex.getExistingDefinition());
+ }
+ }
+
+ @Test
+ public void testBeanDefinitionOverridingWithAlias() {
+ DefaultListableBeanFactory lbf = getInstance();
+ lbf.registerBeanDefinition("test", new RootBeanDefinition(TestBean.class));
+ lbf.registerAlias("test", "testAlias");
+ lbf.registerBeanDefinition("test", new RootBeanDefinition(NestedTestBean.class));
+ lbf.registerAlias("test", "testAlias");
+ assertTrue(lbf.getBean("test") instanceof NestedTestBean);
+ assertTrue(lbf.getBean("testAlias") instanceof NestedTestBean);
+ }
+
+ @Test
+ public void testAliasChaining() {
+ DefaultListableBeanFactory lbf = getInstance();
+ lbf.registerBeanDefinition("test", new RootBeanDefinition(NestedTestBean.class));
+ lbf.registerAlias("test", "testAlias");
+ lbf.registerAlias("testAlias", "testAlias2");
+ lbf.registerAlias("testAlias2", "testAlias3");
+ Object bean = lbf.getBean("test");
+ assertSame(bean, lbf.getBean("testAlias"));
+ assertSame(bean, lbf.getBean("testAlias2"));
+ assertSame(bean, lbf.getBean("testAlias3"));
+ }
+
+ @Test
+ public void testBeanReferenceWithNewSyntax() {
+ DefaultListableBeanFactory lbf = getInstance();
+ Properties p = new Properties();
+ p.setProperty("r.(class)", TestBean.class.getName());
+ p.setProperty("r.name", "rod");
+ p.setProperty("k.(class)", TestBean.class.getName());
+ p.setProperty("k.name", "kerry");
+ p.setProperty("k.spouse", "*r");
+ (new PropertiesBeanDefinitionReader(lbf)).registerBeanDefinitions(p);
+ TestBean k = (TestBean) lbf.getBean("k");
+ TestBean r = (TestBean) lbf.getBean("r");
+ assertTrue(k.getSpouse() == r);
+ }
+
+ @Test
+ public void testCanEscapeBeanReferenceSyntax() {
+ String name = "*name";
+ DefaultListableBeanFactory lbf = getInstance();
+ Properties p = new Properties();
+ p.setProperty("r.(class)", TestBean.class.getName());
+ p.setProperty("r.name", "*" + name);
+ (new PropertiesBeanDefinitionReader(lbf)).registerBeanDefinitions(p);
+ TestBean r = (TestBean) lbf.getBean("r");
+ assertTrue(r.getName().equals(name));
+ }
+
+ @Test
+ public void testCustomEditor() {
+ DefaultListableBeanFactory lbf = getInstance();
+ lbf.addPropertyEditorRegistrar(new PropertyEditorRegistrar() {
+ @Override
+ public void registerCustomEditors(PropertyEditorRegistry registry) {
+ NumberFormat nf = NumberFormat.getInstance(Locale.GERMAN);
+ registry.registerCustomEditor(Float.class, new CustomNumberEditor(Float.class, nf, true));
+ }
+ });
+ MutablePropertyValues pvs = new MutablePropertyValues();
+ pvs.add("myFloat", "1,1");
+ RootBeanDefinition bd = new RootBeanDefinition(TestBean.class);
+ bd.setPropertyValues(pvs);
+ lbf.registerBeanDefinition("testBean", bd);
+ TestBean testBean = (TestBean) lbf.getBean("testBean");
+ assertTrue(testBean.getMyFloat().floatValue() == 1.1f);
+ }
+
+ @Test
+ public void testCustomConverter() {
+ DefaultListableBeanFactory lbf = getInstance();
+ GenericConversionService conversionService = new DefaultConversionService();
+ conversionService.addConverter(new Converter() {
+ @Override
+ public Float convert(String source) {
+ try {
+ NumberFormat nf = NumberFormat.getInstance(Locale.GERMAN);
+ return nf.parse(source).floatValue();
+ }
+ catch (ParseException ex) {
+ throw new IllegalArgumentException(ex);
+ }
+ }
+ });
+ lbf.setConversionService(conversionService);
+ MutablePropertyValues pvs = new MutablePropertyValues();
+ pvs.add("myFloat", "1,1");
+ RootBeanDefinition bd = new RootBeanDefinition(TestBean.class);
+ bd.setPropertyValues(pvs);
+ lbf.registerBeanDefinition("testBean", bd);
+ TestBean testBean = (TestBean) lbf.getBean("testBean");
+ assertTrue(testBean.getMyFloat().floatValue() == 1.1f);
+ }
+
+ @Test
+ public void testCustomEditorWithBeanReference() {
+ DefaultListableBeanFactory lbf = getInstance();
+ lbf.addPropertyEditorRegistrar(new PropertyEditorRegistrar() {
+ @Override
+ public void registerCustomEditors(PropertyEditorRegistry registry) {
+ NumberFormat nf = NumberFormat.getInstance(Locale.GERMAN);
+ registry.registerCustomEditor(Float.class, new CustomNumberEditor(Float.class, nf, true));
+ }
+ });
+ MutablePropertyValues pvs = new MutablePropertyValues();
+ pvs.add("myFloat", new RuntimeBeanReference("myFloat"));
+ RootBeanDefinition bd = new RootBeanDefinition(TestBean.class);
+ bd.setPropertyValues(pvs);
+ lbf.registerBeanDefinition("testBean", bd);
+ lbf.registerSingleton("myFloat", "1,1");
+ TestBean testBean = (TestBean) lbf.getBean("testBean");
+ assertTrue(testBean.getMyFloat().floatValue() == 1.1f);
+ }
+
+ @Test
+ public void testCustomTypeConverter() {
+ DefaultListableBeanFactory lbf = getInstance();
+ NumberFormat nf = NumberFormat.getInstance(Locale.GERMAN);
+ lbf.setTypeConverter(new CustomTypeConverter(nf));
+ MutablePropertyValues pvs = new MutablePropertyValues();
+ pvs.add("myFloat", "1,1");
+ ConstructorArgumentValues cav = new ConstructorArgumentValues();
+ cav.addIndexedArgumentValue(0, "myName");
+ cav.addIndexedArgumentValue(1, "myAge");
+ lbf.registerBeanDefinition("testBean", new RootBeanDefinition(TestBean.class, cav, pvs));
+ TestBean testBean = (TestBean) lbf.getBean("testBean");
+ assertEquals("myName", testBean.getName());
+ assertEquals(5, testBean.getAge());
+ assertTrue(testBean.getMyFloat().floatValue() == 1.1f);
+ }
+
+ @Test
+ public void testCustomTypeConverterWithBeanReference() {
+ DefaultListableBeanFactory lbf = getInstance();
+ NumberFormat nf = NumberFormat.getInstance(Locale.GERMAN);
+ lbf.setTypeConverter(new CustomTypeConverter(nf));
+ MutablePropertyValues pvs = new MutablePropertyValues();
+ pvs.add("myFloat", new RuntimeBeanReference("myFloat"));
+ ConstructorArgumentValues cav = new ConstructorArgumentValues();
+ cav.addIndexedArgumentValue(0, "myName");
+ cav.addIndexedArgumentValue(1, "myAge");
+ lbf.registerBeanDefinition("testBean", new RootBeanDefinition(TestBean.class, cav, pvs));
+ lbf.registerSingleton("myFloat", "1,1");
+ TestBean testBean = (TestBean) lbf.getBean("testBean");
+ assertEquals("myName", testBean.getName());
+ assertEquals(5, testBean.getAge());
+ assertTrue(testBean.getMyFloat().floatValue() == 1.1f);
+ }
+
+ @Test
+ public void testRegisterExistingSingletonWithReference() {
+ DefaultListableBeanFactory lbf = getInstance();
+ Properties p = new Properties();
+ p.setProperty("test.(class)", TestBean.class.getName());
+ p.setProperty("test.name", "Tony");
+ p.setProperty("test.age", "48");
+ p.setProperty("test.spouse(ref)", "singletonObject");
+ (new PropertiesBeanDefinitionReader(lbf)).registerBeanDefinitions(p);
+ Object singletonObject = new TestBean();
+ lbf.registerSingleton("singletonObject", singletonObject);
+
+ assertTrue(lbf.isSingleton("singletonObject"));
+ assertEquals(TestBean.class, lbf.getType("singletonObject"));
+ TestBean test = (TestBean) lbf.getBean("test");
+ assertEquals(singletonObject, lbf.getBean("singletonObject"));
+ assertEquals(singletonObject, test.getSpouse());
+
+ Map, ?> beansOfType = lbf.getBeansOfType(TestBean.class, false, true);
+ assertEquals(2, beansOfType.size());
+ assertTrue(beansOfType.containsValue(test));
+ assertTrue(beansOfType.containsValue(singletonObject));
+
+ beansOfType = lbf.getBeansOfType(null, false, true);
+ assertEquals(2, beansOfType.size());
+
+ Iterator beanNames = lbf.getBeanNamesIterator();
+ assertEquals("test", beanNames.next());
+ assertEquals("singletonObject", beanNames.next());
+ assertFalse(beanNames.hasNext());
+
+ assertTrue(lbf.containsSingleton("test"));
+ assertTrue(lbf.containsSingleton("singletonObject"));
+ assertTrue(lbf.containsBeanDefinition("test"));
+ assertFalse(lbf.containsBeanDefinition("singletonObject"));
+ }
+
+ @Test
+ public void testRegisterExistingSingletonWithNameOverriding() {
+ DefaultListableBeanFactory lbf = getInstance();
+ Properties p = new Properties();
+ p.setProperty("test.(class)", TestBean.class.getName());
+ p.setProperty("test.name", "Tony");
+ p.setProperty("test.age", "48");
+ p.setProperty("test.spouse(ref)", "singletonObject");
+ (new PropertiesBeanDefinitionReader(lbf)).registerBeanDefinitions(p);
+ lbf.registerBeanDefinition("singletonObject", new RootBeanDefinition(PropertiesFactoryBean.class));
+ Object singletonObject = new TestBean();
+ lbf.registerSingleton("singletonObject", singletonObject);
+ lbf.preInstantiateSingletons();
+
+ assertTrue(lbf.isSingleton("singletonObject"));
+ assertEquals(TestBean.class, lbf.getType("singletonObject"));
+ TestBean test = (TestBean) lbf.getBean("test");
+ assertEquals(singletonObject, lbf.getBean("singletonObject"));
+ assertEquals(singletonObject, test.getSpouse());
+
+ Map, ?> beansOfType = lbf.getBeansOfType(TestBean.class, false, true);
+ assertEquals(2, beansOfType.size());
+ assertTrue(beansOfType.containsValue(test));
+ assertTrue(beansOfType.containsValue(singletonObject));
+
+ beansOfType = lbf.getBeansOfType(null, false, true);
+
+ Iterator beanNames = lbf.getBeanNamesIterator();
+ assertEquals("test", beanNames.next());
+ assertEquals("singletonObject", beanNames.next());
+ assertFalse(beanNames.hasNext());
+ assertEquals(2, beansOfType.size());
+
+ assertTrue(lbf.containsSingleton("test"));
+ assertTrue(lbf.containsSingleton("singletonObject"));
+ assertTrue(lbf.containsBeanDefinition("test"));
+ assertTrue(lbf.containsBeanDefinition("singletonObject"));
+ }
+
+ @Test
+ public void testRegisterExistingSingletonWithAutowire() {
+ DefaultListableBeanFactory lbf = getInstance();
+ MutablePropertyValues pvs = new MutablePropertyValues();
+ pvs.add("name", "Tony");
+ pvs.add("age", "48");
+ RootBeanDefinition bd = new RootBeanDefinition(DependenciesBean.class);
+ bd.setPropertyValues(pvs);
+ bd.setDependencyCheck(RootBeanDefinition.DEPENDENCY_CHECK_OBJECTS);
+ bd.setAutowireMode(RootBeanDefinition.AUTOWIRE_BY_TYPE);
+ lbf.registerBeanDefinition("test", bd);
+ Object singletonObject = new TestBean();
+ lbf.registerSingleton("singletonObject", singletonObject);
+
+ assertTrue(lbf.containsBean("singletonObject"));
+ assertTrue(lbf.isSingleton("singletonObject"));
+ assertEquals(TestBean.class, lbf.getType("singletonObject"));
+ assertEquals(0, lbf.getAliases("singletonObject").length);
+ DependenciesBean test = (DependenciesBean) lbf.getBean("test");
+ assertEquals(singletonObject, lbf.getBean("singletonObject"));
+ assertEquals(singletonObject, test.getSpouse());
+ }
+
+ @Test
+ public void testRegisterExistingSingletonWithAlreadyBound() {
+ DefaultListableBeanFactory lbf = getInstance();
+ Object singletonObject = new TestBean();
+ lbf.registerSingleton("singletonObject", singletonObject);
+ try {
+ lbf.registerSingleton("singletonObject", singletonObject);
+ fail("Should have thrown IllegalStateException");
+ }
+ catch (IllegalStateException ex) {
+ // expected
+ }
+ }
+
+ @Test
+ public void testReregisterBeanDefinition() {
+ DefaultListableBeanFactory lbf = getInstance();
+ RootBeanDefinition bd1 = new RootBeanDefinition(TestBean.class);
+ bd1.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
+ lbf.registerBeanDefinition("testBean", bd1);
+ assertTrue(lbf.getBean("testBean") instanceof TestBean);
+ RootBeanDefinition bd2 = new RootBeanDefinition(NestedTestBean.class);
+ bd2.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
+ lbf.registerBeanDefinition("testBean", bd2);
+ assertTrue(lbf.getBean("testBean") instanceof NestedTestBean);
+ }
+
+ @Test
+ public void testArrayPropertyWithAutowiring() throws MalformedURLException {
+ DefaultListableBeanFactory bf = getInstance();
+ bf.registerSingleton("resource1", new UrlResource("http://localhost:8080"));
+ bf.registerSingleton("resource2", new UrlResource("http://localhost:9090"));
+
+ RootBeanDefinition rbd = new RootBeanDefinition(ArrayBean.class);
+ rbd.setAutowireMode(RootBeanDefinition.AUTOWIRE_BY_TYPE);
+ bf.registerBeanDefinition("arrayBean", rbd);
+ ArrayBean ab = (ArrayBean) bf.getBean("arrayBean");
+
+ assertEquals(new UrlResource("http://localhost:8080"), ab.getResourceArray()[0]);
+ assertEquals(new UrlResource("http://localhost:9090"), ab.getResourceArray()[1]);
+ }
+
+ @Test
+ public void testArrayPropertyWithOptionalAutowiring() throws MalformedURLException {
+ DefaultListableBeanFactory bf = getInstance();
+
+ RootBeanDefinition rbd = new RootBeanDefinition(ArrayBean.class);
+ rbd.setAutowireMode(RootBeanDefinition.AUTOWIRE_BY_TYPE);
+ bf.registerBeanDefinition("arrayBean", rbd);
+ ArrayBean ab = (ArrayBean) bf.getBean("arrayBean");
+
+ assertNull(ab.getResourceArray());
+ }
+
+ @Test
+ public void testArrayConstructorWithAutowiring() {
+ DefaultListableBeanFactory bf = getInstance();
+ bf.registerSingleton("integer1", new Integer(4));
+ bf.registerSingleton("integer2", new Integer(5));
+
+ RootBeanDefinition rbd = new RootBeanDefinition(ArrayBean.class);
+ rbd.setAutowireMode(RootBeanDefinition.AUTOWIRE_CONSTRUCTOR);
+ bf.registerBeanDefinition("arrayBean", rbd);
+ ArrayBean ab = (ArrayBean) bf.getBean("arrayBean");
+
+ assertEquals(new Integer(4), ab.getIntegerArray()[0]);
+ assertEquals(new Integer(5), ab.getIntegerArray()[1]);
+ }
+
+ @Test
+ public void testArrayConstructorWithOptionalAutowiring() {
+ DefaultListableBeanFactory bf = getInstance();
+
+ RootBeanDefinition rbd = new RootBeanDefinition(ArrayBean.class);
+ rbd.setAutowireMode(RootBeanDefinition.AUTOWIRE_CONSTRUCTOR);
+ bf.registerBeanDefinition("arrayBean", rbd);
+ ArrayBean ab = (ArrayBean) bf.getBean("arrayBean");
+
+ assertNull(ab.getIntegerArray());
+ }
+
+ @Test
+ public void testDoubleArrayConstructorWithAutowiring() throws MalformedURLException {
+ DefaultListableBeanFactory bf = getInstance();
+ bf.registerSingleton("integer1", new Integer(4));
+ bf.registerSingleton("integer2", new Integer(5));
+ bf.registerSingleton("resource1", new UrlResource("http://localhost:8080"));
+ bf.registerSingleton("resource2", new UrlResource("http://localhost:9090"));
+
+ RootBeanDefinition rbd = new RootBeanDefinition(ArrayBean.class);
+ rbd.setAutowireMode(RootBeanDefinition.AUTOWIRE_CONSTRUCTOR);
+ bf.registerBeanDefinition("arrayBean", rbd);
+ ArrayBean ab = (ArrayBean) bf.getBean("arrayBean");
+
+ assertEquals(new Integer(4), ab.getIntegerArray()[0]);
+ assertEquals(new Integer(5), ab.getIntegerArray()[1]);
+ assertEquals(new UrlResource("http://localhost:8080"), ab.getResourceArray()[0]);
+ assertEquals(new UrlResource("http://localhost:9090"), ab.getResourceArray()[1]);
+ }
+
+ @Test
+ public void testDoubleArrayConstructorWithOptionalAutowiring() throws MalformedURLException {
+ DefaultListableBeanFactory bf = getInstance();
+ bf.registerSingleton("resource1", new UrlResource("http://localhost:8080"));
+ bf.registerSingleton("resource2", new UrlResource("http://localhost:9090"));
+
+ RootBeanDefinition rbd = new RootBeanDefinition(ArrayBean.class);
+ rbd.setAutowireMode(RootBeanDefinition.AUTOWIRE_CONSTRUCTOR);
+ bf.registerBeanDefinition("arrayBean", rbd);
+ ArrayBean ab = (ArrayBean) bf.getBean("arrayBean");
+
+ assertNull(ab.getIntegerArray());
+ assertNull(ab.getResourceArray());
+ }
+
+ @Test
+ public void testExpressionInStringArray() {
+ DefaultListableBeanFactory bf = getInstance();
+ BeanExpressionResolver beanExpressionResolver = mock(BeanExpressionResolver.class);
+ when(beanExpressionResolver.evaluate(eq("#{foo}"), ArgumentMatchers.any(BeanExpressionContext.class)))
+ .thenReturn("classpath:/org/springframework/beans/factory/xml/util.properties");
+ bf.setBeanExpressionResolver(beanExpressionResolver);
+
+ RootBeanDefinition rbd = new RootBeanDefinition(PropertiesFactoryBean.class);
+ MutablePropertyValues pvs = new MutablePropertyValues();
+ pvs.add("locations", new String[]{"#{foo}"});
+ rbd.setPropertyValues(pvs);
+ bf.registerBeanDefinition("myProperties", rbd);
+ Properties properties = (Properties) bf.getBean("myProperties");
+ assertEquals("bar", properties.getProperty("foo"));
+ }
+
+ @Test
+ public void testAutowireWithNoDependencies() {
+ DefaultListableBeanFactory lbf = getInstance();
+ RootBeanDefinition bd = new RootBeanDefinition(TestBean.class);
+ lbf.registerBeanDefinition("rod", bd);
+ assertEquals(1, lbf.getBeanDefinitionCount());
+ Object registered = lbf.autowire(NoDependencies.class, AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, false);
+ assertEquals(1, lbf.getBeanDefinitionCount());
+ assertTrue(registered instanceof NoDependencies);
+ }
+
+ @Test
+ public void testAutowireWithSatisfiedJavaBeanDependency() {
+ DefaultListableBeanFactory lbf = getInstance();
+ MutablePropertyValues pvs = new MutablePropertyValues();
+ pvs.add("name", "Rod");
+ RootBeanDefinition bd = new RootBeanDefinition(TestBean.class);
+ bd.setPropertyValues(pvs);
+ lbf.registerBeanDefinition("rod", bd);
+ assertEquals(1, lbf.getBeanDefinitionCount());
+ // Depends on age, name and spouse (TestBean)
+ Object registered = lbf.autowire(DependenciesBean.class, AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, true);
+ assertEquals(1, lbf.getBeanDefinitionCount());
+ DependenciesBean kerry = (DependenciesBean) registered;
+ TestBean rod = (TestBean) lbf.getBean("rod");
+ assertSame(rod, kerry.getSpouse());
+ }
+
+ @Test
+ public void testAutowireWithSatisfiedConstructorDependency() {
+ DefaultListableBeanFactory lbf = getInstance();
+ MutablePropertyValues pvs = new MutablePropertyValues();
+ pvs.add("name", "Rod");
+ RootBeanDefinition bd = new RootBeanDefinition(TestBean.class);
+ bd.setPropertyValues(pvs);
+ lbf.registerBeanDefinition("rod", bd);
+ assertEquals(1, lbf.getBeanDefinitionCount());
+ Object registered = lbf.autowire(ConstructorDependency.class, AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR, false);
+ assertEquals(1, lbf.getBeanDefinitionCount());
+ ConstructorDependency kerry = (ConstructorDependency) registered;
+ TestBean rod = (TestBean) lbf.getBean("rod");
+ assertSame(rod, kerry.spouse);
+ }
+
+ @Test
+ public void testAutowireWithTwoMatchesForConstructorDependency() {
+ DefaultListableBeanFactory lbf = getInstance();
+ RootBeanDefinition bd = new RootBeanDefinition(TestBean.class);
+ lbf.registerBeanDefinition("rod", bd);
+ RootBeanDefinition bd2 = new RootBeanDefinition(TestBean.class);
+ lbf.registerBeanDefinition("rod2", bd2);
+ try {
+ lbf.autowire(ConstructorDependency.class, AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR, false);
+ fail("Should have thrown UnsatisfiedDependencyException");
+ }
+ catch (UnsatisfiedDependencyException ex) {
+ // expected
+ assertTrue(ex.getMessage().contains("rod"));
+ assertTrue(ex.getMessage().contains("rod2"));
+ }
+ }
+
+ @Test
+ public void testAutowireWithUnsatisfiedConstructorDependency() {
+ DefaultListableBeanFactory lbf = getInstance();
+ MutablePropertyValues pvs = new MutablePropertyValues();
+ pvs.addPropertyValue(new PropertyValue("name", "Rod"));
+ RootBeanDefinition bd = new RootBeanDefinition(TestBean.class);
+ bd.setPropertyValues(pvs);
+ lbf.registerBeanDefinition("rod", bd);
+ assertEquals(1, lbf.getBeanDefinitionCount());
+ try {
+ lbf.autowire(UnsatisfiedConstructorDependency.class, AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR, true);
+ fail("Should have unsatisfied constructor dependency on SideEffectBean");
+ }
+ catch (UnsatisfiedDependencyException ex) {
+ // expected
+ }
+ }
+
+ @Test
+ public void testAutowireConstructor() {
+ DefaultListableBeanFactory lbf = getInstance();
+ RootBeanDefinition bd = new RootBeanDefinition(TestBean.class);
+ lbf.registerBeanDefinition("spouse", bd);
+ ConstructorDependenciesBean bean = (ConstructorDependenciesBean)
+ lbf.autowire(ConstructorDependenciesBean.class, AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR, true);
+ Object spouse = lbf.getBean("spouse");
+ assertTrue(bean.getSpouse1() == spouse);
+ assertTrue(BeanFactoryUtils.beanOfType(lbf, TestBean.class) == spouse);
+ }
+
+ @Test
+ public void testAutowireBeanByName() {
+ DefaultListableBeanFactory lbf = getInstance();
+ RootBeanDefinition bd = new RootBeanDefinition(TestBean.class);
+ lbf.registerBeanDefinition("spouse", bd);
+ DependenciesBean bean = (DependenciesBean)
+ lbf.autowire(DependenciesBean.class, AutowireCapableBeanFactory.AUTOWIRE_BY_NAME, true);
+ TestBean spouse = (TestBean) lbf.getBean("spouse");
+ assertEquals(spouse, bean.getSpouse());
+ assertTrue(BeanFactoryUtils.beanOfType(lbf, TestBean.class) == spouse);
+ }
+
+ @Test
+ public void testAutowireBeanByNameWithDependencyCheck() {
+ DefaultListableBeanFactory lbf = getInstance();
+ RootBeanDefinition bd = new RootBeanDefinition(TestBean.class);
+ lbf.registerBeanDefinition("spous", bd);
+ try {
+ lbf.autowire(DependenciesBean.class, AutowireCapableBeanFactory.AUTOWIRE_BY_NAME, true);
+ fail("Should have thrown UnsatisfiedDependencyException");
+ }
+ catch (UnsatisfiedDependencyException ex) {
+ // expected
+ }
+ }
+
+ @Test
+ public void testAutowireBeanByNameWithNoDependencyCheck() {
+ DefaultListableBeanFactory lbf = getInstance();
+ RootBeanDefinition bd = new RootBeanDefinition(TestBean.class);
+ lbf.registerBeanDefinition("spous", bd);
+ DependenciesBean bean = (DependenciesBean)
+ lbf.autowire(DependenciesBean.class, AutowireCapableBeanFactory.AUTOWIRE_BY_NAME, false);
+ assertNull(bean.getSpouse());
+ }
+
+ @Test
+ public void testDependsOnCycle() {
+ DefaultListableBeanFactory lbf = getInstance();
+ RootBeanDefinition bd1 = new RootBeanDefinition(TestBean.class);
+ bd1.setDependsOn("tb2");
+ lbf.registerBeanDefinition("tb1", bd1);
+ RootBeanDefinition bd2 = new RootBeanDefinition(TestBean.class);
+ bd2.setDependsOn("tb1");
+ lbf.registerBeanDefinition("tb2", bd2);
+ try {
+ lbf.preInstantiateSingletons();
+ fail("Should have thrown BeanCreationException");
+ }
+ catch (BeanCreationException ex) {
+ // expected
+ assertTrue(ex.getMessage().contains("Circular"));
+ assertTrue(ex.getMessage().contains("'tb2'"));
+ assertTrue(ex.getMessage().contains("'tb1'"));
+ }
+ }
+
+ @Test
+ public void testImplicitDependsOnCycle() {
+ DefaultListableBeanFactory lbf = getInstance();
+ RootBeanDefinition bd1 = new RootBeanDefinition(TestBean.class);
+ bd1.setDependsOn("tb2");
+ lbf.registerBeanDefinition("tb1", bd1);
+ RootBeanDefinition bd2 = new RootBeanDefinition(TestBean.class);
+ bd2.setDependsOn("tb3");
+ lbf.registerBeanDefinition("tb2", bd2);
+ RootBeanDefinition bd3 = new RootBeanDefinition(TestBean.class);
+ bd3.setDependsOn("tb1");
+ lbf.registerBeanDefinition("tb3", bd3);
+ try {
+ lbf.preInstantiateSingletons();
+ fail("Should have thrown BeanCreationException");
+ }
+ catch (BeanCreationException ex) {
+ // expected
+ assertTrue(ex.getMessage().contains("Circular"));
+ assertTrue(ex.getMessage().contains("'tb3'"));
+ assertTrue(ex.getMessage().contains("'tb1'"));
+ }
+ }
+
+ @Test(expected = NoSuchBeanDefinitionException.class)
+ public void testGetBeanByTypeWithNoneFound() {
+ DefaultListableBeanFactory lbf = getInstance();
+ lbf.getBean(TestBean.class);
+ }
+
+ @Test
+ public void testGetBeanByTypeDefinedInParent() {
+ DefaultListableBeanFactory parent = getInstance();
+ RootBeanDefinition bd1 = new RootBeanDefinition(TestBean.class);
+ parent.registerBeanDefinition("bd1", bd1);
+ DefaultListableBeanFactory lbf = getInstance(parent);
+ TestBean bean = lbf.getBean(TestBean.class);
+ assertThat(bean.getBeanName(), equalTo("bd1"));
+ }
+
+ @Test(expected = NoUniqueBeanDefinitionException.class)
+ public void testGetBeanByTypeWithAmbiguity() {
+ DefaultListableBeanFactory lbf = getInstance();
+ RootBeanDefinition bd1 = new RootBeanDefinition(TestBean.class);
+ RootBeanDefinition bd2 = new RootBeanDefinition(TestBean.class);
+ lbf.registerBeanDefinition("bd1", bd1);
+ lbf.registerBeanDefinition("bd2", bd2);
+ lbf.getBean(TestBean.class);
+ }
+
+ @Test
+ public void testGetBeanByTypeWithPrimary() {
+ DefaultListableBeanFactory lbf = getInstance();
+ RootBeanDefinition bd1 = new RootBeanDefinition(TestBean.class);
+ bd1.setLazyInit(true);
+ RootBeanDefinition bd2 = new RootBeanDefinition(TestBean.class);
+ bd2.setPrimary(true);
+ lbf.registerBeanDefinition("bd1", bd1);
+ lbf.registerBeanDefinition("bd2", bd2);
+ TestBean bean = lbf.getBean(TestBean.class);
+ assertThat(bean.getBeanName(), equalTo("bd2"));
+ assertFalse(lbf.containsSingleton("bd1"));
+ }
+
+ @Test
+ public void testGetBeanByTypeWithMultiplePrimary() {
+ DefaultListableBeanFactory lbf = getInstance();
+ RootBeanDefinition bd1 = new RootBeanDefinition(TestBean.class);
+ bd1.setPrimary(true);
+ RootBeanDefinition bd2 = new RootBeanDefinition(TestBean.class);
+ bd2.setPrimary(true);
+ lbf.registerBeanDefinition("bd1", bd1);
+ lbf.registerBeanDefinition("bd2", bd2);
+ thrown.expect(NoUniqueBeanDefinitionException.class);
+ thrown.expectMessage(containsString("more than one 'primary'"));
+ lbf.getBean(TestBean.class);
+ }
+
+ @Test
+ public void testGetBeanByTypeWithPriority() {
+ DefaultListableBeanFactory lbf = getInstance();
+ lbf.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
+ RootBeanDefinition bd1 = new RootBeanDefinition(HighPriorityTestBean.class);
+ RootBeanDefinition bd2 = new RootBeanDefinition(LowPriorityTestBean.class);
+ RootBeanDefinition bd3 = new RootBeanDefinition(NullTestBeanFactoryBean.class);
+ lbf.registerBeanDefinition("bd1", bd1);
+ lbf.registerBeanDefinition("bd2", bd2);
+ lbf.registerBeanDefinition("bd3", bd3);
+ lbf.preInstantiateSingletons();
+ TestBean bean = lbf.getBean(TestBean.class);
+ assertThat(bean.getBeanName(), equalTo("bd1"));
+ }
+
+ @Test
+ public void testMapInjectionWithPriority() {
+ DefaultListableBeanFactory lbf = getInstance();
+ lbf.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
+ RootBeanDefinition bd1 = new RootBeanDefinition(HighPriorityTestBean.class);
+ RootBeanDefinition bd2 = new RootBeanDefinition(LowPriorityTestBean.class);
+ RootBeanDefinition bd3 = new RootBeanDefinition(NullTestBeanFactoryBean.class);
+ RootBeanDefinition bd4 = new RootBeanDefinition(TestBeanRecipient.class, RootBeanDefinition.AUTOWIRE_CONSTRUCTOR, false);
+ lbf.registerBeanDefinition("bd1", bd1);
+ lbf.registerBeanDefinition("bd2", bd2);
+ lbf.registerBeanDefinition("bd3", bd3);
+ lbf.registerBeanDefinition("bd4", bd4);
+ lbf.preInstantiateSingletons();
+ TestBean bean = lbf.getBean(TestBeanRecipient.class).testBean;
+ assertThat(bean.getBeanName(), equalTo("bd1"));
+ }
+
+ @Test
+ public void testGetBeanByTypeWithMultiplePriority() {
+ DefaultListableBeanFactory lbf = getInstance();
+ lbf.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
+ RootBeanDefinition bd1 = new RootBeanDefinition(HighPriorityTestBean.class);
+ RootBeanDefinition bd2 = new RootBeanDefinition(HighPriorityTestBean.class);
+ lbf.registerBeanDefinition("bd1", bd1);
+ lbf.registerBeanDefinition("bd2", bd2);
+ thrown.expect(NoUniqueBeanDefinitionException.class);
+ thrown.expectMessage(containsString("Multiple beans found with the same priority"));
+ thrown.expectMessage(containsString("5")); // conflicting priority
+ lbf.getBean(TestBean.class);
+ }
+
+ @Test
+ public void testGetBeanByTypeWithPriorityAndNullInstance() {
+ DefaultListableBeanFactory lbf = getInstance();
+ lbf.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
+ RootBeanDefinition bd1 = new RootBeanDefinition(HighPriorityTestBean.class);
+ RootBeanDefinition bd2 = new RootBeanDefinition(NullTestBeanFactoryBean.class);
+ lbf.registerBeanDefinition("bd1", bd1);
+ lbf.registerBeanDefinition("bd2", bd2);
+ TestBean bean = lbf.getBean(TestBean.class);
+ assertThat(bean.getBeanName(), equalTo("bd1"));
+ }
+
+ @Test
+ public void testGetBeanByTypePrimaryHasPrecedenceOverPriority() {
+ DefaultListableBeanFactory lbf = getInstance();
+ lbf.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
+ RootBeanDefinition bd1 = new RootBeanDefinition(HighPriorityTestBean.class);
+ RootBeanDefinition bd2 = new RootBeanDefinition(TestBean.class);
+ bd2.setPrimary(true);
+ lbf.registerBeanDefinition("bd1", bd1);
+ lbf.registerBeanDefinition("bd2", bd2);
+ TestBean bean = lbf.getBean(TestBean.class);
+ assertThat(bean.getBeanName(), equalTo("bd2"));
+ }
+
+ @Test
+ public void testGetBeanByTypeFiltersOutNonAutowireCandidates() {
+ DefaultListableBeanFactory lbf = getInstance();
+ RootBeanDefinition bd1 = new RootBeanDefinition(TestBean.class);
+ RootBeanDefinition bd2 = new RootBeanDefinition(TestBean.class);
+ RootBeanDefinition na1 = new RootBeanDefinition(TestBean.class);
+ na1.setAutowireCandidate(false);
+
+ lbf.registerBeanDefinition("bd1", bd1);
+ lbf.registerBeanDefinition("na1", na1);
+ TestBean actual = lbf.getBean(TestBean.class); // na1 was filtered
+ assertSame(lbf.getBean("bd1", TestBean.class), actual);
+
+ lbf.registerBeanDefinition("bd2", bd2);
+ try {
+ lbf.getBean(TestBean.class);
+ fail("Should have thrown NoSuchBeanDefinitionException");
+ }
+ catch (NoSuchBeanDefinitionException ex) {
+ // expected
+ }
+ }
+
+ @Test
+ public void testGetBeanByTypeInstanceWithNoneFound() {
+ DefaultListableBeanFactory lbf = getInstance();
+
+ try {
+ lbf.getBean(ConstructorDependency.class);
+ fail("Should have thrown NoSuchBeanDefinitionException");
+ }
+ catch (NoSuchBeanDefinitionException ex) {
+ // expected
+ }
+ try {
+ lbf.getBean(ConstructorDependency.class, 42);
+ fail("Should have thrown NoSuchBeanDefinitionException");
+ }
+ catch (NoSuchBeanDefinitionException ex) {
+ // expected
+ }
+
+ ObjectProvider provider = lbf.getBeanProvider(ConstructorDependency.class);
+ try {
+ provider.getObject();
+ fail("Should have thrown NoSuchBeanDefinitionException");
+ }
+ catch (NoSuchBeanDefinitionException ex) {
+ // expected
+ }
+ try {
+ provider.getObject(42);
+ fail("Should have thrown NoSuchBeanDefinitionException");
+ }
+ catch (NoSuchBeanDefinitionException ex) {
+ // expected
+ }
+ assertNull(provider.getIfAvailable());
+ assertNull(provider.getIfUnique());
+ }
+
+ @Test
+ public void testGetBeanByTypeInstanceDefinedInParent() {
+ DefaultListableBeanFactory parent = getInstance();
+ RootBeanDefinition bd1 = createConstructorDependencyBeanDefinition(99);
+ parent.registerBeanDefinition("bd1", bd1);
+ DefaultListableBeanFactory lbf = getInstance(parent);
+
+ ConstructorDependency bean = lbf.getBean(ConstructorDependency.class);
+ assertThat(bean.beanName, equalTo("bd1"));
+ assertThat(bean.spouseAge, equalTo(99));
+ bean = lbf.getBean(ConstructorDependency.class, 42);
+ assertThat(bean.beanName, equalTo("bd1"));
+ assertThat(bean.spouseAge, equalTo(42));
+
+ ObjectProvider provider = lbf.getBeanProvider(ConstructorDependency.class);
+ bean = provider.getObject();
+ assertThat(bean.beanName, equalTo("bd1"));
+ assertThat(bean.spouseAge, equalTo(99));
+ bean = provider.getObject(42);
+ assertThat(bean.beanName, equalTo("bd1"));
+ assertThat(bean.spouseAge, equalTo(42));
+ bean = provider.getIfAvailable();
+ assertThat(bean.beanName, equalTo("bd1"));
+ assertThat(bean.spouseAge, equalTo(99));
+ bean = provider.getIfUnique();
+ assertThat(bean.beanName, equalTo("bd1"));
+ assertThat(bean.spouseAge, equalTo(99));
+ }
+
+ @Test
+ public void testGetBeanByTypeInstanceWithAmbiguity() {
+ DefaultListableBeanFactory lbf = getInstance();
+ RootBeanDefinition bd1 = createConstructorDependencyBeanDefinition(99);
+ RootBeanDefinition bd2 = new RootBeanDefinition(ConstructorDependency.class);
+ bd2.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
+ bd2.getConstructorArgumentValues().addGenericArgumentValue("43");
+ lbf.registerBeanDefinition("bd1", bd1);
+ lbf.registerBeanDefinition("bd2", bd2);
+
+ try {
+ lbf.getBean(ConstructorDependency.class);
+ fail("Should have thrown NoUniqueBeanDefinitionException");
+ }
+ catch (NoUniqueBeanDefinitionException ex) {
+ // expected
+ }
+ try {
+ lbf.getBean(ConstructorDependency.class, 42);
+ fail("Should have thrown NoUniqueBeanDefinitionException");
+ }
+ catch (NoUniqueBeanDefinitionException ex) {
+ // expected
+ }
+
+ ObjectProvider provider = lbf.getBeanProvider(ConstructorDependency.class);
+ try {
+ provider.getObject();
+ fail("Should have thrown NoUniqueBeanDefinitionException");
+ }
+ catch (NoUniqueBeanDefinitionException ex) {
+ // expected
+ }
+ try {
+ provider.getObject(42);
+ fail("Should have thrown NoUniqueBeanDefinitionException");
+ }
+ catch (NoUniqueBeanDefinitionException ex) {
+ // expected
+ }
+ try {
+ provider.getIfAvailable();
+ fail("Should have thrown NoUniqueBeanDefinitionException");
+ }
+ catch (NoUniqueBeanDefinitionException ex) {
+ // expected
+ }
+ assertNull(provider.getIfUnique());
+
+ Set resolved = new HashSet<>();
+ for (ConstructorDependency instance : provider) {
+ resolved.add(instance);
+ }
+ assertEquals(2, resolved.size());
+ assertTrue(resolved.contains(lbf.getBean("bd1")));
+ assertTrue(resolved.contains(lbf.getBean("bd2")));
+
+ resolved = new HashSet<>();
+ provider.forEach(resolved::add);
+ assertEquals(2, resolved.size());
+ assertTrue(resolved.contains(lbf.getBean("bd1")));
+ assertTrue(resolved.contains(lbf.getBean("bd2")));
+
+ resolved = provider.stream().collect(Collectors.toSet());
+ assertEquals(2, resolved.size());
+ assertTrue(resolved.contains(lbf.getBean("bd1")));
+ assertTrue(resolved.contains(lbf.getBean("bd2")));
+ }
+
+ @Test
+ public void testGetBeanByTypeInstanceWithPrimary() {
+ DefaultListableBeanFactory lbf = getInstance();
+ RootBeanDefinition bd1 = createConstructorDependencyBeanDefinition(99);
+ RootBeanDefinition bd2 = createConstructorDependencyBeanDefinition(43);
+ bd2.setPrimary(true);
+ lbf.registerBeanDefinition("bd1", bd1);
+ lbf.registerBeanDefinition("bd2", bd2);
+
+ ConstructorDependency bean = lbf.getBean(ConstructorDependency.class);
+ assertThat(bean.beanName, equalTo("bd2"));
+ assertThat(bean.spouseAge, equalTo(43));
+ bean = lbf.getBean(ConstructorDependency.class, 42);
+ assertThat(bean.beanName, equalTo("bd2"));
+ assertThat(bean.spouseAge, equalTo(42));
+
+ ObjectProvider provider = lbf.getBeanProvider(ConstructorDependency.class);
+ bean = provider.getObject();
+ assertThat(bean.beanName, equalTo("bd2"));
+ assertThat(bean.spouseAge, equalTo(43));
+ bean = provider.getObject(42);
+ assertThat(bean.beanName, equalTo("bd2"));
+ assertThat(bean.spouseAge, equalTo(42));
+ bean = provider.getIfAvailable();
+ assertThat(bean.beanName, equalTo("bd2"));
+ assertThat(bean.spouseAge, equalTo(43));
+ bean = provider.getIfUnique();
+ assertThat(bean.beanName, equalTo("bd2"));
+ assertThat(bean.spouseAge, equalTo(43));
+
+ Set resolved = new HashSet<>();
+ for (ConstructorDependency instance : provider) {
+ resolved.add(instance);
+ }
+ assertEquals(2, resolved.size());
+ assertTrue(resolved.contains(lbf.getBean("bd1")));
+ assertTrue(resolved.contains(lbf.getBean("bd2")));
+
+ resolved = new HashSet<>();
+ provider.forEach(resolved::add);
+ assertEquals(2, resolved.size());
+ assertTrue(resolved.contains(lbf.getBean("bd1")));
+ assertTrue(resolved.contains(lbf.getBean("bd2")));
+
+ resolved = provider.stream().collect(Collectors.toSet());
+ assertEquals(2, resolved.size());
+ assertTrue(resolved.contains(lbf.getBean("bd1")));
+ assertTrue(resolved.contains(lbf.getBean("bd2")));
+ }
+
+ @Test
+ public void testGetBeanByTypeInstanceWithMultiplePrimary() {
+ DefaultListableBeanFactory lbf = getInstance();
+ RootBeanDefinition bd1 = createConstructorDependencyBeanDefinition(99);
+ RootBeanDefinition bd2 = createConstructorDependencyBeanDefinition(43);
+ bd1.setPrimary(true);
+ bd2.setPrimary(true);
+ lbf.registerBeanDefinition("bd1", bd1);
+ lbf.registerBeanDefinition("bd2", bd2);
+
+ thrown.expect(NoUniqueBeanDefinitionException.class);
+ thrown.expectMessage(containsString("more than one 'primary'"));
+ lbf.getBean(ConstructorDependency.class, 42);
+ }
+
+ @Test
+ public void testGetBeanByTypeInstanceFiltersOutNonAutowireCandidates() {
+ DefaultListableBeanFactory lbf = getInstance();
+ RootBeanDefinition bd1 = createConstructorDependencyBeanDefinition(99);
+ RootBeanDefinition bd2 = createConstructorDependencyBeanDefinition(43);
+ RootBeanDefinition na1 = createConstructorDependencyBeanDefinition(21);
+ na1.setAutowireCandidate(false);
+
+ lbf.registerBeanDefinition("bd1", bd1);
+ lbf.registerBeanDefinition("na1", na1);
+ ConstructorDependency actual = lbf.getBean(ConstructorDependency.class, 42); // na1 was filtered
+ assertThat(actual.beanName, equalTo("bd1"));
+
+ lbf.registerBeanDefinition("bd2", bd2);
+ try {
+ lbf.getBean(TestBean.class, 67);
+ fail("Should have thrown NoSuchBeanDefinitionException");
+ }
+ catch (NoSuchBeanDefinitionException ex) {
+ // expected
+ }
+ }
+
+ @Test
+ public void testBeanProviderSerialization() throws Exception {
+ DefaultListableBeanFactory lbf = getInstance();
+ lbf.setSerializationId("test");
+
+ ObjectProvider provider = lbf.getBeanProvider(ConstructorDependency.class);
+ ObjectProvider deserialized = (ObjectProvider) SerializationTestUtils.serializeAndDeserialize(provider);
+ try {
+ deserialized.getObject();
+ fail("Should have thrown NoSuchBeanDefinitionException");
+ }
+ catch (NoSuchBeanDefinitionException ex) {
+ // expected
+ }
+ try {
+ deserialized.getObject(42);
+ fail("Should have thrown NoSuchBeanDefinitionException");
+ }
+ catch (NoSuchBeanDefinitionException ex) {
+ // expected
+ }
+ assertNull(deserialized.getIfAvailable());
+ assertNull(deserialized.getIfUnique());
+ }
+
+ @Test
+ public void testGetBeanWithArgsNotCreatedForFactoryBeanChecking() {
+ DefaultListableBeanFactory lbf = getInstance();
+ RootBeanDefinition bd1 = new RootBeanDefinition(ConstructorDependency.class);
+ bd1.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
+ lbf.registerBeanDefinition("bd1", bd1);
+ RootBeanDefinition bd2 = new RootBeanDefinition(ConstructorDependencyFactoryBean.class);
+ bd2.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
+ lbf.registerBeanDefinition("bd2", bd2);
+
+ ConstructorDependency bean = lbf.getBean(ConstructorDependency.class, 42);
+ assertThat(bean.beanName, equalTo("bd1"));
+ assertThat(bean.spouseAge, equalTo(42));
+
+ assertEquals(1, lbf.getBeanNamesForType(ConstructorDependency.class).length);
+ assertEquals(1, lbf.getBeanNamesForType(ConstructorDependencyFactoryBean.class).length);
+ assertEquals(1, lbf.getBeanNamesForType(ResolvableType.forClassWithGenerics(FactoryBean.class, Object.class)).length);
+ assertEquals(0, lbf.getBeanNamesForType(ResolvableType.forClassWithGenerics(FactoryBean.class, String.class)).length);
+ }
+
+ private RootBeanDefinition createConstructorDependencyBeanDefinition(int age) {
+ RootBeanDefinition bd = new RootBeanDefinition(ConstructorDependency.class);
+ bd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
+ bd.getConstructorArgumentValues().addGenericArgumentValue(age);
+ return bd;
+ }
+
+ @Test
+ public void testAutowireBeanByType() {
+ DefaultListableBeanFactory lbf = getInstance();
+ RootBeanDefinition bd = new RootBeanDefinition(TestBean.class);
+ lbf.registerBeanDefinition("test", bd);
+ DependenciesBean bean = (DependenciesBean)
+ lbf.autowire(DependenciesBean.class, AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, true);
+ TestBean test = (TestBean) lbf.getBean("test");
+ assertEquals(test, bean.getSpouse());
+ }
+
+ /**
+ * Verifies that a dependency on a {@link FactoryBean} can be autowired
+ * by type , specifically addressing the JIRA issue raised in SPR-4040 .
+ */
+ @Test
+ public void testAutowireBeanWithFactoryBeanByType() {
+ DefaultListableBeanFactory lbf = getInstance();
+ RootBeanDefinition bd = new RootBeanDefinition(LazyInitFactory.class);
+ lbf.registerBeanDefinition("factoryBean", bd);
+ LazyInitFactory factoryBean = (LazyInitFactory) lbf.getBean("&factoryBean");
+ assertNotNull("The FactoryBean should have been registered.", factoryBean);
+ FactoryBeanDependentBean bean = (FactoryBeanDependentBean) lbf.autowire(FactoryBeanDependentBean.class,
+ AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, true);
+ assertEquals("The FactoryBeanDependentBean should have been autowired 'by type' with the LazyInitFactory.",
+ factoryBean, bean.getFactoryBean());
+ }
+
+ @Test
+ public void testGetTypeForAbstractFactoryBean() {
+ DefaultListableBeanFactory lbf = getInstance();
+ RootBeanDefinition bd = new RootBeanDefinition(FactoryBeanThatShouldntBeCalled.class);
+ bd.setAbstract(true);
+ lbf.registerBeanDefinition("factoryBean", bd);
+ assertNull(lbf.getType("factoryBean"));
+ }
+
+ @Test
+ public void testGetBeanNamesForTypeBeforeFactoryBeanCreation() {
+ DefaultListableBeanFactory lbf = getInstance();
+ lbf.registerBeanDefinition("factoryBean", new RootBeanDefinition(FactoryBeanThatShouldntBeCalled.class));
+ assertFalse(lbf.containsSingleton("factoryBean"));
+
+ String[] beanNames = lbf.getBeanNamesForType(Runnable.class, false, false);
+ assertEquals(1, beanNames.length);
+ assertEquals("&factoryBean", beanNames[0]);
+
+ beanNames = lbf.getBeanNamesForType(Callable.class, false, false);
+ assertEquals(1, beanNames.length);
+ assertEquals("&factoryBean", beanNames[0]);
+
+ beanNames = lbf.getBeanNamesForType(RepositoryFactoryInformation.class, false, false);
+ assertEquals(1, beanNames.length);
+ assertEquals("&factoryBean", beanNames[0]);
+
+ beanNames = lbf.getBeanNamesForType(FactoryBean.class, false, false);
+ assertEquals(1, beanNames.length);
+ assertEquals("&factoryBean", beanNames[0]);
+ }
+
+ @Test
+ public void testGetBeanNamesForTypeAfterFactoryBeanCreation() {
+ DefaultListableBeanFactory lbf = getInstance();
+ lbf.registerBeanDefinition("factoryBean", new RootBeanDefinition(FactoryBeanThatShouldntBeCalled.class));
+ lbf.getBean("&factoryBean");
+
+ String[] beanNames = lbf.getBeanNamesForType(Runnable.class, false, false);
+ assertEquals(1, beanNames.length);
+ assertEquals("&factoryBean", beanNames[0]);
+
+ beanNames = lbf.getBeanNamesForType(Callable.class, false, false);
+ assertEquals(1, beanNames.length);
+ assertEquals("&factoryBean", beanNames[0]);
+
+ beanNames = lbf.getBeanNamesForType(RepositoryFactoryInformation.class, false, false);
+ assertEquals(1, beanNames.length);
+ assertEquals("&factoryBean", beanNames[0]);
+
+ beanNames = lbf.getBeanNamesForType(FactoryBean.class, false, false);
+ assertEquals(1, beanNames.length);
+ assertEquals("&factoryBean", beanNames[0]);
+ }
+
+ /**
+ * Verifies that a dependency on a {@link FactoryBean} can not
+ * be autowired by name , as & is an illegal character in
+ * Java method names. In other words, you can't name a method
+ * {@code set&FactoryBean(...)}.
+ */
+ @Test(expected = TypeMismatchException.class)
+ public void testAutowireBeanWithFactoryBeanByName() {
+ DefaultListableBeanFactory lbf = getInstance();
+ RootBeanDefinition bd = new RootBeanDefinition(LazyInitFactory.class);
+ lbf.registerBeanDefinition("factoryBean", bd);
+ LazyInitFactory factoryBean = (LazyInitFactory) lbf.getBean("&factoryBean");
+ assertNotNull("The FactoryBean should have been registered.", factoryBean);
+ lbf.autowire(FactoryBeanDependentBean.class, AutowireCapableBeanFactory.AUTOWIRE_BY_NAME, true);
+ }
+
+ @Test
+ public void testAutowireBeanByTypeWithTwoMatches() {
+ DefaultListableBeanFactory lbf = getInstance();
+ RootBeanDefinition bd = new RootBeanDefinition(TestBean.class);
+ RootBeanDefinition bd2 = new RootBeanDefinition(TestBean.class);
+ lbf.registerBeanDefinition("test", bd);
+ lbf.registerBeanDefinition("spouse", bd2);
+ try {
+ lbf.autowire(DependenciesBean.class, AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, true);
+ fail("Should have thrown UnsatisfiedDependencyException");
+ }
+ catch (UnsatisfiedDependencyException ex) {
+ // expected
+ assertTrue(ex.getMessage().contains("test"));
+ assertTrue(ex.getMessage().contains("spouse"));
+ }
+ }
+
+ @Test
+ public void testAutowireBeanByTypeWithDependencyCheck() {
+ DefaultListableBeanFactory lbf = getInstance();
+ try {
+ lbf.autowire(DependenciesBean.class, AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, true);
+ fail("Should have thrown UnsatisfiedDependencyException");
+ }
+ catch (UnsatisfiedDependencyException ex) {
+ // expected
+ }
+ }
+
+ @Test
+ public void testAutowireBeanByTypeWithNoDependencyCheck() {
+ DefaultListableBeanFactory lbf = getInstance();
+ DependenciesBean bean = (DependenciesBean)
+ lbf.autowire(DependenciesBean.class, AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, false);
+ assertNull(bean.getSpouse());
+ }
+
+ @Test
+ public void testAutowireBeanByTypeWithTwoMatchesAndOnePrimary() {
+ DefaultListableBeanFactory lbf = getInstance();
+ RootBeanDefinition bd = new RootBeanDefinition(TestBean.class);
+ bd.setPrimary(true);
+ RootBeanDefinition bd2 = new RootBeanDefinition(TestBean.class);
+ lbf.registerBeanDefinition("test", bd);
+ lbf.registerBeanDefinition("spouse", bd2);
+
+ DependenciesBean bean = (DependenciesBean)
+ lbf.autowire(DependenciesBean.class, AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, true);
+ assertThat(bean.getSpouse(), equalTo(lbf.getBean("test")));
+ }
+
+ @Test
+ public void testAutowireBeanByTypeWithTwoPrimaryCandidates() {
+ DefaultListableBeanFactory lbf = getInstance();
+ RootBeanDefinition bd = new RootBeanDefinition(TestBean.class);
+ bd.setPrimary(true);
+ RootBeanDefinition bd2 = new RootBeanDefinition(TestBean.class);
+ bd2.setPrimary(true);
+ lbf.registerBeanDefinition("test", bd);
+ lbf.registerBeanDefinition("spouse", bd2);
+
+ try {
+ lbf.autowire(DependenciesBean.class, AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, true);
+ fail("Should have thrown UnsatisfiedDependencyException");
+ }
+ catch (UnsatisfiedDependencyException ex) {
+ // expected
+ assertNotNull("Exception should have cause", ex.getCause());
+ assertEquals("Wrong cause type", NoUniqueBeanDefinitionException.class, ex.getCause().getClass());
+ }
+ }
+
+ @Test
+ public void testAutowireBeanByTypeWithTwoMatchesAndPriority() {
+ DefaultListableBeanFactory lbf = getInstance();
+ lbf.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
+ RootBeanDefinition bd = new RootBeanDefinition(HighPriorityTestBean.class);
+ RootBeanDefinition bd2 = new RootBeanDefinition(LowPriorityTestBean.class);
+ lbf.registerBeanDefinition("test", bd);
+ lbf.registerBeanDefinition("spouse", bd2);
+
+ DependenciesBean bean = (DependenciesBean)
+ lbf.autowire(DependenciesBean.class, AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, true);
+ assertThat(bean.getSpouse(), equalTo(lbf.getBean("test")));
+ }
+
+ @Test
+ public void testAutowireBeanByTypeWithIdenticalPriorityCandidates() {
+ DefaultListableBeanFactory lbf = getInstance();
+ lbf.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
+ RootBeanDefinition bd = new RootBeanDefinition(HighPriorityTestBean.class);
+ RootBeanDefinition bd2 = new RootBeanDefinition(HighPriorityTestBean.class);
+ lbf.registerBeanDefinition("test", bd);
+ lbf.registerBeanDefinition("spouse", bd2);
+
+ try {
+ lbf.autowire(DependenciesBean.class, AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, true);
+ fail("Should have thrown UnsatisfiedDependencyException");
+ }
+ catch (UnsatisfiedDependencyException ex) {
+ // expected
+ assertNotNull("Exception should have cause", ex.getCause());
+ assertEquals("Wrong cause type", NoUniqueBeanDefinitionException.class, ex.getCause().getClass());
+ assertTrue(ex.getMessage().contains("5")); // conflicting priority
+ }
+ }
+
+ @Test
+ public void testAutowireBeanByTypePrimaryTakesPrecedenceOverPriority() {
+ DefaultListableBeanFactory lbf = getInstance();
+ lbf.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
+ RootBeanDefinition bd = new RootBeanDefinition(HighPriorityTestBean.class);
+ RootBeanDefinition bd2 = new RootBeanDefinition(TestBean.class);
+ bd2.setPrimary(true);
+ lbf.registerBeanDefinition("test", bd);
+ lbf.registerBeanDefinition("spouse", bd2);
+
+ DependenciesBean bean = (DependenciesBean)
+ lbf.autowire(DependenciesBean.class, AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, true);
+ assertThat(bean.getSpouse(), equalTo(lbf.getBean("spouse")));
+ }
+
+ @Test
+ public void testAutowireExistingBeanByName() {
+ DefaultListableBeanFactory lbf = getInstance();
+ RootBeanDefinition bd = new RootBeanDefinition(TestBean.class);
+ lbf.registerBeanDefinition("spouse", bd);
+ DependenciesBean existingBean = new DependenciesBean();
+ lbf.autowireBeanProperties(existingBean, AutowireCapableBeanFactory.AUTOWIRE_BY_NAME, true);
+ TestBean spouse = (TestBean) lbf.getBean("spouse");
+ assertEquals(existingBean.getSpouse(), spouse);
+ assertSame(spouse, BeanFactoryUtils.beanOfType(lbf, TestBean.class));
+ }
+
+ @Test
+ public void testAutowireExistingBeanByNameWithDependencyCheck() {
+ DefaultListableBeanFactory lbf = getInstance();
+ RootBeanDefinition bd = new RootBeanDefinition(TestBean.class);
+ lbf.registerBeanDefinition("spous", bd);
+ DependenciesBean existingBean = new DependenciesBean();
+ try {
+ lbf.autowireBeanProperties(existingBean, AutowireCapableBeanFactory.AUTOWIRE_BY_NAME, true);
+ fail("Should have thrown UnsatisfiedDependencyException");
+ }
+ catch (UnsatisfiedDependencyException ex) {
+ // expected
+ }
+ }
+
+ @Test
+ public void testAutowireExistingBeanByNameWithNoDependencyCheck() {
+ DefaultListableBeanFactory lbf = getInstance();
+ RootBeanDefinition bd = new RootBeanDefinition(TestBean.class);
+ lbf.registerBeanDefinition("spous", bd);
+ DependenciesBean existingBean = new DependenciesBean();
+ lbf.autowireBeanProperties(existingBean, AutowireCapableBeanFactory.AUTOWIRE_BY_NAME, false);
+ assertNull(existingBean.getSpouse());
+ }
+
+ @Test
+ public void testAutowireExistingBeanByType() {
+ DefaultListableBeanFactory lbf = getInstance();
+ RootBeanDefinition bd = new RootBeanDefinition(TestBean.class);
+ lbf.registerBeanDefinition("test", bd);
+ DependenciesBean existingBean = new DependenciesBean();
+ lbf.autowireBeanProperties(existingBean, AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, true);
+ TestBean test = (TestBean) lbf.getBean("test");
+ assertEquals(existingBean.getSpouse(), test);
+ }
+
+ @Test
+ public void testAutowireExistingBeanByTypeWithDependencyCheck() {
+ DefaultListableBeanFactory lbf = getInstance();
+ DependenciesBean existingBean = new DependenciesBean();
+ try {
+ lbf.autowireBeanProperties(existingBean, AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, true);
+ fail("Should have thrown UnsatisfiedDependencyException");
+ }
+ catch (UnsatisfiedDependencyException expected) {
+ }
+ }
+
+ @Test
+ public void testAutowireExistingBeanByTypeWithNoDependencyCheck() {
+ DefaultListableBeanFactory lbf = getInstance();
+ DependenciesBean existingBean = new DependenciesBean();
+ lbf.autowireBeanProperties(existingBean, AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, false);
+ assertNull(existingBean.getSpouse());
+ }
+
+ @Test
+ public void testInvalidAutowireMode() {
+ DefaultListableBeanFactory lbf = getInstance();
+ try {
+ lbf.autowireBeanProperties(new TestBean(), AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR, false);
+ fail("Should have thrown IllegalArgumentException");
+ }
+ catch (IllegalArgumentException expected) {
+ }
+ }
+
+ @Test
+ public void testApplyBeanPropertyValues() {
+ DefaultListableBeanFactory lbf = getInstance();
+ MutablePropertyValues pvs = new MutablePropertyValues();
+ pvs.add("age", "99");
+ RootBeanDefinition bd = new RootBeanDefinition(TestBean.class);
+ bd.setPropertyValues(pvs);
+ lbf.registerBeanDefinition("test", bd);
+ TestBean tb = new TestBean();
+ assertEquals(0, tb.getAge());
+ lbf.applyBeanPropertyValues(tb, "test");
+ assertEquals(99, tb.getAge());
+ }
+
+ @Test
+ public void testApplyBeanPropertyValuesWithIncompleteDefinition() {
+ DefaultListableBeanFactory lbf = getInstance();
+ MutablePropertyValues pvs = new MutablePropertyValues();
+ pvs.add("age", "99");
+ RootBeanDefinition bd = new RootBeanDefinition();
+ bd.setPropertyValues(pvs);
+ lbf.registerBeanDefinition("test", bd);
+ TestBean tb = new TestBean();
+ assertEquals(0, tb.getAge());
+ lbf.applyBeanPropertyValues(tb, "test");
+ assertEquals(99, tb.getAge());
+ assertNull(tb.getBeanFactory());
+ assertNull(tb.getSpouse());
+ }
+
+ @Test
+ public void testCreateBean() {
+ DefaultListableBeanFactory lbf = getInstance();
+ TestBean tb = lbf.createBean(TestBean.class);
+ assertSame(lbf, tb.getBeanFactory());
+ lbf.destroyBean(tb);
+ }
+
+ @Test
+ public void testCreateBeanWithDisposableBean() {
+ DefaultListableBeanFactory lbf = getInstance();
+ DerivedTestBean tb = lbf.createBean(DerivedTestBean.class);
+ assertSame(lbf, tb.getBeanFactory());
+ lbf.destroyBean(tb);
+ assertTrue(tb.wasDestroyed());
+ }
+
+ @Test
+ public void testConfigureBean() {
+ DefaultListableBeanFactory lbf = getInstance();
+ MutablePropertyValues pvs = new MutablePropertyValues();
+ pvs.add("age", "99");
+ RootBeanDefinition bd = new RootBeanDefinition(TestBean.class);
+ bd.setPropertyValues(pvs);
+ lbf.registerBeanDefinition("test", bd);
+ TestBean tb = new TestBean();
+ assertEquals(0, tb.getAge());
+ lbf.configureBean(tb, "test");
+ assertEquals(99, tb.getAge());
+ assertSame(lbf, tb.getBeanFactory());
+ assertNull(tb.getSpouse());
+ }
+
+ @Test
+ public void testConfigureBeanWithAutowiring() {
+ DefaultListableBeanFactory lbf = getInstance();
+ RootBeanDefinition bd = new RootBeanDefinition(TestBean.class);
+ lbf.registerBeanDefinition("spouse", bd);
+ MutablePropertyValues pvs = new MutablePropertyValues();
+ pvs.add("age", "99");
+ RootBeanDefinition tbd = new RootBeanDefinition(TestBean.class);
+ tbd.setAutowireMode(RootBeanDefinition.AUTOWIRE_BY_NAME);
+ lbf.registerBeanDefinition("test", tbd);
+ TestBean tb = new TestBean();
+ lbf.configureBean(tb, "test");
+ assertSame(lbf, tb.getBeanFactory());
+ TestBean spouse = (TestBean) lbf.getBean("spouse");
+ assertEquals(spouse, tb.getSpouse());
+ }
+
+ @Test
+ public void testExtensiveCircularReference() {
+ DefaultListableBeanFactory lbf = getInstance();
+ for (int i = 0; i < 1000; i++) {
+ MutablePropertyValues pvs = new MutablePropertyValues();
+ pvs.addPropertyValue(new PropertyValue("spouse", new RuntimeBeanReference("bean" + (i < 99 ? i + 1 : 0))));
+ RootBeanDefinition bd = new RootBeanDefinition(TestBean.class);
+ bd.setPropertyValues(pvs);
+ lbf.registerBeanDefinition("bean" + i, bd);
+ }
+ lbf.preInstantiateSingletons();
+ for (int i = 0; i < 1000; i++) {
+ TestBean bean = (TestBean) lbf.getBean("bean" + i);
+ TestBean otherBean = (TestBean) lbf.getBean("bean" + (i < 99 ? i + 1 : 0));
+ assertTrue(bean.getSpouse() == otherBean);
+ }
+ }
+
+ @Test
+ public void testCircularReferenceThroughAutowiring() {
+ DefaultListableBeanFactory lbf = getInstance();
+ RootBeanDefinition bd = new RootBeanDefinition(ConstructorDependencyBean.class);
+ bd.setAutowireMode(RootBeanDefinition.AUTOWIRE_CONSTRUCTOR);
+ lbf.registerBeanDefinition("test", bd);
+ try {
+ lbf.preInstantiateSingletons();
+ fail("Should have thrown UnsatisfiedDependencyException");
+ }
+ catch (UnsatisfiedDependencyException expected) {
+ }
+ }
+
+ @Test
+ public void testCircularReferenceThroughFactoryBeanAutowiring() {
+ DefaultListableBeanFactory lbf = getInstance();
+ RootBeanDefinition bd = new RootBeanDefinition(ConstructorDependencyFactoryBean.class);
+ bd.setAutowireMode(RootBeanDefinition.AUTOWIRE_CONSTRUCTOR);
+ lbf.registerBeanDefinition("test", bd);
+ try {
+ lbf.preInstantiateSingletons();
+ fail("Should have thrown UnsatisfiedDependencyException");
+ }
+ catch (UnsatisfiedDependencyException expected) {
+ }
+ }
+
+ @Test
+ public void testCircularReferenceThroughFactoryBeanTypeCheck() {
+ DefaultListableBeanFactory lbf = getInstance();
+ RootBeanDefinition bd = new RootBeanDefinition(ConstructorDependencyFactoryBean.class);
+ bd.setAutowireMode(RootBeanDefinition.AUTOWIRE_CONSTRUCTOR);
+ lbf.registerBeanDefinition("test", bd);
+ try {
+ lbf.getBeansOfType(String.class);
+ fail("Should have thrown UnsatisfiedDependencyException");
+ }
+ catch (UnsatisfiedDependencyException expected) {
+ }
+ }
+
+ @Test
+ public void testAvoidCircularReferenceThroughAutowiring() {
+ DefaultListableBeanFactory lbf = getInstance();
+ RootBeanDefinition bd = new RootBeanDefinition(ConstructorDependencyFactoryBean.class);
+ bd.setAutowireMode(RootBeanDefinition.AUTOWIRE_CONSTRUCTOR);
+ lbf.registerBeanDefinition("test", bd);
+ RootBeanDefinition bd2 = new RootBeanDefinition(String.class);
+ bd2.setAutowireMode(RootBeanDefinition.AUTOWIRE_CONSTRUCTOR);
+ lbf.registerBeanDefinition("string", bd2);
+ lbf.preInstantiateSingletons();
+ }
+
+ @Test
+ public void testConstructorDependencyWithClassResolution() {
+ DefaultListableBeanFactory lbf = getInstance();
+ RootBeanDefinition bd = new RootBeanDefinition(ConstructorDependencyWithClassResolution.class);
+ bd.getConstructorArgumentValues().addGenericArgumentValue("java.lang.String");
+ lbf.registerBeanDefinition("test", bd);
+ lbf.preInstantiateSingletons();
+ }
+
+ @Test
+ public void testConstructorDependencyWithUnresolvableClass() {
+ DefaultListableBeanFactory lbf = getInstance();
+ RootBeanDefinition bd = new RootBeanDefinition(ConstructorDependencyWithClassResolution.class);
+ bd.getConstructorArgumentValues().addGenericArgumentValue("java.lang.Strin");
+ lbf.registerBeanDefinition("test", bd);
+ try {
+ lbf.preInstantiateSingletons();
+ fail("Should have thrown UnsatisfiedDependencyException");
+ }
+ catch (UnsatisfiedDependencyException expected) {
+ assertTrue(expected.toString().contains("java.lang.Strin"));
+ }
+ }
+
+ @Test
+ public void testBeanDefinitionWithInterface() {
+ DefaultListableBeanFactory lbf = getInstance();
+ lbf.registerBeanDefinition("test", new RootBeanDefinition(ITestBean.class));
+ try {
+ lbf.getBean("test");
+ fail("Should have thrown BeanCreationException");
+ }
+ catch (BeanCreationException ex) {
+ assertEquals("test", ex.getBeanName());
+ assertTrue(ex.getMessage().toLowerCase().contains("interface"));
+ }
+ }
+
+ @Test
+ public void testBeanDefinitionWithAbstractClass() {
+ DefaultListableBeanFactory lbf = getInstance();
+ lbf.registerBeanDefinition("test", new RootBeanDefinition(AbstractBeanFactory.class));
+ try {
+ lbf.getBean("test");
+ fail("Should have thrown BeanCreationException");
+ }
+ catch (BeanCreationException ex) {
+ assertEquals("test", ex.getBeanName());
+ assertTrue(ex.getMessage().toLowerCase().contains("abstract"));
+ }
+ }
+
+ @Test
+ public void testPrototypeFactoryBeanNotEagerlyCalled() {
+ DefaultListableBeanFactory lbf = getInstance();
+ lbf.registerBeanDefinition("test", new RootBeanDefinition(FactoryBeanThatShouldntBeCalled.class));
+ lbf.preInstantiateSingletons();
+ }
+
+ @Test
+ public void testLazyInitFactory() {
+ DefaultListableBeanFactory lbf = getInstance();
+ lbf.registerBeanDefinition("test", new RootBeanDefinition(LazyInitFactory.class));
+ lbf.preInstantiateSingletons();
+ LazyInitFactory factory = (LazyInitFactory) lbf.getBean("&test");
+ assertFalse(factory.initialized);
+ }
+
+ @Test
+ public void testSmartInitFactory() {
+ DefaultListableBeanFactory lbf = getInstance();
+ lbf.registerBeanDefinition("test", new RootBeanDefinition(EagerInitFactory.class));
+ lbf.preInstantiateSingletons();
+ EagerInitFactory factory = (EagerInitFactory) lbf.getBean("&test");
+ assertTrue(factory.initialized);
+ }
+
+ @Test
+ public void testPrototypeFactoryBeanNotEagerlyCalledInCaseOfBeanClassName() {
+ DefaultListableBeanFactory lbf = getInstance();
+ lbf.registerBeanDefinition("test",
+ new RootBeanDefinition(FactoryBeanThatShouldntBeCalled.class.getName(), null, null));
+ lbf.preInstantiateSingletons();
+ }
+
+ @Test
+ public void testPrototypeStringCreatedRepeatedly() {
+ DefaultListableBeanFactory lbf = getInstance();
+ RootBeanDefinition stringDef = new RootBeanDefinition(String.class);
+ stringDef.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
+ stringDef.getConstructorArgumentValues().addGenericArgumentValue(new TypedStringValue("value"));
+ lbf.registerBeanDefinition("string", stringDef);
+ String val1 = lbf.getBean("string", String.class);
+ String val2 = lbf.getBean("string", String.class);
+ assertEquals("value", val1);
+ assertEquals("value", val2);
+ assertNotSame(val1, val2);
+ }
+
+ @Test
+ public void testPrototypeWithArrayConversionForConstructor() {
+ DefaultListableBeanFactory lbf = getInstance();
+ List list = new ManagedList<>();
+ list.add("myName");
+ list.add("myBeanName");
+ RootBeanDefinition bd = new RootBeanDefinition(DerivedTestBean.class);
+ bd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
+ bd.getConstructorArgumentValues().addGenericArgumentValue(list);
+ lbf.registerBeanDefinition("test", bd);
+ DerivedTestBean tb = (DerivedTestBean) lbf.getBean("test");
+ assertEquals("myName", tb.getName());
+ assertEquals("myBeanName", tb.getBeanName());
+ DerivedTestBean tb2 = (DerivedTestBean) lbf.getBean("test");
+ assertTrue(tb != tb2);
+ assertEquals("myName", tb2.getName());
+ assertEquals("myBeanName", tb2.getBeanName());
+ }
+
+ @Test
+ public void testPrototypeWithArrayConversionForFactoryMethod() {
+ DefaultListableBeanFactory lbf = getInstance();
+ List list = new ManagedList<>();
+ list.add("myName");
+ list.add("myBeanName");
+ RootBeanDefinition bd = new RootBeanDefinition(DerivedTestBean.class);
+ bd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
+ bd.setFactoryMethodName("create");
+ bd.getConstructorArgumentValues().addGenericArgumentValue(list);
+ lbf.registerBeanDefinition("test", bd);
+ DerivedTestBean tb = (DerivedTestBean) lbf.getBean("test");
+ assertEquals("myName", tb.getName());
+ assertEquals("myBeanName", tb.getBeanName());
+ DerivedTestBean tb2 = (DerivedTestBean) lbf.getBean("test");
+ assertTrue(tb != tb2);
+ assertEquals("myName", tb2.getName());
+ assertEquals("myBeanName", tb2.getBeanName());
+ }
+
+ @Test
+ public void testPrototypeCreationIsFastEnough() {
+ Assume.group(TestGroup.PERFORMANCE);
+ Assume.notLogging(factoryLog);
+ DefaultListableBeanFactory lbf = getInstance();
+ RootBeanDefinition rbd = new RootBeanDefinition(TestBean.class);
+ rbd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
+ lbf.registerBeanDefinition("test", rbd);
+ lbf.freezeConfiguration();
+ StopWatch sw = new StopWatch();
+ sw.start("prototype");
+ for (int i = 0; i < 100000; i++) {
+ lbf.getBean("test");
+ }
+ sw.stop();
+ // System.out.println(sw.getTotalTimeMillis());
+ assertTrue("Prototype creation took too long: " + sw.getTotalTimeMillis(), sw.getTotalTimeMillis() < 3000);
+ }
+
+ @Test
+ public void testPrototypeCreationWithDependencyCheckIsFastEnough() {
+ Assume.group(TestGroup.PERFORMANCE);
+ Assume.notLogging(factoryLog);
+ DefaultListableBeanFactory lbf = getInstance();
+ RootBeanDefinition rbd = new RootBeanDefinition(LifecycleBean.class);
+ rbd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
+ rbd.setDependencyCheck(RootBeanDefinition.DEPENDENCY_CHECK_OBJECTS);
+ lbf.registerBeanDefinition("test", rbd);
+ lbf.addBeanPostProcessor(new LifecycleBean.PostProcessor());
+ lbf.freezeConfiguration();
+ StopWatch sw = new StopWatch();
+ sw.start("prototype");
+ for (int i = 0; i < 100000; i++) {
+ lbf.getBean("test");
+ }
+ sw.stop();
+ // System.out.println(sw.getTotalTimeMillis());
+ assertTrue("Prototype creation took too long: " + sw.getTotalTimeMillis(), sw.getTotalTimeMillis() < 3000);
+ }
+
+ @Test
+ @Ignore // TODO re-enable when ConstructorResolver TODO sorted out
+ public void testPrototypeCreationWithConstructorArgumentsIsFastEnough() {
+ Assume.group(TestGroup.PERFORMANCE);
+ Assume.notLogging(factoryLog);
+ DefaultListableBeanFactory lbf = getInstance();
+ RootBeanDefinition rbd = new RootBeanDefinition(TestBean.class);
+ rbd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
+ rbd.getConstructorArgumentValues().addGenericArgumentValue("juergen");
+ rbd.getConstructorArgumentValues().addGenericArgumentValue("99");
+ lbf.registerBeanDefinition("test", rbd);
+ lbf.freezeConfiguration();
+ StopWatch sw = new StopWatch();
+ sw.start("prototype");
+ for (int i = 0; i < 100000; i++) {
+ TestBean tb = (TestBean) lbf.getBean("test");
+ assertEquals("juergen", tb.getName());
+ assertEquals(99, tb.getAge());
+ }
+ sw.stop();
+ // System.out.println(sw.getTotalTimeMillis());
+ assertTrue("Prototype creation took too long: " + sw.getTotalTimeMillis(), sw.getTotalTimeMillis() < 3000);
+ }
+
+ @Test
+ public void testPrototypeCreationWithResolvedConstructorArgumentsIsFastEnough() {
+ Assume.group(TestGroup.PERFORMANCE);
+ Assume.notLogging(factoryLog);
+ DefaultListableBeanFactory lbf = getInstance();
+ RootBeanDefinition rbd = new RootBeanDefinition(TestBean.class);
+ rbd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
+ rbd.getConstructorArgumentValues().addGenericArgumentValue(new RuntimeBeanReference("spouse"));
+ lbf.registerBeanDefinition("test", rbd);
+ lbf.registerBeanDefinition("spouse", new RootBeanDefinition(TestBean.class));
+ lbf.freezeConfiguration();
+ TestBean spouse = (TestBean) lbf.getBean("spouse");
+ StopWatch sw = new StopWatch();
+ sw.start("prototype");
+ for (int i = 0; i < 100000; i++) {
+ TestBean tb = (TestBean) lbf.getBean("test");
+ assertSame(spouse, tb.getSpouse());
+ }
+ sw.stop();
+ // System.out.println(sw.getTotalTimeMillis());
+ assertTrue("Prototype creation took too long: " + sw.getTotalTimeMillis(), sw.getTotalTimeMillis() < 4000);
+ }
+
+ @Test
+ public void testPrototypeCreationWithPropertiesIsFastEnough() {
+ Assume.group(TestGroup.PERFORMANCE);
+ Assume.notLogging(factoryLog);
+ DefaultListableBeanFactory lbf = getInstance();
+ RootBeanDefinition rbd = new RootBeanDefinition(TestBean.class);
+ rbd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
+ rbd.getPropertyValues().add("name", "juergen");
+ rbd.getPropertyValues().add("age", "99");
+ lbf.registerBeanDefinition("test", rbd);
+ lbf.freezeConfiguration();
+ StopWatch sw = new StopWatch();
+ sw.start("prototype");
+ for (int i = 0; i < 100000; i++) {
+ TestBean tb = (TestBean) lbf.getBean("test");
+ assertEquals("juergen", tb.getName());
+ assertEquals(99, tb.getAge());
+ }
+ sw.stop();
+ // System.out.println(sw.getTotalTimeMillis());
+ assertTrue("Prototype creation took too long: " + sw.getTotalTimeMillis(), sw.getTotalTimeMillis() < 4000);
+ }
+
+ @Test
+ public void testPrototypeCreationWithResolvedPropertiesIsFastEnough() {
+ Assume.group(TestGroup.PERFORMANCE);
+ Assume.notLogging(factoryLog);
+ DefaultListableBeanFactory lbf = getInstance();
+ RootBeanDefinition rbd = new RootBeanDefinition(TestBean.class);
+ rbd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
+ rbd.getPropertyValues().add("spouse", new RuntimeBeanReference("spouse"));
+ lbf.registerBeanDefinition("test", rbd);
+ lbf.registerBeanDefinition("spouse", new RootBeanDefinition(TestBean.class));
+ lbf.freezeConfiguration();
+ TestBean spouse = (TestBean) lbf.getBean("spouse");
+ StopWatch sw = new StopWatch();
+ sw.start("prototype");
+ for (int i = 0; i < 100000; i++) {
+ TestBean tb = (TestBean) lbf.getBean("test");
+ assertSame(spouse, tb.getSpouse());
+ }
+ sw.stop();
+ // System.out.println(sw.getTotalTimeMillis());
+ assertTrue("Prototype creation took too long: " + sw.getTotalTimeMillis(), sw.getTotalTimeMillis() < 4000);
+ }
+
+ @Test
+ public void testSingletonLookupByNameIsFastEnough() {
+ Assume.group(TestGroup.PERFORMANCE);
+ Assume.notLogging(factoryLog);
+ DefaultListableBeanFactory lbf = getInstance();
+ lbf.registerBeanDefinition("test", new RootBeanDefinition(TestBean.class));
+ lbf.freezeConfiguration();
+ StopWatch sw = new StopWatch();
+ sw.start("singleton");
+ for (int i = 0; i < 1000000; i++) {
+ lbf.getBean("test");
+ }
+ sw.stop();
+ // System.out.println(sw.getTotalTimeMillis());
+ assertTrue("Singleton lookup took too long: " + sw.getTotalTimeMillis(), sw.getTotalTimeMillis() < 1000);
+ }
+
+ @Test
+ public void testSingletonLookupByTypeIsFastEnough() {
+ Assume.group(TestGroup.PERFORMANCE);
+ Assume.notLogging(factoryLog);
+ DefaultListableBeanFactory lbf = getInstance();
+ lbf.registerBeanDefinition("test", new RootBeanDefinition(TestBean.class));
+ lbf.freezeConfiguration();
+ StopWatch sw = new StopWatch();
+ sw.start("singleton");
+ for (int i = 0; i < 1000000; i++) {
+ lbf.getBean(TestBean.class);
+ }
+ sw.stop();
+ // System.out.println(sw.getTotalTimeMillis());
+ assertTrue("Singleton lookup took too long: " + sw.getTotalTimeMillis(), sw.getTotalTimeMillis() < 1000);
+ }
+
+ @Test
+ public void testBeanPostProcessorWithWrappedObjectAndDisposableBean() {
+ DefaultListableBeanFactory lbf = getInstance();
+ RootBeanDefinition bd = new RootBeanDefinition(BeanWithDisposableBean.class);
+ lbf.registerBeanDefinition("test", bd);
+ lbf.addBeanPostProcessor(new BeanPostProcessor() {
+ @Override
+ public Object postProcessBeforeInitialization(Object bean, String beanName) {
+ return new TestBean();
+ }
+ @Override
+ public Object postProcessAfterInitialization(Object bean, String beanName) {
+ return bean;
+ }
+ });
+ BeanWithDisposableBean.closed = false;
+ lbf.preInstantiateSingletons();
+ lbf.destroySingletons();
+ assertTrue("Destroy method invoked", BeanWithDisposableBean.closed);
+ }
+
+ @Test
+ public void testBeanPostProcessorWithWrappedObjectAndCloseable() {
+ DefaultListableBeanFactory lbf = getInstance();
+ RootBeanDefinition bd = new RootBeanDefinition(BeanWithCloseable.class);
+ lbf.registerBeanDefinition("test", bd);
+ lbf.addBeanPostProcessor(new BeanPostProcessor() {
+ @Override
+ public Object postProcessBeforeInitialization(Object bean, String beanName) {
+ return new TestBean();
+ }
+ @Override
+ public Object postProcessAfterInitialization(Object bean, String beanName) {
+ return bean;
+ }
+ });
+ BeanWithDisposableBean.closed = false;
+ lbf.preInstantiateSingletons();
+ lbf.destroySingletons();
+ assertTrue("Destroy method invoked", BeanWithCloseable.closed);
+ }
+
+ @Test
+ public void testBeanPostProcessorWithWrappedObjectAndDestroyMethod() {
+ DefaultListableBeanFactory lbf = getInstance();
+ RootBeanDefinition bd = new RootBeanDefinition(BeanWithDestroyMethod.class);
+ bd.setDestroyMethodName("close");
+ lbf.registerBeanDefinition("test", bd);
+ lbf.addBeanPostProcessor(new BeanPostProcessor() {
+ @Override
+ public Object postProcessBeforeInitialization(Object bean, String beanName) {
+ return new TestBean();
+ }
+ @Override
+ public Object postProcessAfterInitialization(Object bean, String beanName) {
+ return bean;
+ }
+ });
+ BeanWithDestroyMethod.closeCount = 0;
+ lbf.preInstantiateSingletons();
+ lbf.destroySingletons();
+ assertEquals("Destroy methods invoked", 1, BeanWithDestroyMethod.closeCount);
+ }
+
+ @Test
+ public void testDestroyMethodOnInnerBean() {
+ DefaultListableBeanFactory lbf = getInstance();
+ RootBeanDefinition innerBd = new RootBeanDefinition(BeanWithDestroyMethod.class);
+ innerBd.setDestroyMethodName("close");
+ RootBeanDefinition bd = new RootBeanDefinition(BeanWithDestroyMethod.class);
+ bd.setDestroyMethodName("close");
+ bd.getPropertyValues().add("inner", innerBd);
+ lbf.registerBeanDefinition("test", bd);
+ BeanWithDestroyMethod.closeCount = 0;
+ lbf.preInstantiateSingletons();
+ lbf.destroySingletons();
+ assertEquals("Destroy methods invoked", 2, BeanWithDestroyMethod.closeCount);
+ }
+
+ @Test
+ public void testDestroyMethodOnInnerBeanAsPrototype() {
+ DefaultListableBeanFactory lbf = getInstance();
+ RootBeanDefinition innerBd = new RootBeanDefinition(BeanWithDestroyMethod.class);
+ innerBd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
+ innerBd.setDestroyMethodName("close");
+ RootBeanDefinition bd = new RootBeanDefinition(BeanWithDestroyMethod.class);
+ bd.setDestroyMethodName("close");
+ bd.getPropertyValues().add("inner", innerBd);
+ lbf.registerBeanDefinition("test", bd);
+ BeanWithDestroyMethod.closeCount = 0;
+ lbf.preInstantiateSingletons();
+ lbf.destroySingletons();
+ assertEquals("Destroy methods invoked", 1, BeanWithDestroyMethod.closeCount);
+ }
+
+ @Test
+ public void testFindTypeOfSingletonFactoryMethodOnBeanInstance() {
+ findTypeOfPrototypeFactoryMethodOnBeanInstance(true);
+ }
+
+ @Test
+ public void testFindTypeOfPrototypeFactoryMethodOnBeanInstance() {
+ findTypeOfPrototypeFactoryMethodOnBeanInstance(false);
+ }
+
+ /**
+ * @param singleton whether the bean created from the factory method on
+ * the bean instance should be a singleton or prototype. This flag is
+ * used to allow checking of the new ability in 1.2.4 to determine the type
+ * of a prototype created from invoking a factory method on a bean instance
+ * in the factory.
+ */
+ private void findTypeOfPrototypeFactoryMethodOnBeanInstance(boolean singleton) {
+ String expectedNameFromProperties = "tony";
+ String expectedNameFromArgs = "gordon";
+
+ DefaultListableBeanFactory lbf = getInstance();
+ RootBeanDefinition instanceFactoryDefinition = new RootBeanDefinition(BeanWithFactoryMethod.class);
+ MutablePropertyValues pvs = new MutablePropertyValues();
+ pvs.add("name", expectedNameFromProperties);
+ instanceFactoryDefinition.setPropertyValues(pvs);
+ lbf.registerBeanDefinition("factoryBeanInstance", instanceFactoryDefinition);
+
+ RootBeanDefinition factoryMethodDefinitionWithProperties = new RootBeanDefinition();
+ factoryMethodDefinitionWithProperties.setFactoryBeanName("factoryBeanInstance");
+ factoryMethodDefinitionWithProperties.setFactoryMethodName("create");
+ if (!singleton) {
+ factoryMethodDefinitionWithProperties.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
+ }
+ lbf.registerBeanDefinition("fmWithProperties", factoryMethodDefinitionWithProperties);
+
+ RootBeanDefinition factoryMethodDefinitionGeneric = new RootBeanDefinition();
+ factoryMethodDefinitionGeneric.setFactoryBeanName("factoryBeanInstance");
+ factoryMethodDefinitionGeneric.setFactoryMethodName("createGeneric");
+ if (!singleton) {
+ factoryMethodDefinitionGeneric.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
+ }
+ lbf.registerBeanDefinition("fmGeneric", factoryMethodDefinitionGeneric);
+
+ RootBeanDefinition factoryMethodDefinitionWithArgs = new RootBeanDefinition();
+ factoryMethodDefinitionWithArgs.setFactoryBeanName("factoryBeanInstance");
+ factoryMethodDefinitionWithArgs.setFactoryMethodName("createWithArgs");
+ ConstructorArgumentValues cvals = new ConstructorArgumentValues();
+ cvals.addGenericArgumentValue(expectedNameFromArgs);
+ factoryMethodDefinitionWithArgs.setConstructorArgumentValues(cvals);
+ if (!singleton) {
+ factoryMethodDefinitionWithArgs.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
+ }
+ lbf.registerBeanDefinition("fmWithArgs", factoryMethodDefinitionWithArgs);
+
+ assertEquals(4, lbf.getBeanDefinitionCount());
+ List tbNames = Arrays.asList(lbf.getBeanNamesForType(TestBean.class));
+ assertTrue(tbNames.contains("fmWithProperties"));
+ assertTrue(tbNames.contains("fmWithArgs"));
+ assertEquals(2, tbNames.size());
+
+ TestBean tb = (TestBean) lbf.getBean("fmWithProperties");
+ TestBean second = (TestBean) lbf.getBean("fmWithProperties");
+ if (singleton) {
+ assertSame(tb, second);
+ }
+ else {
+ assertNotSame(tb, second);
+ }
+ assertEquals(expectedNameFromProperties, tb.getName());
+
+ tb = (TestBean) lbf.getBean("fmGeneric");
+ second = (TestBean) lbf.getBean("fmGeneric");
+ if (singleton) {
+ assertSame(tb, second);
+ }
+ else {
+ assertNotSame(tb, second);
+ }
+ assertEquals(expectedNameFromProperties, tb.getName());
+
+ TestBean tb2 = (TestBean) lbf.getBean("fmWithArgs");
+ second = (TestBean) lbf.getBean("fmWithArgs");
+ if (singleton) {
+ assertSame(tb2, second);
+ }
+ else {
+ assertNotSame(tb2, second);
+ }
+ assertEquals(expectedNameFromArgs, tb2.getName());
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void testScopingBeanToUnregisteredScopeResultsInAnException() {
+ BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(TestBean.class);
+ AbstractBeanDefinition beanDefinition = builder.getBeanDefinition();
+ beanDefinition.setScope("he put himself so low could hardly look me in the face");
+
+ DefaultListableBeanFactory factory = getInstance();
+ factory.registerBeanDefinition("testBean", beanDefinition);
+ factory.getBean("testBean");
+ }
+
+ @Test
+ public void testExplicitScopeInheritanceForChildBeanDefinitions() {
+ String theChildScope = "bonanza!";
+
+ RootBeanDefinition parent = new RootBeanDefinition();
+ parent.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
+
+ AbstractBeanDefinition child = BeanDefinitionBuilder.childBeanDefinition("parent").getBeanDefinition();
+ child.setBeanClass(TestBean.class);
+ child.setScope(theChildScope);
+
+ DefaultListableBeanFactory factory = getInstance();
+ factory.registerBeanDefinition("parent", parent);
+ factory.registerBeanDefinition("child", child);
+
+ AbstractBeanDefinition def = (AbstractBeanDefinition) factory.getBeanDefinition("child");
+ assertEquals("Child 'scope' not overriding parent scope (it must).", theChildScope, def.getScope());
+ }
+
+ @Test
+ public void testScopeInheritanceForChildBeanDefinitions() {
+ RootBeanDefinition parent = new RootBeanDefinition();
+ parent.setScope("bonanza!");
+
+ AbstractBeanDefinition child = new ChildBeanDefinition("parent");
+ child.setBeanClass(TestBean.class);
+
+ DefaultListableBeanFactory factory = getInstance();
+ factory.registerBeanDefinition("parent", parent);
+ factory.registerBeanDefinition("child", child);
+
+ BeanDefinition def = factory.getMergedBeanDefinition("child");
+ assertEquals("Child 'scope' not inherited", "bonanza!", def.getScope());
+ }
+
+ @Test
+ public void testFieldSettingWithInstantiationAwarePostProcessorNoShortCircuit() {
+ doTestFieldSettingWithInstantiationAwarePostProcessor(false);
+ }
+
+ @Test
+ public void testFieldSettingWithInstantiationAwarePostProcessorWithShortCircuit() {
+ doTestFieldSettingWithInstantiationAwarePostProcessor(true);
+ }
+
+ private void doTestFieldSettingWithInstantiationAwarePostProcessor(final boolean skipPropertyPopulation) {
+ DefaultListableBeanFactory lbf = getInstance();
+ RootBeanDefinition bd = new RootBeanDefinition(TestBean.class);
+ int ageSetByPropertyValue = 27;
+ bd.getPropertyValues().addPropertyValue(new PropertyValue("age", new Integer(ageSetByPropertyValue)));
+ lbf.registerBeanDefinition("test", bd);
+ final String nameSetOnField = "nameSetOnField";
+ lbf.addBeanPostProcessor(new InstantiationAwareBeanPostProcessorAdapter() {
+ @Override
+ public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
+ TestBean tb = (TestBean) bean;
+ try {
+ Field f = TestBean.class.getDeclaredField("name");
+ f.setAccessible(true);
+ f.set(tb, nameSetOnField);
+ return !skipPropertyPopulation;
+ }
+ catch (Exception ex) {
+ fail("Unexpected exception: " + ex);
+ // Keep compiler happy about return
+ throw new IllegalStateException();
+ }
+ }
+ });
+ lbf.preInstantiateSingletons();
+ TestBean tb = (TestBean) lbf.getBean("test");
+ assertEquals("Name was set on field by IAPP", nameSetOnField, tb.getName());
+ if (!skipPropertyPopulation) {
+ assertEquals("Property value still set", ageSetByPropertyValue, tb.getAge());
+ }
+ else {
+ assertEquals("Property value was NOT set and still has default value", 0, tb.getAge());
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test
+ public void testInitSecurityAwarePrototypeBean() {
+ final DefaultListableBeanFactory lbf = getInstance();
+ RootBeanDefinition bd = new RootBeanDefinition(TestSecuredBean.class);
+ bd.setScope(ConfigurableBeanFactory.SCOPE_PROTOTYPE);
+ bd.setInitMethodName("init");
+ lbf.registerBeanDefinition("test", bd);
+ final Subject subject = new Subject();
+ subject.getPrincipals().add(new TestPrincipal("user1"));
+
+ TestSecuredBean bean = (TestSecuredBean) Subject.doAsPrivileged(subject,
+ new PrivilegedAction() {
+ @Override
+ public Object run() {
+ return lbf.getBean("test");
+ }
+ }, null);
+ assertNotNull(bean);
+ assertEquals("user1", bean.getUserName());
+ }
+
+ @Test
+ public void testContainsBeanReturnsTrueEvenForAbstractBeanDefinition() {
+ DefaultListableBeanFactory bf = getInstance();
+ bf.registerBeanDefinition("abs", BeanDefinitionBuilder
+ .rootBeanDefinition(TestBean.class).setAbstract(true).getBeanDefinition());
+ assertThat(bf.containsBean("abs"), equalTo(true));
+ assertThat(bf.containsBean("bogus"), equalTo(false));
+ }
+
+ @Test
+ public void resolveEmbeddedValue() {
+ DefaultListableBeanFactory bf = getInstance();
+ StringValueResolver r1 = mock(StringValueResolver.class);
+ StringValueResolver r2 = mock(StringValueResolver.class);
+ StringValueResolver r3 = mock(StringValueResolver.class);
+ bf.addEmbeddedValueResolver(r1);
+ bf.addEmbeddedValueResolver(r2);
+ bf.addEmbeddedValueResolver(r3);
+ given(r1.resolveStringValue("A")).willReturn("B");
+ given(r2.resolveStringValue("B")).willReturn(null);
+ given(r3.resolveStringValue(isNull())).willThrow(new IllegalArgumentException());
+
+ bf.resolveEmbeddedValue("A");
+
+ verify(r1).resolveStringValue("A");
+ verify(r2).resolveStringValue("B");
+ verify(r3, never()).resolveStringValue(isNull());
+ }
+
+ @Test
+ public void populatedJavaUtilOptionalBean() {
+ DefaultListableBeanFactory bf = getInstance();
+ RootBeanDefinition bd = new RootBeanDefinition(Optional.class);
+ bd.setFactoryMethodName("of");
+ bd.getConstructorArgumentValues().addGenericArgumentValue("CONTENT");
+ bf.registerBeanDefinition("optionalBean", bd);
+ assertEquals(Optional.of("CONTENT"), bf.getBean(Optional.class));
+ }
+
+ @Test
+ public void emptyJavaUtilOptionalBean() {
+ DefaultListableBeanFactory bf = getInstance();
+ RootBeanDefinition bd = new RootBeanDefinition(Optional.class);
+ bd.setFactoryMethodName("empty");
+ bf.registerBeanDefinition("optionalBean", bd);
+ assertSame(Optional.empty(), bf.getBean(Optional.class));
+ }
+
+ @Test
+ public void testNonPublicEnum() {
+ DefaultListableBeanFactory bf = getInstance();
+ RootBeanDefinition bd = new RootBeanDefinition(NonPublicEnumHolder.class);
+ bd.getConstructorArgumentValues().addGenericArgumentValue("VALUE_1");
+ bf.registerBeanDefinition("holderBean", bd);
+ NonPublicEnumHolder holder = (NonPublicEnumHolder) bf.getBean("holderBean");
+ assertEquals(NonPublicEnum.VALUE_1, holder.getNonPublicEnum());
+ }
+
+ /**
+ * Test that by-type bean lookup caching is working effectively by searching for a
+ * bean of type B 10K times within a container having 1K additional beans of type A.
+ * Prior to by-type caching, each bean lookup would traverse the entire container
+ * (all 1001 beans), performing expensive assignability checks, etc. Now these
+ * operations are necessary only once, providing a dramatic performance improvement.
+ * On load-free modern hardware (e.g. an 8-core MPB), this method should complete well
+ * under the 1000 ms timeout, usually ~= 300ms. With caching removed and on the same
+ * hardware the method will take ~13000 ms. See SPR-6870.
+ */
+ @Test(timeout = 1000)
+ public void testByTypeLookupIsFastEnough() {
+ Assume.group(TestGroup.PERFORMANCE);
+ DefaultListableBeanFactory bf = getInstance();
+
+ for (int i = 0; i < 1000; i++) {
+ bf.registerBeanDefinition("a" + i, new RootBeanDefinition(A.class));
+ }
+ bf.registerBeanDefinition("b", new RootBeanDefinition(B.class));
+
+ bf.freezeConfiguration();
+
+ for (int i = 0; i < 10000; i++) {
+ bf.getBean(B.class);
+ }
+ }
+
+ @Test(timeout = 1000)
+ public void testRegistrationOfManyBeanDefinitionsIsFastEnough() {
+ Assume.group(TestGroup.PERFORMANCE);
+ DefaultListableBeanFactory bf = getInstance();
+ bf.registerBeanDefinition("b", new RootBeanDefinition(B.class));
+ // bf.getBean("b");
+
+ for (int i = 0; i < 100000; i++) {
+ bf.registerBeanDefinition("a" + i, new RootBeanDefinition(A.class));
+ }
+ }
+
+ @Test(timeout = 1000)
+ public void testRegistrationOfManySingletonsIsFastEnough() {
+ Assume.group(TestGroup.PERFORMANCE);
+ DefaultListableBeanFactory bf = getInstance();
+ bf.registerBeanDefinition("b", new RootBeanDefinition(B.class));
+ // bf.getBean("b");
+
+ for (int i = 0; i < 100000; i++) {
+ bf.registerSingleton("a" + i, new A());
+ }
+ }
+
+
+ static class A { }
+
+ static class B { }
+
+
+ public static class NoDependencies {
+
+ private NoDependencies() {
+ }
+ }
+
+
+ public static class ConstructorDependency implements BeanNameAware {
+
+ public TestBean spouse;
+
+ public int spouseAge;
+
+ private String beanName;
+
+ public ConstructorDependency(TestBean spouse) {
+ this.spouse = spouse;
+ }
+
+ public ConstructorDependency(int spouseAge) {
+ this.spouseAge = spouseAge;
+ }
+
+ @SuppressWarnings("unused")
+ private ConstructorDependency(TestBean spouse, TestBean otherSpouse) {
+ throw new IllegalArgumentException("Should never be called");
+ }
+
+ @Override
+ public void setBeanName(String name) {
+ this.beanName = name;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ ConstructorDependency that = (ConstructorDependency) o;
+ return spouseAge == that.spouseAge &&
+ Objects.equals(spouse, that.spouse) &&
+ Objects.equals(beanName, that.beanName);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(spouse, spouseAge, beanName);
+ }
+ }
+
+
+ public static class UnsatisfiedConstructorDependency {
+
+ public UnsatisfiedConstructorDependency(TestBean t, SideEffectBean b) {
+ }
+ }
+
+
+ public static class ConstructorDependencyBean {
+
+ public ConstructorDependencyBean(ConstructorDependencyBean dependency) {
+ }
+ }
+
+
+ public static class ConstructorDependencyFactoryBean implements FactoryBean {
+
+ public ConstructorDependencyFactoryBean(String dependency) {
+ }
+
+ @Override
+ public Object getObject() {
+ return "test";
+ }
+
+ @Override
+ public Class> getObjectType() {
+ return String.class;
+ }
+
+ @Override
+ public boolean isSingleton() {
+ return true;
+ }
+ }
+
+
+ public static class ConstructorDependencyWithClassResolution {
+
+ public ConstructorDependencyWithClassResolution(Class> clazz) {
+ }
+
+ public ConstructorDependencyWithClassResolution() {
+ }
+ }
+
+
+ public static class BeanWithDisposableBean implements DisposableBean {
+
+ private static boolean closed;
+
+ @Override
+ public void destroy() {
+ closed = true;
+ }
+ }
+
+
+ public static class BeanWithCloseable implements Closeable {
+
+ private static boolean closed;
+
+ @Override
+ public void close() {
+ closed = true;
+ }
+ }
+
+
+ public static abstract class BaseClassWithDestroyMethod {
+
+ public abstract BaseClassWithDestroyMethod close();
+ }
+
+
+ public static class BeanWithDestroyMethod extends BaseClassWithDestroyMethod {
+
+ private static int closeCount = 0;
+
+ private BeanWithDestroyMethod inner;
+
+ public void setInner(BeanWithDestroyMethod inner) {
+ this.inner = inner;
+ }
+
+ @Override
+ public BeanWithDestroyMethod close() {
+ closeCount++;
+ return this;
+ }
+ }
+
+
+ public static class BeanWithFactoryMethod {
+
+ private String name;
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public TestBean create() {
+ TestBean tb = new TestBean();
+ tb.setName(this.name);
+ return tb;
+ }
+
+ public TestBean createWithArgs(String arg) {
+ TestBean tb = new TestBean();
+ tb.setName(arg);
+ return tb;
+ }
+
+ public Object createGeneric() {
+ return create();
+ }
+ }
+
+
+ public interface Repository {
+ }
+
+
+ public interface RepositoryFactoryInformation {
+ }
+
+
+ public static abstract class RepositoryFactoryBeanSupport, S, ID extends Serializable>
+ implements RepositoryFactoryInformation, FactoryBean {
+ }
+
+
+ public static class FactoryBeanThatShouldntBeCalled, S, ID extends Serializable>
+ extends RepositoryFactoryBeanSupport implements Runnable, Callable {
+
+ @Override
+ public T getObject() {
+ throw new IllegalStateException();
+ }
+
+ @Override
+ public Class> getObjectType() {
+ return null;
+ }
+
+ @Override
+ public boolean isSingleton() {
+ return false;
+ }
+
+ @Override
+ public void run() {
+ throw new IllegalStateException();
+ }
+
+ @Override
+ public T call() {
+ throw new IllegalStateException();
+ }
+ }
+
+
+ public static class LazyInitFactory implements FactoryBean {
+
+ public boolean initialized = false;
+
+ @Override
+ public Object getObject() {
+ this.initialized = true;
+ return "";
+ }
+
+ @Override
+ public Class> getObjectType() {
+ return String.class;
+ }
+
+ @Override
+ public boolean isSingleton() {
+ return true;
+ }
+ }
+
+
+ public static class EagerInitFactory implements SmartFactoryBean {
+
+ public boolean initialized = false;
+
+ @Override
+ public Object getObject() {
+ this.initialized = true;
+ return "";
+ }
+
+ @Override
+ public Class> getObjectType() {
+ return String.class;
+ }
+
+ @Override
+ public boolean isSingleton() {
+ return true;
+ }
+
+ @Override
+ public boolean isPrototype() {
+ return false;
+ }
+
+ @Override
+ public boolean isEagerInit() {
+ return true;
+ }
+ }
+
+
+ public static class TestBeanFactory {
+
+ public static boolean initialized = false;
+
+ public TestBeanFactory() {
+ initialized = true;
+ }
+
+ public static TestBean createTestBean() {
+ return new TestBean();
+ }
+
+ public TestBean createTestBeanNonStatic() {
+ return new TestBean();
+ }
+ }
+
+
+ public static class ArrayBean {
+
+ private Integer[] integerArray;
+
+ private Resource[] resourceArray;
+
+ public ArrayBean() {
+ }
+
+ public ArrayBean(Integer[] integerArray) {
+ this.integerArray = integerArray;
+ }
+
+ public ArrayBean(Integer[] integerArray, Resource[] resourceArray) {
+ this.integerArray = integerArray;
+ this.resourceArray = resourceArray;
+ }
+
+ public Integer[] getIntegerArray() {
+ return this.integerArray;
+ }
+
+ public void setResourceArray(Resource[] resourceArray) {
+ this.resourceArray = resourceArray;
+ }
+
+ public Resource[] getResourceArray() {
+ return this.resourceArray;
+ }
+ }
+
+
+ /**
+ * Bean with a dependency on a {@link FactoryBean}.
+ */
+ @SuppressWarnings("unused")
+ private static class FactoryBeanDependentBean {
+
+ private FactoryBean> factoryBean;
+
+ public final FactoryBean> getFactoryBean() {
+ return this.factoryBean;
+ }
+
+ public final void setFactoryBean(final FactoryBean> factoryBean) {
+ this.factoryBean = factoryBean;
+ }
+ }
+
+
+ private static class CustomTypeConverter implements TypeConverter {
+
+ private final NumberFormat numberFormat;
+
+ public CustomTypeConverter(NumberFormat numberFormat) {
+ this.numberFormat = numberFormat;
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public Object convertIfNecessary(Object value, @Nullable Class requiredType) {
+ if (value instanceof String && Float.class.isAssignableFrom(requiredType)) {
+ try {
+ return new Float(this.numberFormat.parse((String) value).floatValue());
+ }
+ catch (ParseException ex) {
+ throw new TypeMismatchException(value, requiredType, ex);
+ }
+ }
+ else if (value instanceof String && int.class.isAssignableFrom(requiredType)) {
+ return new Integer(5);
+ }
+ else {
+ return value;
+ }
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public Object convertIfNecessary(Object value, @Nullable Class requiredType, @Nullable MethodParameter methodParam) {
+ return convertIfNecessary(value, requiredType);
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public Object convertIfNecessary(Object value, @Nullable Class requiredType, @Nullable Field field) {
+ return convertIfNecessary(value, requiredType);
+ }
+ }
+
+
+ private static class TestPrincipal implements Principal {
+
+ private String name;
+
+ public TestPrincipal(String name) {
+ this.name = name;
+ }
+
+ @Override
+ public String getName() {
+ return this.name;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == this) {
+ return true;
+ }
+ if (!(obj instanceof TestPrincipal)) {
+ return false;
+ }
+ TestPrincipal p = (TestPrincipal) obj;
+ return this.name.equals(p.name);
+ }
+
+ @Override
+ public int hashCode() {
+ return this.name.hashCode();
+ }
+ }
+
+
+ @SuppressWarnings("unused")
+ private static class TestSecuredBean {
+
+ private String userName;
+
+ public void init() {
+ AccessControlContext acc = AccessController.getContext();
+ Subject subject = Subject.getSubject(acc);
+ if (subject == null) {
+ return;
+ }
+ setNameFromPrincipal(subject.getPrincipals());
+ }
+
+ private void setNameFromPrincipal(Set principals) {
+ if (principals == null) {
+ return;
+ }
+ for (Iterator it = principals.iterator(); it.hasNext();) {
+ Principal p = it.next();
+ this.userName = p.getName();
+ return;
+ }
+ }
+
+ public String getUserName() {
+ return this.userName;
+ }
+ }
+
+
+ @SuppressWarnings("unused")
+ private static class KnowsIfInstantiated {
+
+ private static boolean instantiated;
+
+ public static void clearInstantiationRecord() {
+ instantiated = false;
+ }
+
+ public static boolean wasInstantiated() {
+ return instantiated;
+ }
+
+ public KnowsIfInstantiated() {
+ instantiated = true;
+ }
+
+ }
+
+
+ @Priority(5)
+ private static class HighPriorityTestBean extends TestBean {
+ }
+
+
+ @Priority(500)
+ private static class LowPriorityTestBean extends TestBean {
+ }
+
+
+ private static class NullTestBeanFactoryBean implements FactoryBean {
+
+ @Override
+ public TestBean getObject() {
+ return null;
+ }
+
+ @Override
+ public Class> getObjectType() {
+ return TestBean.class;
+ }
+
+ @Override
+ public boolean isSingleton() {
+ return true;
+ }
+ }
+
+
+ private static class TestBeanRecipient {
+
+ public TestBean testBean;
+
+ public TestBeanRecipient(TestBean testBean) {
+ this.testBean = testBean;
+ }
+ }
+
+
+ enum NonPublicEnum {
+
+ VALUE_1, VALUE_2;
+ }
+
+
+ static class NonPublicEnumHolder {
+
+ final NonPublicEnum nonPublicEnum;
+
+ public NonPublicEnumHolder(NonPublicEnum nonPublicEnum) {
+ this.nonPublicEnum = nonPublicEnum;
+ }
+
+ public NonPublicEnum getNonPublicEnum() {
+ return nonPublicEnum;
+ }
+ }
+
+}
diff --git a/spring-beans/src/test/java/org/springframework/beans/factory/DefaultListableBeanFactoryTests.java b/spring-beans/src/test/java/org/springframework/beans/factory/DefaultListableBeanFactoryTests.java
index 1b27b8e4b078..00498b76b3ca 100644
--- a/spring-beans/src/test/java/org/springframework/beans/factory/DefaultListableBeanFactoryTests.java
+++ b/spring-beans/src/test/java/org/springframework/beans/factory/DefaultListableBeanFactoryTests.java
@@ -16,95 +16,8 @@
package org.springframework.beans.factory;
-import java.io.Closeable;
-import java.io.Serializable;
-import java.lang.reflect.Field;
-import java.net.MalformedURLException;
-import java.security.AccessControlContext;
-import java.security.AccessController;
-import java.security.Principal;
-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;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Optional;
-import java.util.Properties;
-import java.util.Set;
-import java.util.concurrent.Callable;
-import java.util.stream.Collectors;
-import javax.annotation.Priority;
-import javax.security.auth.Subject;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.junit.Ignore;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.ExpectedException;
-import org.mockito.ArgumentMatchers;
-
-import org.springframework.beans.BeansException;
-import org.springframework.beans.MutablePropertyValues;
-import org.springframework.beans.NotWritablePropertyException;
-import org.springframework.beans.PropertyEditorRegistrar;
-import org.springframework.beans.PropertyEditorRegistry;
-import org.springframework.beans.PropertyValue;
-import org.springframework.beans.TypeConverter;
-import org.springframework.beans.TypeMismatchException;
-import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
-import org.springframework.beans.factory.config.BeanDefinition;
-import org.springframework.beans.factory.config.BeanExpressionContext;
-import org.springframework.beans.factory.config.BeanExpressionResolver;
-import org.springframework.beans.factory.config.BeanPostProcessor;
-import org.springframework.beans.factory.config.ConfigurableBeanFactory;
-import org.springframework.beans.factory.config.ConstructorArgumentValues;
-import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter;
-import org.springframework.beans.factory.config.PropertiesFactoryBean;
-import org.springframework.beans.factory.config.RuntimeBeanReference;
-import org.springframework.beans.factory.config.TypedStringValue;
-import org.springframework.beans.factory.support.AbstractBeanDefinition;
-import org.springframework.beans.factory.support.AbstractBeanFactory;
-import org.springframework.beans.factory.support.BeanDefinitionBuilder;
-import org.springframework.beans.factory.support.BeanDefinitionOverrideException;
-import org.springframework.beans.factory.support.ChildBeanDefinition;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
-import org.springframework.beans.factory.support.ManagedList;
-import org.springframework.beans.factory.support.PropertiesBeanDefinitionReader;
-import org.springframework.beans.factory.support.RootBeanDefinition;
-import org.springframework.beans.factory.xml.ConstructorDependenciesBean;
-import org.springframework.beans.propertyeditors.CustomNumberEditor;
-import org.springframework.core.MethodParameter;
-import org.springframework.core.ResolvableType;
-import org.springframework.core.annotation.AnnotationAwareOrderComparator;
-import org.springframework.core.convert.converter.Converter;
-import org.springframework.core.convert.support.DefaultConversionService;
-import org.springframework.core.convert.support.GenericConversionService;
-import org.springframework.core.io.Resource;
-import org.springframework.core.io.UrlResource;
import org.springframework.lang.Nullable;
-import org.springframework.tests.Assume;
-import org.springframework.tests.TestGroup;
-import org.springframework.tests.sample.beans.DependenciesBean;
-import org.springframework.tests.sample.beans.DerivedTestBean;
-import org.springframework.tests.sample.beans.ITestBean;
-import org.springframework.tests.sample.beans.LifecycleBean;
-import org.springframework.tests.sample.beans.NestedTestBean;
-import org.springframework.tests.sample.beans.SideEffectBean;
-import org.springframework.tests.sample.beans.TestBean;
-import org.springframework.tests.sample.beans.factory.DummyFactory;
-import org.springframework.util.SerializationTestUtils;
-import org.springframework.util.StopWatch;
-import org.springframework.util.StringValueResolver;
-
-import static org.hamcrest.Matchers.*;
-import static org.junit.Assert.*;
-import static org.mockito.BDDMockito.*;
/**
* Tests properties population and autowire behavior.
@@ -117,3416 +30,13 @@
* @author Phillip Webb
* @author Stephane Nicoll
*/
-public class DefaultListableBeanFactoryTests {
-
- private static final Log factoryLog = LogFactory.getLog(DefaultListableBeanFactory.class);
-
-
- @Rule
- public ExpectedException thrown = ExpectedException.none();
-
-
- @Test
- public void testUnreferencedSingletonWasInstantiated() {
- KnowsIfInstantiated.clearInstantiationRecord();
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- Properties p = new Properties();
- p.setProperty("x1.(class)", KnowsIfInstantiated.class.getName());
- assertTrue("singleton not instantiated", !KnowsIfInstantiated.wasInstantiated());
- (new PropertiesBeanDefinitionReader(lbf)).registerBeanDefinitions(p);
- lbf.preInstantiateSingletons();
- assertTrue("singleton was instantiated", KnowsIfInstantiated.wasInstantiated());
- }
-
- @Test
- public void testLazyInitialization() {
- KnowsIfInstantiated.clearInstantiationRecord();
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- Properties p = new Properties();
- p.setProperty("x1.(class)", KnowsIfInstantiated.class.getName());
- p.setProperty("x1.(lazy-init)", "true");
- assertTrue("singleton not instantiated", !KnowsIfInstantiated.wasInstantiated());
- (new PropertiesBeanDefinitionReader(lbf)).registerBeanDefinitions(p);
- assertTrue("singleton not instantiated", !KnowsIfInstantiated.wasInstantiated());
- lbf.preInstantiateSingletons();
-
- assertTrue("singleton not instantiated", !KnowsIfInstantiated.wasInstantiated());
- lbf.getBean("x1");
- assertTrue("singleton was instantiated", KnowsIfInstantiated.wasInstantiated());
- }
-
- @Test
- public void testFactoryBeanDidNotCreatePrototype() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- Properties p = new Properties();
- p.setProperty("x1.(class)", DummyFactory.class.getName());
- // Reset static state
- DummyFactory.reset();
- p.setProperty("x1.singleton", "false");
- assertTrue("prototype not instantiated", !DummyFactory.wasPrototypeCreated());
- (new PropertiesBeanDefinitionReader(lbf)).registerBeanDefinitions(p);
- assertTrue("prototype not instantiated", !DummyFactory.wasPrototypeCreated());
- assertEquals(TestBean.class, lbf.getType("x1"));
- lbf.preInstantiateSingletons();
-
- assertTrue("prototype not instantiated", !DummyFactory.wasPrototypeCreated());
- lbf.getBean("x1");
- assertEquals(TestBean.class, lbf.getType("x1"));
- assertTrue(lbf.containsBean("x1"));
- assertTrue(lbf.containsBean("&x1"));
- assertTrue("prototype was instantiated", DummyFactory.wasPrototypeCreated());
- }
-
- @Test
- public void testPrototypeFactoryBeanIgnoredByNonEagerTypeMatching() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- Properties p = new Properties();
- p.setProperty("x1.(class)", DummyFactory.class.getName());
- // Reset static state
- DummyFactory.reset();
- p.setProperty("x1.(singleton)", "false");
- p.setProperty("x1.singleton", "false");
- (new PropertiesBeanDefinitionReader(lbf)).registerBeanDefinitions(p);
-
- assertTrue("prototype not instantiated", !DummyFactory.wasPrototypeCreated());
- String[] beanNames = lbf.getBeanNamesForType(TestBean.class, true, false);
- assertEquals(0, beanNames.length);
- beanNames = lbf.getBeanNamesForAnnotation(SuppressWarnings.class);
- assertEquals(0, beanNames.length);
-
- assertFalse(lbf.containsSingleton("x1"));
- assertTrue(lbf.containsBean("x1"));
- assertTrue(lbf.containsBean("&x1"));
- assertFalse(lbf.isSingleton("x1"));
- assertFalse(lbf.isSingleton("&x1"));
- assertTrue(lbf.isPrototype("x1"));
- assertTrue(lbf.isPrototype("&x1"));
- assertTrue(lbf.isTypeMatch("x1", TestBean.class));
- assertFalse(lbf.isTypeMatch("&x1", TestBean.class));
- assertTrue(lbf.isTypeMatch("&x1", DummyFactory.class));
- assertTrue(lbf.isTypeMatch("&x1", ResolvableType.forClass(DummyFactory.class)));
- assertTrue(lbf.isTypeMatch("&x1", ResolvableType.forClassWithGenerics(FactoryBean.class, Object.class)));
- assertFalse(lbf.isTypeMatch("&x1", ResolvableType.forClassWithGenerics(FactoryBean.class, String.class)));
- assertEquals(TestBean.class, lbf.getType("x1"));
- assertEquals(DummyFactory.class, lbf.getType("&x1"));
- assertTrue("prototype not instantiated", !DummyFactory.wasPrototypeCreated());
- }
-
- @Test
- public void testSingletonFactoryBeanIgnoredByNonEagerTypeMatching() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- Properties p = new Properties();
- p.setProperty("x1.(class)", DummyFactory.class.getName());
- // Reset static state
- DummyFactory.reset();
- p.setProperty("x1.(singleton)", "false");
- p.setProperty("x1.singleton", "true");
- (new PropertiesBeanDefinitionReader(lbf)).registerBeanDefinitions(p);
-
- assertTrue("prototype not instantiated", !DummyFactory.wasPrototypeCreated());
- String[] beanNames = lbf.getBeanNamesForType(TestBean.class, true, false);
- assertEquals(0, beanNames.length);
- beanNames = lbf.getBeanNamesForAnnotation(SuppressWarnings.class);
- assertEquals(0, beanNames.length);
-
- assertFalse(lbf.containsSingleton("x1"));
- assertTrue(lbf.containsBean("x1"));
- assertTrue(lbf.containsBean("&x1"));
- assertFalse(lbf.isSingleton("x1"));
- assertFalse(lbf.isSingleton("&x1"));
- assertTrue(lbf.isPrototype("x1"));
- assertTrue(lbf.isPrototype("&x1"));
- assertTrue(lbf.isTypeMatch("x1", TestBean.class));
- assertFalse(lbf.isTypeMatch("&x1", TestBean.class));
- assertTrue(lbf.isTypeMatch("&x1", DummyFactory.class));
- assertTrue(lbf.isTypeMatch("&x1", ResolvableType.forClass(DummyFactory.class)));
- assertTrue(lbf.isTypeMatch("&x1", ResolvableType.forClassWithGenerics(FactoryBean.class, Object.class)));
- assertFalse(lbf.isTypeMatch("&x1", ResolvableType.forClassWithGenerics(FactoryBean.class, String.class)));
- assertEquals(TestBean.class, lbf.getType("x1"));
- assertEquals(DummyFactory.class, lbf.getType("&x1"));
- assertTrue("prototype not instantiated", !DummyFactory.wasPrototypeCreated());
- }
-
- @Test
- public void testNonInitializedFactoryBeanIgnoredByNonEagerTypeMatching() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- Properties p = new Properties();
- p.setProperty("x1.(class)", DummyFactory.class.getName());
- // Reset static state
- DummyFactory.reset();
- p.setProperty("x1.singleton", "false");
- (new PropertiesBeanDefinitionReader(lbf)).registerBeanDefinitions(p);
-
- assertTrue("prototype not instantiated", !DummyFactory.wasPrototypeCreated());
- String[] beanNames = lbf.getBeanNamesForType(TestBean.class, true, false);
- assertEquals(0, beanNames.length);
- beanNames = lbf.getBeanNamesForAnnotation(SuppressWarnings.class);
- assertEquals(0, beanNames.length);
-
- assertFalse(lbf.containsSingleton("x1"));
- assertTrue(lbf.containsBean("x1"));
- assertTrue(lbf.containsBean("&x1"));
- assertFalse(lbf.isSingleton("x1"));
- assertTrue(lbf.isSingleton("&x1"));
- assertTrue(lbf.isPrototype("x1"));
- assertFalse(lbf.isPrototype("&x1"));
- assertTrue(lbf.isTypeMatch("x1", TestBean.class));
- assertFalse(lbf.isTypeMatch("&x1", TestBean.class));
- assertTrue(lbf.isTypeMatch("&x1", DummyFactory.class));
- assertTrue(lbf.isTypeMatch("&x1", ResolvableType.forClass(DummyFactory.class)));
- assertTrue(lbf.isTypeMatch("&x1", ResolvableType.forClassWithGenerics(FactoryBean.class, Object.class)));
- assertFalse(lbf.isTypeMatch("&x1", ResolvableType.forClassWithGenerics(FactoryBean.class, String.class)));
- assertEquals(TestBean.class, lbf.getType("x1"));
- assertEquals(DummyFactory.class, lbf.getType("&x1"));
- assertTrue("prototype not instantiated", !DummyFactory.wasPrototypeCreated());
- }
-
- @Test
- public void testInitializedFactoryBeanFoundByNonEagerTypeMatching() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- Properties p = new Properties();
- p.setProperty("x1.(class)", DummyFactory.class.getName());
- // Reset static state
- DummyFactory.reset();
- p.setProperty("x1.singleton", "false");
- (new PropertiesBeanDefinitionReader(lbf)).registerBeanDefinitions(p);
- lbf.preInstantiateSingletons();
-
- assertTrue("prototype not instantiated", !DummyFactory.wasPrototypeCreated());
- String[] beanNames = lbf.getBeanNamesForType(TestBean.class, true, false);
- assertEquals(1, beanNames.length);
- assertEquals("x1", beanNames[0]);
- assertTrue(lbf.containsSingleton("x1"));
- assertTrue(lbf.containsBean("x1"));
- assertTrue(lbf.containsBean("&x1"));
- assertTrue(lbf.containsLocalBean("x1"));
- assertTrue(lbf.containsLocalBean("&x1"));
- assertFalse(lbf.isSingleton("x1"));
- assertTrue(lbf.isSingleton("&x1"));
- assertTrue(lbf.isPrototype("x1"));
- assertFalse(lbf.isPrototype("&x1"));
- assertTrue(lbf.isTypeMatch("x1", TestBean.class));
- assertFalse(lbf.isTypeMatch("&x1", TestBean.class));
- assertTrue(lbf.isTypeMatch("&x1", DummyFactory.class));
- assertTrue(lbf.isTypeMatch("x1", Object.class));
- assertTrue(lbf.isTypeMatch("&x1", Object.class));
- assertEquals(TestBean.class, lbf.getType("x1"));
- assertEquals(DummyFactory.class, lbf.getType("&x1"));
- assertTrue("prototype not instantiated", !DummyFactory.wasPrototypeCreated());
-
- lbf.registerAlias("x1", "x2");
- assertTrue(lbf.containsBean("x2"));
- assertTrue(lbf.containsBean("&x2"));
- assertTrue(lbf.containsLocalBean("x2"));
- assertTrue(lbf.containsLocalBean("&x2"));
- assertFalse(lbf.isSingleton("x2"));
- assertTrue(lbf.isSingleton("&x2"));
- assertTrue(lbf.isPrototype("x2"));
- assertFalse(lbf.isPrototype("&x2"));
- assertTrue(lbf.isTypeMatch("x2", TestBean.class));
- assertFalse(lbf.isTypeMatch("&x2", TestBean.class));
- assertTrue(lbf.isTypeMatch("&x2", DummyFactory.class));
- assertTrue(lbf.isTypeMatch("x2", Object.class));
- assertTrue(lbf.isTypeMatch("&x2", Object.class));
- assertEquals(TestBean.class, lbf.getType("x2"));
- assertEquals(DummyFactory.class, lbf.getType("&x2"));
- assertEquals(1, lbf.getAliases("x1").length);
- assertEquals("x2", lbf.getAliases("x1")[0]);
- assertEquals(1, lbf.getAliases("&x1").length);
- assertEquals("&x2", lbf.getAliases("&x1")[0]);
- assertEquals(1, lbf.getAliases("x2").length);
- assertEquals("x1", lbf.getAliases("x2")[0]);
- assertEquals(1, lbf.getAliases("&x2").length);
- assertEquals("&x1", lbf.getAliases("&x2")[0]);
- }
-
- @Test
- public void testStaticFactoryMethodFoundByNonEagerTypeMatching() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- RootBeanDefinition rbd = new RootBeanDefinition(TestBeanFactory.class);
- rbd.setFactoryMethodName("createTestBean");
- lbf.registerBeanDefinition("x1", rbd);
-
- TestBeanFactory.initialized = false;
- String[] beanNames = lbf.getBeanNamesForType(TestBean.class, true, false);
- assertEquals(1, beanNames.length);
- assertEquals("x1", beanNames[0]);
- assertFalse(lbf.containsSingleton("x1"));
- assertTrue(lbf.containsBean("x1"));
- assertFalse(lbf.containsBean("&x1"));
- assertTrue(lbf.isSingleton("x1"));
- assertFalse(lbf.isSingleton("&x1"));
- assertFalse(lbf.isPrototype("x1"));
- assertFalse(lbf.isPrototype("&x1"));
- assertTrue(lbf.isTypeMatch("x1", TestBean.class));
- assertFalse(lbf.isTypeMatch("&x1", TestBean.class));
- assertEquals(TestBean.class, lbf.getType("x1"));
- assertEquals(null, lbf.getType("&x1"));
- assertFalse(TestBeanFactory.initialized);
- }
-
- @Test
- public void testStaticPrototypeFactoryMethodFoundByNonEagerTypeMatching() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- RootBeanDefinition rbd = new RootBeanDefinition(TestBeanFactory.class);
- rbd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
- rbd.setFactoryMethodName("createTestBean");
- lbf.registerBeanDefinition("x1", rbd);
-
- TestBeanFactory.initialized = false;
- String[] beanNames = lbf.getBeanNamesForType(TestBean.class, true, false);
- assertEquals(1, beanNames.length);
- assertEquals("x1", beanNames[0]);
- assertFalse(lbf.containsSingleton("x1"));
- assertTrue(lbf.containsBean("x1"));
- assertFalse(lbf.containsBean("&x1"));
- assertFalse(lbf.isSingleton("x1"));
- assertFalse(lbf.isSingleton("&x1"));
- assertTrue(lbf.isPrototype("x1"));
- assertFalse(lbf.isPrototype("&x1"));
- assertTrue(lbf.isTypeMatch("x1", TestBean.class));
- assertFalse(lbf.isTypeMatch("&x1", TestBean.class));
- assertEquals(TestBean.class, lbf.getType("x1"));
- assertEquals(null, lbf.getType("&x1"));
- assertFalse(TestBeanFactory.initialized);
- }
-
- @Test
- public void testNonStaticFactoryMethodFoundByNonEagerTypeMatching() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- RootBeanDefinition factoryBd = new RootBeanDefinition(TestBeanFactory.class);
- lbf.registerBeanDefinition("factory", factoryBd);
- RootBeanDefinition rbd = new RootBeanDefinition(TestBeanFactory.class);
- rbd.setFactoryBeanName("factory");
- rbd.setFactoryMethodName("createTestBeanNonStatic");
- lbf.registerBeanDefinition("x1", rbd);
-
- TestBeanFactory.initialized = false;
- String[] beanNames = lbf.getBeanNamesForType(TestBean.class, true, false);
- assertEquals(1, beanNames.length);
- assertEquals("x1", beanNames[0]);
- assertFalse(lbf.containsSingleton("x1"));
- assertTrue(lbf.containsBean("x1"));
- assertFalse(lbf.containsBean("&x1"));
- assertTrue(lbf.isSingleton("x1"));
- assertFalse(lbf.isSingleton("&x1"));
- assertFalse(lbf.isPrototype("x1"));
- assertFalse(lbf.isPrototype("&x1"));
- assertTrue(lbf.isTypeMatch("x1", TestBean.class));
- assertFalse(lbf.isTypeMatch("&x1", TestBean.class));
- assertEquals(TestBean.class, lbf.getType("x1"));
- assertEquals(null, lbf.getType("&x1"));
- assertFalse(TestBeanFactory.initialized);
- }
-
- @Test
- public void testNonStaticPrototypeFactoryMethodFoundByNonEagerTypeMatching() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- RootBeanDefinition factoryBd = new RootBeanDefinition(TestBeanFactory.class);
- lbf.registerBeanDefinition("factory", factoryBd);
- RootBeanDefinition rbd = new RootBeanDefinition();
- rbd.setFactoryBeanName("factory");
- rbd.setFactoryMethodName("createTestBeanNonStatic");
- rbd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
- lbf.registerBeanDefinition("x1", rbd);
-
- TestBeanFactory.initialized = false;
- String[] beanNames = lbf.getBeanNamesForType(TestBean.class, true, false);
- assertEquals(1, beanNames.length);
- assertEquals("x1", beanNames[0]);
- assertFalse(lbf.containsSingleton("x1"));
- assertTrue(lbf.containsBean("x1"));
- assertFalse(lbf.containsBean("&x1"));
- assertTrue(lbf.containsLocalBean("x1"));
- assertFalse(lbf.containsLocalBean("&x1"));
- assertFalse(lbf.isSingleton("x1"));
- assertFalse(lbf.isSingleton("&x1"));
- assertTrue(lbf.isPrototype("x1"));
- assertFalse(lbf.isPrototype("&x1"));
- assertTrue(lbf.isTypeMatch("x1", TestBean.class));
- assertFalse(lbf.isTypeMatch("&x1", TestBean.class));
- assertTrue(lbf.isTypeMatch("x1", Object.class));
- assertFalse(lbf.isTypeMatch("&x1", Object.class));
- assertEquals(TestBean.class, lbf.getType("x1"));
- assertEquals(null, lbf.getType("&x1"));
- assertFalse(TestBeanFactory.initialized);
-
- lbf.registerAlias("x1", "x2");
- assertTrue(lbf.containsBean("x2"));
- assertFalse(lbf.containsBean("&x2"));
- assertTrue(lbf.containsLocalBean("x2"));
- assertFalse(lbf.containsLocalBean("&x2"));
- assertFalse(lbf.isSingleton("x2"));
- assertFalse(lbf.isSingleton("&x2"));
- assertTrue(lbf.isPrototype("x2"));
- assertFalse(lbf.isPrototype("&x2"));
- assertTrue(lbf.isTypeMatch("x2", TestBean.class));
- assertFalse(lbf.isTypeMatch("&x2", TestBean.class));
- assertTrue(lbf.isTypeMatch("x2", Object.class));
- assertFalse(lbf.isTypeMatch("&x2", Object.class));
- assertEquals(TestBean.class, lbf.getType("x2"));
- assertEquals(null, lbf.getType("&x2"));
- assertEquals(1, lbf.getAliases("x1").length);
- assertEquals("x2", lbf.getAliases("x1")[0]);
- assertEquals(1, lbf.getAliases("&x1").length);
- assertEquals("&x2", lbf.getAliases("&x1")[0]);
- assertEquals(1, lbf.getAliases("x2").length);
- assertEquals("x1", lbf.getAliases("x2")[0]);
- assertEquals(1, lbf.getAliases("&x2").length);
- assertEquals("&x1", lbf.getAliases("&x2")[0]);
- }
-
- @Test
- public void testEmpty() {
- ListableBeanFactory lbf = new DefaultListableBeanFactory();
- assertTrue("No beans defined --> array != null", lbf.getBeanDefinitionNames() != null);
- assertTrue("No beans defined after no arg constructor", lbf.getBeanDefinitionNames().length == 0);
- assertTrue("No beans defined after no arg constructor", lbf.getBeanDefinitionCount() == 0);
- }
-
- @Test
- public void testEmptyPropertiesPopulation() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- Properties p = new Properties();
- (new PropertiesBeanDefinitionReader(lbf)).registerBeanDefinitions(p);
- assertTrue("No beans defined after ignorable invalid", lbf.getBeanDefinitionCount() == 0);
- }
-
- @Test
- public void testHarmlessIgnorableRubbish() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- Properties p = new Properties();
- p.setProperty("foo", "bar");
- p.setProperty("qwert", "er");
- (new PropertiesBeanDefinitionReader(lbf)).registerBeanDefinitions(p, "test");
- assertTrue("No beans defined after harmless ignorable rubbish", lbf.getBeanDefinitionCount() == 0);
- }
-
- @Test
- public void testPropertiesPopulationWithNullPrefix() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- Properties p = new Properties();
- p.setProperty("test.(class)", TestBean.class.getName());
- p.setProperty("test.name", "Tony");
- p.setProperty("test.age", "48");
- int count = (new PropertiesBeanDefinitionReader(lbf)).registerBeanDefinitions(p);
- assertTrue("1 beans registered, not " + count, count == 1);
- testSingleTestBean(lbf);
- }
-
- @Test
- public void testPropertiesPopulationWithPrefix() {
- String PREFIX = "beans.";
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- Properties p = new Properties();
- p.setProperty(PREFIX + "test.(class)", TestBean.class.getName());
- p.setProperty(PREFIX + "test.name", "Tony");
- p.setProperty(PREFIX + "test.age", "0x30");
- int count = (new PropertiesBeanDefinitionReader(lbf)).registerBeanDefinitions(p, PREFIX);
- assertTrue("1 beans registered, not " + count, count == 1);
- testSingleTestBean(lbf);
- }
-
- @Test
- public void testSimpleReference() {
- String PREFIX = "beans.";
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- Properties p = new Properties();
-
- p.setProperty(PREFIX + "rod.(class)", TestBean.class.getName());
- p.setProperty(PREFIX + "rod.name", "Rod");
-
- p.setProperty(PREFIX + "kerry.(class)", TestBean.class.getName());
- p.setProperty(PREFIX + "kerry.name", "Kerry");
- p.setProperty(PREFIX + "kerry.age", "35");
- p.setProperty(PREFIX + "kerry.spouse(ref)", "rod");
-
- int count = (new PropertiesBeanDefinitionReader(lbf)).registerBeanDefinitions(p, PREFIX);
- assertTrue("2 beans registered, not " + count, count == 2);
-
- TestBean kerry = lbf.getBean("kerry", TestBean.class);
- assertTrue("Kerry name is Kerry", "Kerry".equals(kerry.getName()));
- ITestBean spouse = kerry.getSpouse();
- assertTrue("Kerry spouse is non null", spouse != null);
- assertTrue("Kerry spouse name is Rod", "Rod".equals(spouse.getName()));
- }
-
- @Test
- public void testPropertiesWithDotsInKey() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- Properties p = new Properties();
-
- p.setProperty("tb.(class)", TestBean.class.getName());
- p.setProperty("tb.someMap[my.key]", "my.value");
-
- int count = (new PropertiesBeanDefinitionReader(lbf)).registerBeanDefinitions(p);
- assertTrue("1 beans registered, not " + count, count == 1);
- assertEquals(1, lbf.getBeanDefinitionCount());
-
- TestBean tb = lbf.getBean("tb", TestBean.class);
- assertEquals("my.value", tb.getSomeMap().get("my.key"));
- }
-
- @Test
- public void testUnresolvedReference() {
- String PREFIX = "beans.";
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- Properties p = new Properties();
-
- try {
- p.setProperty(PREFIX + "kerry.(class)", TestBean.class.getName());
- p.setProperty(PREFIX + "kerry.name", "Kerry");
- p.setProperty(PREFIX + "kerry.age", "35");
- p.setProperty(PREFIX + "kerry.spouse(ref)", "rod");
-
- (new PropertiesBeanDefinitionReader(lbf)).registerBeanDefinitions(p, PREFIX);
-
- lbf.getBean("kerry");
- fail("Unresolved reference should have been detected");
- }
- catch (BeansException ex) {
- // cool
- }
- }
-
- @Test
- public void testSelfReference() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- MutablePropertyValues pvs = new MutablePropertyValues();
- pvs.add("spouse", new RuntimeBeanReference("self"));
- RootBeanDefinition bd = new RootBeanDefinition(TestBean.class);
- bd.setPropertyValues(pvs);
- lbf.registerBeanDefinition("self", bd);
- TestBean self = (TestBean) lbf.getBean("self");
- assertEquals(self, self.getSpouse());
- }
-
- @Test
- public void testPossibleMatches() {
- try {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- MutablePropertyValues pvs = new MutablePropertyValues();
- pvs.add("ag", "foobar");
- RootBeanDefinition bd = new RootBeanDefinition(TestBean.class);
- bd.setPropertyValues(pvs);
- lbf.registerBeanDefinition("tb", bd);
- lbf.getBean("tb");
- fail("Should throw exception on invalid property");
- }
- catch (BeanCreationException ex) {
- assertTrue(ex.getCause() instanceof NotWritablePropertyException);
- NotWritablePropertyException cause = (NotWritablePropertyException) ex.getCause();
- // expected
- assertEquals(1, cause.getPossibleMatches().length);
- assertEquals("age", cause.getPossibleMatches()[0]);
- }
- }
-
- @Test
- public void testPrototype() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- Properties p = new Properties();
- p.setProperty("kerry.(class)", TestBean.class.getName());
- p.setProperty("kerry.age", "35");
- (new PropertiesBeanDefinitionReader(lbf)).registerBeanDefinitions(p);
- TestBean kerry1 = (TestBean) lbf.getBean("kerry");
- TestBean kerry2 = (TestBean) lbf.getBean("kerry");
- assertTrue("Non null", kerry1 != null);
- assertTrue("Singletons equal", kerry1 == kerry2);
-
- lbf = new DefaultListableBeanFactory();
- p = new Properties();
- p.setProperty("kerry.(class)", TestBean.class.getName());
- p.setProperty("kerry.(scope)", "prototype");
- p.setProperty("kerry.age", "35");
- (new PropertiesBeanDefinitionReader(lbf)).registerBeanDefinitions(p);
- kerry1 = (TestBean) lbf.getBean("kerry");
- kerry2 = (TestBean) lbf.getBean("kerry");
- assertTrue("Non null", kerry1 != null);
- assertTrue("Prototypes NOT equal", kerry1 != kerry2);
-
- lbf = new DefaultListableBeanFactory();
- p = new Properties();
- p.setProperty("kerry.(class)", TestBean.class.getName());
- p.setProperty("kerry.(scope)", "singleton");
- p.setProperty("kerry.age", "35");
- (new PropertiesBeanDefinitionReader(lbf)).registerBeanDefinitions(p);
- kerry1 = (TestBean) lbf.getBean("kerry");
- kerry2 = (TestBean) lbf.getBean("kerry");
- assertTrue("Non null", kerry1 != null);
- assertTrue("Specified singletons equal", kerry1 == kerry2);
- }
-
- @Test
- public void testPrototypeCircleLeadsToException() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- Properties p = new Properties();
- p.setProperty("kerry.(class)", TestBean.class.getName());
- p.setProperty("kerry.(singleton)", "false");
- p.setProperty("kerry.age", "35");
- p.setProperty("kerry.spouse", "*rod");
- p.setProperty("rod.(class)", TestBean.class.getName());
- p.setProperty("rod.(singleton)", "false");
- p.setProperty("rod.age", "34");
- p.setProperty("rod.spouse", "*kerry");
-
- (new PropertiesBeanDefinitionReader(lbf)).registerBeanDefinitions(p);
- try {
- lbf.getBean("kerry");
- fail("Should have thrown BeanCreationException");
- }
- catch (BeanCreationException ex) {
- // expected
- assertTrue(ex.contains(BeanCurrentlyInCreationException.class));
- }
- }
-
- @Test
- public void testPrototypeExtendsPrototype() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- Properties p = new Properties();
- p.setProperty("wife.(class)", TestBean.class.getName());
- p.setProperty("wife.name", "kerry");
-
- p.setProperty("kerry.(parent)", "wife");
- p.setProperty("kerry.age", "35");
- (new PropertiesBeanDefinitionReader(lbf)).registerBeanDefinitions(p);
- TestBean kerry1 = (TestBean) lbf.getBean("kerry");
- TestBean kerry2 = (TestBean) lbf.getBean("kerry");
- assertEquals("kerry", kerry1.getName());
- assertNotNull("Non null", kerry1);
- assertTrue("Singletons equal", kerry1 == kerry2);
-
- lbf = new DefaultListableBeanFactory();
- p = new Properties();
- p.setProperty("wife.(class)", TestBean.class.getName());
- p.setProperty("wife.name", "kerry");
- p.setProperty("wife.(singleton)", "false");
- p.setProperty("kerry.(parent)", "wife");
- p.setProperty("kerry.(singleton)", "false");
- p.setProperty("kerry.age", "35");
- (new PropertiesBeanDefinitionReader(lbf)).registerBeanDefinitions(p);
- assertFalse(lbf.isSingleton("kerry"));
- kerry1 = (TestBean) lbf.getBean("kerry");
- kerry2 = (TestBean) lbf.getBean("kerry");
- assertTrue("Non null", kerry1 != null);
- assertTrue("Prototypes NOT equal", kerry1 != kerry2);
-
- lbf = new DefaultListableBeanFactory();
- p = new Properties();
- p.setProperty("kerry.(class)", TestBean.class.getName());
- p.setProperty("kerry.(singleton)", "true");
- p.setProperty("kerry.age", "35");
- (new PropertiesBeanDefinitionReader(lbf)).registerBeanDefinitions(p);
- kerry1 = (TestBean) lbf.getBean("kerry");
- kerry2 = (TestBean) lbf.getBean("kerry");
- assertTrue("Non null", kerry1 != null);
- assertTrue("Specified singletons equal", kerry1 == kerry2);
- }
-
- @Test
- public void testCanReferenceParentBeanFromChildViaAlias() {
- final String EXPECTED_NAME = "Juergen";
- final int EXPECTED_AGE = 41;
-
- RootBeanDefinition parentDefinition = new RootBeanDefinition(TestBean.class);
- parentDefinition.setAbstract(true);
- parentDefinition.getPropertyValues().add("name", EXPECTED_NAME);
- parentDefinition.getPropertyValues().add("age", EXPECTED_AGE);
-
- ChildBeanDefinition childDefinition = new ChildBeanDefinition("alias");
-
- DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
- factory.registerBeanDefinition("parent", parentDefinition);
- factory.registerBeanDefinition("child", childDefinition);
- factory.registerAlias("parent", "alias");
-
- TestBean child = (TestBean) factory.getBean("child");
- assertEquals(EXPECTED_NAME, child.getName());
- assertEquals(EXPECTED_AGE, child.getAge());
-
- assertEquals("Use cached merged bean definition",
- factory.getMergedBeanDefinition("child"), factory.getMergedBeanDefinition("child"));
- }
-
- @Test
- public void testGetTypeWorksAfterParentChildMerging() {
- RootBeanDefinition parentDefinition = new RootBeanDefinition(TestBean.class);
- ChildBeanDefinition childDefinition = new ChildBeanDefinition("parent", DerivedTestBean.class, null, null);
-
- DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
- factory.registerBeanDefinition("parent", parentDefinition);
- factory.registerBeanDefinition("child", childDefinition);
- factory.freezeConfiguration();
-
- assertEquals(TestBean.class, factory.getType("parent"));
- assertEquals(DerivedTestBean.class, factory.getType("child"));
- }
-
- @Test
- public void testNameAlreadyBound() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- Properties p = new Properties();
- p.setProperty("kerry.(class)", TestBean.class.getName());
- p.setProperty("kerry.age", "35");
- (new PropertiesBeanDefinitionReader(lbf)).registerBeanDefinitions(p);
- try {
- (new PropertiesBeanDefinitionReader(lbf)).registerBeanDefinitions(p);
- }
- catch (BeanDefinitionStoreException ex) {
- assertEquals("kerry", ex.getBeanName());
- // expected
- }
- }
-
- private void testSingleTestBean(ListableBeanFactory lbf) {
- assertTrue("1 beans defined", lbf.getBeanDefinitionCount() == 1);
- String[] names = lbf.getBeanDefinitionNames();
- assertTrue(names != lbf.getBeanDefinitionNames());
- assertTrue("Array length == 1", names.length == 1);
- assertTrue("0th element == test", names[0].equals("test"));
- TestBean tb = (TestBean) lbf.getBean("test");
- assertTrue("Test is non null", tb != null);
- assertTrue("Test bean name is Tony", "Tony".equals(tb.getName()));
- assertTrue("Test bean age is 48", tb.getAge() == 48);
- }
-
- @Test
- public void testAliasCircle() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- lbf.registerAlias("test", "test2");
- lbf.registerAlias("test2", "test3");
-
- try {
- lbf.registerAlias("test3", "test2");
- fail("Should have thrown IllegalStateException");
- }
- catch (IllegalStateException ex) {
- // expected
- }
-
- try {
- lbf.registerAlias("test3", "test");
- fail("Should have thrown IllegalStateException");
- }
- catch (IllegalStateException ex) {
- // expected
- }
-
- lbf.registerAlias("test", "test3");
- }
-
- @Test
- public void testBeanDefinitionOverriding() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- lbf.registerBeanDefinition("test", new RootBeanDefinition(TestBean.class));
- lbf.registerBeanDefinition("test", new RootBeanDefinition(NestedTestBean.class));
- lbf.registerAlias("otherTest", "test2");
- lbf.registerAlias("test", "test2");
- assertTrue(lbf.getBean("test") instanceof NestedTestBean);
- assertTrue(lbf.getBean("test2") instanceof NestedTestBean);
- }
-
- @Test
- public void testBeanDefinitionRemoval() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- lbf.setAllowBeanDefinitionOverriding(false);
- lbf.registerBeanDefinition("test", new RootBeanDefinition(TestBean.class));
- lbf.registerAlias("test", "test2");
- lbf.preInstantiateSingletons();
- lbf.removeBeanDefinition("test");
- lbf.removeAlias("test2");
- lbf.registerBeanDefinition("test", new RootBeanDefinition(NestedTestBean.class));
- lbf.registerAlias("test", "test2");
- assertTrue(lbf.getBean("test") instanceof NestedTestBean);
- assertTrue(lbf.getBean("test2") instanceof NestedTestBean);
- }
-
- @Test
- public void testBeanDefinitionOverridingNotAllowed() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- lbf.setAllowBeanDefinitionOverriding(false);
- BeanDefinition oldDef = new RootBeanDefinition(TestBean.class);
- BeanDefinition newDef = new RootBeanDefinition(NestedTestBean.class);
- lbf.registerBeanDefinition("test", oldDef);
- try {
- lbf.registerBeanDefinition("test", newDef);
- fail("Should have thrown BeanDefinitionOverrideException");
- }
- catch (BeanDefinitionOverrideException ex) {
- assertEquals("test", ex.getBeanName());
- assertSame(newDef, ex.getBeanDefinition());
- assertSame(oldDef, ex.getExistingDefinition());
- }
- }
-
- @Test
- public void testBeanDefinitionOverridingWithAlias() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- lbf.registerBeanDefinition("test", new RootBeanDefinition(TestBean.class));
- lbf.registerAlias("test", "testAlias");
- lbf.registerBeanDefinition("test", new RootBeanDefinition(NestedTestBean.class));
- lbf.registerAlias("test", "testAlias");
- assertTrue(lbf.getBean("test") instanceof NestedTestBean);
- assertTrue(lbf.getBean("testAlias") instanceof NestedTestBean);
- }
-
- @Test
- public void testAliasChaining() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- lbf.registerBeanDefinition("test", new RootBeanDefinition(NestedTestBean.class));
- lbf.registerAlias("test", "testAlias");
- lbf.registerAlias("testAlias", "testAlias2");
- lbf.registerAlias("testAlias2", "testAlias3");
- Object bean = lbf.getBean("test");
- assertSame(bean, lbf.getBean("testAlias"));
- assertSame(bean, lbf.getBean("testAlias2"));
- assertSame(bean, lbf.getBean("testAlias3"));
- }
-
- @Test
- public void testBeanReferenceWithNewSyntax() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- Properties p = new Properties();
- p.setProperty("r.(class)", TestBean.class.getName());
- p.setProperty("r.name", "rod");
- p.setProperty("k.(class)", TestBean.class.getName());
- p.setProperty("k.name", "kerry");
- p.setProperty("k.spouse", "*r");
- (new PropertiesBeanDefinitionReader(lbf)).registerBeanDefinitions(p);
- TestBean k = (TestBean) lbf.getBean("k");
- TestBean r = (TestBean) lbf.getBean("r");
- assertTrue(k.getSpouse() == r);
- }
-
- @Test
- public void testCanEscapeBeanReferenceSyntax() {
- String name = "*name";
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- Properties p = new Properties();
- p.setProperty("r.(class)", TestBean.class.getName());
- p.setProperty("r.name", "*" + name);
- (new PropertiesBeanDefinitionReader(lbf)).registerBeanDefinitions(p);
- TestBean r = (TestBean) lbf.getBean("r");
- assertTrue(r.getName().equals(name));
- }
-
- @Test
- public void testCustomEditor() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- lbf.addPropertyEditorRegistrar(new PropertyEditorRegistrar() {
- @Override
- public void registerCustomEditors(PropertyEditorRegistry registry) {
- NumberFormat nf = NumberFormat.getInstance(Locale.GERMAN);
- registry.registerCustomEditor(Float.class, new CustomNumberEditor(Float.class, nf, true));
- }
- });
- MutablePropertyValues pvs = new MutablePropertyValues();
- pvs.add("myFloat", "1,1");
- RootBeanDefinition bd = new RootBeanDefinition(TestBean.class);
- bd.setPropertyValues(pvs);
- lbf.registerBeanDefinition("testBean", bd);
- TestBean testBean = (TestBean) lbf.getBean("testBean");
- assertTrue(testBean.getMyFloat().floatValue() == 1.1f);
- }
-
- @Test
- public void testCustomConverter() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- GenericConversionService conversionService = new DefaultConversionService();
- conversionService.addConverter(new Converter() {
- @Override
- public Float convert(String source) {
- try {
- NumberFormat nf = NumberFormat.getInstance(Locale.GERMAN);
- return nf.parse(source).floatValue();
- }
- catch (ParseException ex) {
- throw new IllegalArgumentException(ex);
- }
- }
- });
- lbf.setConversionService(conversionService);
- MutablePropertyValues pvs = new MutablePropertyValues();
- pvs.add("myFloat", "1,1");
- RootBeanDefinition bd = new RootBeanDefinition(TestBean.class);
- bd.setPropertyValues(pvs);
- lbf.registerBeanDefinition("testBean", bd);
- TestBean testBean = (TestBean) lbf.getBean("testBean");
- assertTrue(testBean.getMyFloat().floatValue() == 1.1f);
- }
-
- @Test
- public void testCustomEditorWithBeanReference() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- lbf.addPropertyEditorRegistrar(new PropertyEditorRegistrar() {
- @Override
- public void registerCustomEditors(PropertyEditorRegistry registry) {
- NumberFormat nf = NumberFormat.getInstance(Locale.GERMAN);
- registry.registerCustomEditor(Float.class, new CustomNumberEditor(Float.class, nf, true));
- }
- });
- MutablePropertyValues pvs = new MutablePropertyValues();
- pvs.add("myFloat", new RuntimeBeanReference("myFloat"));
- RootBeanDefinition bd = new RootBeanDefinition(TestBean.class);
- bd.setPropertyValues(pvs);
- lbf.registerBeanDefinition("testBean", bd);
- lbf.registerSingleton("myFloat", "1,1");
- TestBean testBean = (TestBean) lbf.getBean("testBean");
- assertTrue(testBean.getMyFloat().floatValue() == 1.1f);
- }
-
- @Test
- public void testCustomTypeConverter() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- NumberFormat nf = NumberFormat.getInstance(Locale.GERMAN);
- lbf.setTypeConverter(new CustomTypeConverter(nf));
- MutablePropertyValues pvs = new MutablePropertyValues();
- pvs.add("myFloat", "1,1");
- ConstructorArgumentValues cav = new ConstructorArgumentValues();
- cav.addIndexedArgumentValue(0, "myName");
- cav.addIndexedArgumentValue(1, "myAge");
- lbf.registerBeanDefinition("testBean", new RootBeanDefinition(TestBean.class, cav, pvs));
- TestBean testBean = (TestBean) lbf.getBean("testBean");
- assertEquals("myName", testBean.getName());
- assertEquals(5, testBean.getAge());
- assertTrue(testBean.getMyFloat().floatValue() == 1.1f);
- }
+public class DefaultListableBeanFactoryTests extends AbstractDefaultListableBeanFactoryTests {
- @Test
- public void testCustomTypeConverterWithBeanReference() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- NumberFormat nf = NumberFormat.getInstance(Locale.GERMAN);
- lbf.setTypeConverter(new CustomTypeConverter(nf));
- MutablePropertyValues pvs = new MutablePropertyValues();
- pvs.add("myFloat", new RuntimeBeanReference("myFloat"));
- ConstructorArgumentValues cav = new ConstructorArgumentValues();
- cav.addIndexedArgumentValue(0, "myName");
- cav.addIndexedArgumentValue(1, "myAge");
- lbf.registerBeanDefinition("testBean", new RootBeanDefinition(TestBean.class, cav, pvs));
- lbf.registerSingleton("myFloat", "1,1");
- TestBean testBean = (TestBean) lbf.getBean("testBean");
- assertEquals("myName", testBean.getName());
- assertEquals(5, testBean.getAge());
- assertTrue(testBean.getMyFloat().floatValue() == 1.1f);
+ public DefaultListableBeanFactory getInstance() {
+ return new DefaultListableBeanFactory();
}
- @Test
- public void testRegisterExistingSingletonWithReference() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- Properties p = new Properties();
- p.setProperty("test.(class)", TestBean.class.getName());
- p.setProperty("test.name", "Tony");
- p.setProperty("test.age", "48");
- p.setProperty("test.spouse(ref)", "singletonObject");
- (new PropertiesBeanDefinitionReader(lbf)).registerBeanDefinitions(p);
- Object singletonObject = new TestBean();
- lbf.registerSingleton("singletonObject", singletonObject);
-
- assertTrue(lbf.isSingleton("singletonObject"));
- assertEquals(TestBean.class, lbf.getType("singletonObject"));
- TestBean test = (TestBean) lbf.getBean("test");
- assertEquals(singletonObject, lbf.getBean("singletonObject"));
- assertEquals(singletonObject, test.getSpouse());
-
- Map, ?> beansOfType = lbf.getBeansOfType(TestBean.class, false, true);
- assertEquals(2, beansOfType.size());
- assertTrue(beansOfType.containsValue(test));
- assertTrue(beansOfType.containsValue(singletonObject));
-
- beansOfType = lbf.getBeansOfType(null, false, true);
- assertEquals(2, beansOfType.size());
-
- Iterator beanNames = lbf.getBeanNamesIterator();
- assertEquals("test", beanNames.next());
- assertEquals("singletonObject", beanNames.next());
- assertFalse(beanNames.hasNext());
-
- assertTrue(lbf.containsSingleton("test"));
- assertTrue(lbf.containsSingleton("singletonObject"));
- assertTrue(lbf.containsBeanDefinition("test"));
- assertFalse(lbf.containsBeanDefinition("singletonObject"));
- }
-
- @Test
- public void testRegisterExistingSingletonWithNameOverriding() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- Properties p = new Properties();
- p.setProperty("test.(class)", TestBean.class.getName());
- p.setProperty("test.name", "Tony");
- p.setProperty("test.age", "48");
- p.setProperty("test.spouse(ref)", "singletonObject");
- (new PropertiesBeanDefinitionReader(lbf)).registerBeanDefinitions(p);
- lbf.registerBeanDefinition("singletonObject", new RootBeanDefinition(PropertiesFactoryBean.class));
- Object singletonObject = new TestBean();
- lbf.registerSingleton("singletonObject", singletonObject);
- lbf.preInstantiateSingletons();
-
- assertTrue(lbf.isSingleton("singletonObject"));
- assertEquals(TestBean.class, lbf.getType("singletonObject"));
- TestBean test = (TestBean) lbf.getBean("test");
- assertEquals(singletonObject, lbf.getBean("singletonObject"));
- assertEquals(singletonObject, test.getSpouse());
-
- Map, ?> beansOfType = lbf.getBeansOfType(TestBean.class, false, true);
- assertEquals(2, beansOfType.size());
- assertTrue(beansOfType.containsValue(test));
- assertTrue(beansOfType.containsValue(singletonObject));
-
- beansOfType = lbf.getBeansOfType(null, false, true);
-
- Iterator beanNames = lbf.getBeanNamesIterator();
- assertEquals("test", beanNames.next());
- assertEquals("singletonObject", beanNames.next());
- assertFalse(beanNames.hasNext());
- assertEquals(2, beansOfType.size());
-
- assertTrue(lbf.containsSingleton("test"));
- assertTrue(lbf.containsSingleton("singletonObject"));
- assertTrue(lbf.containsBeanDefinition("test"));
- assertTrue(lbf.containsBeanDefinition("singletonObject"));
- }
-
- @Test
- public void testRegisterExistingSingletonWithAutowire() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- MutablePropertyValues pvs = new MutablePropertyValues();
- pvs.add("name", "Tony");
- pvs.add("age", "48");
- RootBeanDefinition bd = new RootBeanDefinition(DependenciesBean.class);
- bd.setPropertyValues(pvs);
- bd.setDependencyCheck(RootBeanDefinition.DEPENDENCY_CHECK_OBJECTS);
- bd.setAutowireMode(RootBeanDefinition.AUTOWIRE_BY_TYPE);
- lbf.registerBeanDefinition("test", bd);
- Object singletonObject = new TestBean();
- lbf.registerSingleton("singletonObject", singletonObject);
-
- assertTrue(lbf.containsBean("singletonObject"));
- assertTrue(lbf.isSingleton("singletonObject"));
- assertEquals(TestBean.class, lbf.getType("singletonObject"));
- assertEquals(0, lbf.getAliases("singletonObject").length);
- DependenciesBean test = (DependenciesBean) lbf.getBean("test");
- assertEquals(singletonObject, lbf.getBean("singletonObject"));
- assertEquals(singletonObject, test.getSpouse());
- }
-
- @Test
- public void testRegisterExistingSingletonWithAlreadyBound() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- Object singletonObject = new TestBean();
- lbf.registerSingleton("singletonObject", singletonObject);
- try {
- lbf.registerSingleton("singletonObject", singletonObject);
- fail("Should have thrown IllegalStateException");
- }
- catch (IllegalStateException ex) {
- // expected
- }
- }
-
- @Test
- public void testReregisterBeanDefinition() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- RootBeanDefinition bd1 = new RootBeanDefinition(TestBean.class);
- bd1.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
- lbf.registerBeanDefinition("testBean", bd1);
- assertTrue(lbf.getBean("testBean") instanceof TestBean);
- RootBeanDefinition bd2 = new RootBeanDefinition(NestedTestBean.class);
- bd2.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
- lbf.registerBeanDefinition("testBean", bd2);
- assertTrue(lbf.getBean("testBean") instanceof NestedTestBean);
- }
-
- @Test
- public void testArrayPropertyWithAutowiring() throws MalformedURLException {
- DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
- bf.registerSingleton("resource1", new UrlResource("http://localhost:8080"));
- bf.registerSingleton("resource2", new UrlResource("http://localhost:9090"));
-
- RootBeanDefinition rbd = new RootBeanDefinition(ArrayBean.class);
- rbd.setAutowireMode(RootBeanDefinition.AUTOWIRE_BY_TYPE);
- bf.registerBeanDefinition("arrayBean", rbd);
- ArrayBean ab = (ArrayBean) bf.getBean("arrayBean");
-
- assertEquals(new UrlResource("http://localhost:8080"), ab.getResourceArray()[0]);
- assertEquals(new UrlResource("http://localhost:9090"), ab.getResourceArray()[1]);
- }
-
- @Test
- public void testArrayPropertyWithOptionalAutowiring() throws MalformedURLException {
- DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
-
- RootBeanDefinition rbd = new RootBeanDefinition(ArrayBean.class);
- rbd.setAutowireMode(RootBeanDefinition.AUTOWIRE_BY_TYPE);
- bf.registerBeanDefinition("arrayBean", rbd);
- ArrayBean ab = (ArrayBean) bf.getBean("arrayBean");
-
- assertNull(ab.getResourceArray());
- }
-
- @Test
- public void testArrayConstructorWithAutowiring() {
- DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
- bf.registerSingleton("integer1", new Integer(4));
- bf.registerSingleton("integer2", new Integer(5));
-
- RootBeanDefinition rbd = new RootBeanDefinition(ArrayBean.class);
- rbd.setAutowireMode(RootBeanDefinition.AUTOWIRE_CONSTRUCTOR);
- bf.registerBeanDefinition("arrayBean", rbd);
- ArrayBean ab = (ArrayBean) bf.getBean("arrayBean");
-
- assertEquals(new Integer(4), ab.getIntegerArray()[0]);
- assertEquals(new Integer(5), ab.getIntegerArray()[1]);
- }
-
- @Test
- public void testArrayConstructorWithOptionalAutowiring() {
- DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
-
- RootBeanDefinition rbd = new RootBeanDefinition(ArrayBean.class);
- rbd.setAutowireMode(RootBeanDefinition.AUTOWIRE_CONSTRUCTOR);
- bf.registerBeanDefinition("arrayBean", rbd);
- ArrayBean ab = (ArrayBean) bf.getBean("arrayBean");
-
- assertNull(ab.getIntegerArray());
- }
-
- @Test
- public void testDoubleArrayConstructorWithAutowiring() throws MalformedURLException {
- DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
- bf.registerSingleton("integer1", new Integer(4));
- bf.registerSingleton("integer2", new Integer(5));
- bf.registerSingleton("resource1", new UrlResource("http://localhost:8080"));
- bf.registerSingleton("resource2", new UrlResource("http://localhost:9090"));
-
- RootBeanDefinition rbd = new RootBeanDefinition(ArrayBean.class);
- rbd.setAutowireMode(RootBeanDefinition.AUTOWIRE_CONSTRUCTOR);
- bf.registerBeanDefinition("arrayBean", rbd);
- ArrayBean ab = (ArrayBean) bf.getBean("arrayBean");
-
- assertEquals(new Integer(4), ab.getIntegerArray()[0]);
- assertEquals(new Integer(5), ab.getIntegerArray()[1]);
- assertEquals(new UrlResource("http://localhost:8080"), ab.getResourceArray()[0]);
- assertEquals(new UrlResource("http://localhost:9090"), ab.getResourceArray()[1]);
- }
-
- @Test
- public void testDoubleArrayConstructorWithOptionalAutowiring() throws MalformedURLException {
- DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
- bf.registerSingleton("resource1", new UrlResource("http://localhost:8080"));
- bf.registerSingleton("resource2", new UrlResource("http://localhost:9090"));
-
- RootBeanDefinition rbd = new RootBeanDefinition(ArrayBean.class);
- rbd.setAutowireMode(RootBeanDefinition.AUTOWIRE_CONSTRUCTOR);
- bf.registerBeanDefinition("arrayBean", rbd);
- ArrayBean ab = (ArrayBean) bf.getBean("arrayBean");
-
- assertNull(ab.getIntegerArray());
- assertNull(ab.getResourceArray());
- }
-
- @Test
- public void testExpressionInStringArray() {
- DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
- BeanExpressionResolver beanExpressionResolver = mock(BeanExpressionResolver.class);
- when(beanExpressionResolver.evaluate(eq("#{foo}"), ArgumentMatchers.any(BeanExpressionContext.class)))
- .thenReturn("classpath:/org/springframework/beans/factory/xml/util.properties");
- bf.setBeanExpressionResolver(beanExpressionResolver);
-
- RootBeanDefinition rbd = new RootBeanDefinition(PropertiesFactoryBean.class);
- MutablePropertyValues pvs = new MutablePropertyValues();
- pvs.add("locations", new String[]{"#{foo}"});
- rbd.setPropertyValues(pvs);
- bf.registerBeanDefinition("myProperties", rbd);
- Properties properties = (Properties) bf.getBean("myProperties");
- assertEquals("bar", properties.getProperty("foo"));
- }
-
- @Test
- public void testAutowireWithNoDependencies() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- RootBeanDefinition bd = new RootBeanDefinition(TestBean.class);
- lbf.registerBeanDefinition("rod", bd);
- assertEquals(1, lbf.getBeanDefinitionCount());
- Object registered = lbf.autowire(NoDependencies.class, AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, false);
- assertEquals(1, lbf.getBeanDefinitionCount());
- assertTrue(registered instanceof NoDependencies);
- }
-
- @Test
- public void testAutowireWithSatisfiedJavaBeanDependency() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- MutablePropertyValues pvs = new MutablePropertyValues();
- pvs.add("name", "Rod");
- RootBeanDefinition bd = new RootBeanDefinition(TestBean.class);
- bd.setPropertyValues(pvs);
- lbf.registerBeanDefinition("rod", bd);
- assertEquals(1, lbf.getBeanDefinitionCount());
- // Depends on age, name and spouse (TestBean)
- Object registered = lbf.autowire(DependenciesBean.class, AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, true);
- assertEquals(1, lbf.getBeanDefinitionCount());
- DependenciesBean kerry = (DependenciesBean) registered;
- TestBean rod = (TestBean) lbf.getBean("rod");
- assertSame(rod, kerry.getSpouse());
- }
-
- @Test
- public void testAutowireWithSatisfiedConstructorDependency() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- MutablePropertyValues pvs = new MutablePropertyValues();
- pvs.add("name", "Rod");
- RootBeanDefinition bd = new RootBeanDefinition(TestBean.class);
- bd.setPropertyValues(pvs);
- lbf.registerBeanDefinition("rod", bd);
- assertEquals(1, lbf.getBeanDefinitionCount());
- Object registered = lbf.autowire(ConstructorDependency.class, AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR, false);
- assertEquals(1, lbf.getBeanDefinitionCount());
- ConstructorDependency kerry = (ConstructorDependency) registered;
- TestBean rod = (TestBean) lbf.getBean("rod");
- assertSame(rod, kerry.spouse);
- }
-
- @Test
- public void testAutowireWithTwoMatchesForConstructorDependency() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- RootBeanDefinition bd = new RootBeanDefinition(TestBean.class);
- lbf.registerBeanDefinition("rod", bd);
- RootBeanDefinition bd2 = new RootBeanDefinition(TestBean.class);
- lbf.registerBeanDefinition("rod2", bd2);
- try {
- lbf.autowire(ConstructorDependency.class, AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR, false);
- fail("Should have thrown UnsatisfiedDependencyException");
- }
- catch (UnsatisfiedDependencyException ex) {
- // expected
- assertTrue(ex.getMessage().contains("rod"));
- assertTrue(ex.getMessage().contains("rod2"));
- }
- }
-
- @Test
- public void testAutowireWithUnsatisfiedConstructorDependency() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- MutablePropertyValues pvs = new MutablePropertyValues();
- pvs.addPropertyValue(new PropertyValue("name", "Rod"));
- RootBeanDefinition bd = new RootBeanDefinition(TestBean.class);
- bd.setPropertyValues(pvs);
- lbf.registerBeanDefinition("rod", bd);
- assertEquals(1, lbf.getBeanDefinitionCount());
- try {
- lbf.autowire(UnsatisfiedConstructorDependency.class, AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR, true);
- fail("Should have unsatisfied constructor dependency on SideEffectBean");
- }
- catch (UnsatisfiedDependencyException ex) {
- // expected
- }
- }
-
- @Test
- public void testAutowireConstructor() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- RootBeanDefinition bd = new RootBeanDefinition(TestBean.class);
- lbf.registerBeanDefinition("spouse", bd);
- ConstructorDependenciesBean bean = (ConstructorDependenciesBean)
- lbf.autowire(ConstructorDependenciesBean.class, AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR, true);
- Object spouse = lbf.getBean("spouse");
- assertTrue(bean.getSpouse1() == spouse);
- assertTrue(BeanFactoryUtils.beanOfType(lbf, TestBean.class) == spouse);
- }
-
- @Test
- public void testAutowireBeanByName() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- RootBeanDefinition bd = new RootBeanDefinition(TestBean.class);
- lbf.registerBeanDefinition("spouse", bd);
- DependenciesBean bean = (DependenciesBean)
- lbf.autowire(DependenciesBean.class, AutowireCapableBeanFactory.AUTOWIRE_BY_NAME, true);
- TestBean spouse = (TestBean) lbf.getBean("spouse");
- assertEquals(spouse, bean.getSpouse());
- assertTrue(BeanFactoryUtils.beanOfType(lbf, TestBean.class) == spouse);
- }
-
- @Test
- public void testAutowireBeanByNameWithDependencyCheck() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- RootBeanDefinition bd = new RootBeanDefinition(TestBean.class);
- lbf.registerBeanDefinition("spous", bd);
- try {
- lbf.autowire(DependenciesBean.class, AutowireCapableBeanFactory.AUTOWIRE_BY_NAME, true);
- fail("Should have thrown UnsatisfiedDependencyException");
- }
- catch (UnsatisfiedDependencyException ex) {
- // expected
- }
- }
-
- @Test
- public void testAutowireBeanByNameWithNoDependencyCheck() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- RootBeanDefinition bd = new RootBeanDefinition(TestBean.class);
- lbf.registerBeanDefinition("spous", bd);
- DependenciesBean bean = (DependenciesBean)
- lbf.autowire(DependenciesBean.class, AutowireCapableBeanFactory.AUTOWIRE_BY_NAME, false);
- assertNull(bean.getSpouse());
- }
-
- @Test
- public void testDependsOnCycle() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- RootBeanDefinition bd1 = new RootBeanDefinition(TestBean.class);
- bd1.setDependsOn("tb2");
- lbf.registerBeanDefinition("tb1", bd1);
- RootBeanDefinition bd2 = new RootBeanDefinition(TestBean.class);
- bd2.setDependsOn("tb1");
- lbf.registerBeanDefinition("tb2", bd2);
- try {
- lbf.preInstantiateSingletons();
- fail("Should have thrown BeanCreationException");
- }
- catch (BeanCreationException ex) {
- // expected
- assertTrue(ex.getMessage().contains("Circular"));
- assertTrue(ex.getMessage().contains("'tb2'"));
- assertTrue(ex.getMessage().contains("'tb1'"));
- }
- }
-
- @Test
- public void testImplicitDependsOnCycle() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- RootBeanDefinition bd1 = new RootBeanDefinition(TestBean.class);
- bd1.setDependsOn("tb2");
- lbf.registerBeanDefinition("tb1", bd1);
- RootBeanDefinition bd2 = new RootBeanDefinition(TestBean.class);
- bd2.setDependsOn("tb3");
- lbf.registerBeanDefinition("tb2", bd2);
- RootBeanDefinition bd3 = new RootBeanDefinition(TestBean.class);
- bd3.setDependsOn("tb1");
- lbf.registerBeanDefinition("tb3", bd3);
- try {
- lbf.preInstantiateSingletons();
- fail("Should have thrown BeanCreationException");
- }
- catch (BeanCreationException ex) {
- // expected
- assertTrue(ex.getMessage().contains("Circular"));
- assertTrue(ex.getMessage().contains("'tb3'"));
- assertTrue(ex.getMessage().contains("'tb1'"));
- }
- }
-
- @Test(expected = NoSuchBeanDefinitionException.class)
- public void testGetBeanByTypeWithNoneFound() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- lbf.getBean(TestBean.class);
- }
-
- @Test
- public void testGetBeanByTypeDefinedInParent() {
- DefaultListableBeanFactory parent = new DefaultListableBeanFactory();
- RootBeanDefinition bd1 = new RootBeanDefinition(TestBean.class);
- parent.registerBeanDefinition("bd1", bd1);
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory(parent);
- TestBean bean = lbf.getBean(TestBean.class);
- assertThat(bean.getBeanName(), equalTo("bd1"));
- }
-
- @Test(expected = NoUniqueBeanDefinitionException.class)
- public void testGetBeanByTypeWithAmbiguity() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- RootBeanDefinition bd1 = new RootBeanDefinition(TestBean.class);
- RootBeanDefinition bd2 = new RootBeanDefinition(TestBean.class);
- lbf.registerBeanDefinition("bd1", bd1);
- lbf.registerBeanDefinition("bd2", bd2);
- lbf.getBean(TestBean.class);
- }
-
- @Test
- public void testGetBeanByTypeWithPrimary() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- RootBeanDefinition bd1 = new RootBeanDefinition(TestBean.class);
- bd1.setLazyInit(true);
- RootBeanDefinition bd2 = new RootBeanDefinition(TestBean.class);
- bd2.setPrimary(true);
- lbf.registerBeanDefinition("bd1", bd1);
- lbf.registerBeanDefinition("bd2", bd2);
- TestBean bean = lbf.getBean(TestBean.class);
- assertThat(bean.getBeanName(), equalTo("bd2"));
- assertFalse(lbf.containsSingleton("bd1"));
- }
-
- @Test
- public void testGetBeanByTypeWithMultiplePrimary() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- RootBeanDefinition bd1 = new RootBeanDefinition(TestBean.class);
- bd1.setPrimary(true);
- RootBeanDefinition bd2 = new RootBeanDefinition(TestBean.class);
- bd2.setPrimary(true);
- lbf.registerBeanDefinition("bd1", bd1);
- lbf.registerBeanDefinition("bd2", bd2);
- thrown.expect(NoUniqueBeanDefinitionException.class);
- thrown.expectMessage(containsString("more than one 'primary'"));
- lbf.getBean(TestBean.class);
- }
-
- @Test
- public void testGetBeanByTypeWithPriority() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- lbf.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
- RootBeanDefinition bd1 = new RootBeanDefinition(HighPriorityTestBean.class);
- RootBeanDefinition bd2 = new RootBeanDefinition(LowPriorityTestBean.class);
- RootBeanDefinition bd3 = new RootBeanDefinition(NullTestBeanFactoryBean.class);
- lbf.registerBeanDefinition("bd1", bd1);
- lbf.registerBeanDefinition("bd2", bd2);
- lbf.registerBeanDefinition("bd3", bd3);
- lbf.preInstantiateSingletons();
- TestBean bean = lbf.getBean(TestBean.class);
- assertThat(bean.getBeanName(), equalTo("bd1"));
- }
-
- @Test
- public void testMapInjectionWithPriority() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- lbf.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
- RootBeanDefinition bd1 = new RootBeanDefinition(HighPriorityTestBean.class);
- RootBeanDefinition bd2 = new RootBeanDefinition(LowPriorityTestBean.class);
- RootBeanDefinition bd3 = new RootBeanDefinition(NullTestBeanFactoryBean.class);
- RootBeanDefinition bd4 = new RootBeanDefinition(TestBeanRecipient.class, RootBeanDefinition.AUTOWIRE_CONSTRUCTOR, false);
- lbf.registerBeanDefinition("bd1", bd1);
- lbf.registerBeanDefinition("bd2", bd2);
- lbf.registerBeanDefinition("bd3", bd3);
- lbf.registerBeanDefinition("bd4", bd4);
- lbf.preInstantiateSingletons();
- TestBean bean = lbf.getBean(TestBeanRecipient.class).testBean;
- assertThat(bean.getBeanName(), equalTo("bd1"));
- }
-
- @Test
- public void testGetBeanByTypeWithMultiplePriority() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- lbf.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
- RootBeanDefinition bd1 = new RootBeanDefinition(HighPriorityTestBean.class);
- RootBeanDefinition bd2 = new RootBeanDefinition(HighPriorityTestBean.class);
- lbf.registerBeanDefinition("bd1", bd1);
- lbf.registerBeanDefinition("bd2", bd2);
- thrown.expect(NoUniqueBeanDefinitionException.class);
- thrown.expectMessage(containsString("Multiple beans found with the same priority"));
- thrown.expectMessage(containsString("5")); // conflicting priority
- lbf.getBean(TestBean.class);
- }
-
- @Test
- public void testGetBeanByTypeWithPriorityAndNullInstance() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- lbf.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
- RootBeanDefinition bd1 = new RootBeanDefinition(HighPriorityTestBean.class);
- RootBeanDefinition bd2 = new RootBeanDefinition(NullTestBeanFactoryBean.class);
- lbf.registerBeanDefinition("bd1", bd1);
- lbf.registerBeanDefinition("bd2", bd2);
- TestBean bean = lbf.getBean(TestBean.class);
- assertThat(bean.getBeanName(), equalTo("bd1"));
- }
-
- @Test
- public void testGetBeanByTypePrimaryHasPrecedenceOverPriority() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- lbf.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
- RootBeanDefinition bd1 = new RootBeanDefinition(HighPriorityTestBean.class);
- RootBeanDefinition bd2 = new RootBeanDefinition(TestBean.class);
- bd2.setPrimary(true);
- lbf.registerBeanDefinition("bd1", bd1);
- lbf.registerBeanDefinition("bd2", bd2);
- TestBean bean = lbf.getBean(TestBean.class);
- assertThat(bean.getBeanName(), equalTo("bd2"));
- }
-
- @Test
- public void testGetBeanByTypeFiltersOutNonAutowireCandidates() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- RootBeanDefinition bd1 = new RootBeanDefinition(TestBean.class);
- RootBeanDefinition bd2 = new RootBeanDefinition(TestBean.class);
- RootBeanDefinition na1 = new RootBeanDefinition(TestBean.class);
- na1.setAutowireCandidate(false);
-
- lbf.registerBeanDefinition("bd1", bd1);
- lbf.registerBeanDefinition("na1", na1);
- TestBean actual = lbf.getBean(TestBean.class); // na1 was filtered
- assertSame(lbf.getBean("bd1", TestBean.class), actual);
-
- lbf.registerBeanDefinition("bd2", bd2);
- try {
- lbf.getBean(TestBean.class);
- fail("Should have thrown NoSuchBeanDefinitionException");
- }
- catch (NoSuchBeanDefinitionException ex) {
- // expected
- }
- }
-
- @Test
- public void testGetBeanByTypeInstanceWithNoneFound() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
-
- try {
- lbf.getBean(ConstructorDependency.class);
- fail("Should have thrown NoSuchBeanDefinitionException");
- }
- catch (NoSuchBeanDefinitionException ex) {
- // expected
- }
- try {
- lbf.getBean(ConstructorDependency.class, 42);
- fail("Should have thrown NoSuchBeanDefinitionException");
- }
- catch (NoSuchBeanDefinitionException ex) {
- // expected
- }
-
- ObjectProvider provider = lbf.getBeanProvider(ConstructorDependency.class);
- try {
- provider.getObject();
- fail("Should have thrown NoSuchBeanDefinitionException");
- }
- catch (NoSuchBeanDefinitionException ex) {
- // expected
- }
- try {
- provider.getObject(42);
- fail("Should have thrown NoSuchBeanDefinitionException");
- }
- catch (NoSuchBeanDefinitionException ex) {
- // expected
- }
- assertNull(provider.getIfAvailable());
- assertNull(provider.getIfUnique());
- }
-
- @Test
- public void testGetBeanByTypeInstanceDefinedInParent() {
- DefaultListableBeanFactory parent = new DefaultListableBeanFactory();
- RootBeanDefinition bd1 = createConstructorDependencyBeanDefinition(99);
- parent.registerBeanDefinition("bd1", bd1);
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory(parent);
-
- ConstructorDependency bean = lbf.getBean(ConstructorDependency.class);
- assertThat(bean.beanName, equalTo("bd1"));
- assertThat(bean.spouseAge, equalTo(99));
- bean = lbf.getBean(ConstructorDependency.class, 42);
- assertThat(bean.beanName, equalTo("bd1"));
- assertThat(bean.spouseAge, equalTo(42));
-
- ObjectProvider provider = lbf.getBeanProvider(ConstructorDependency.class);
- bean = provider.getObject();
- assertThat(bean.beanName, equalTo("bd1"));
- assertThat(bean.spouseAge, equalTo(99));
- bean = provider.getObject(42);
- assertThat(bean.beanName, equalTo("bd1"));
- assertThat(bean.spouseAge, equalTo(42));
- bean = provider.getIfAvailable();
- assertThat(bean.beanName, equalTo("bd1"));
- assertThat(bean.spouseAge, equalTo(99));
- bean = provider.getIfUnique();
- assertThat(bean.beanName, equalTo("bd1"));
- assertThat(bean.spouseAge, equalTo(99));
- }
-
- @Test
- public void testGetBeanByTypeInstanceWithAmbiguity() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- RootBeanDefinition bd1 = createConstructorDependencyBeanDefinition(99);
- RootBeanDefinition bd2 = new RootBeanDefinition(ConstructorDependency.class);
- bd2.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
- bd2.getConstructorArgumentValues().addGenericArgumentValue("43");
- lbf.registerBeanDefinition("bd1", bd1);
- lbf.registerBeanDefinition("bd2", bd2);
-
- try {
- lbf.getBean(ConstructorDependency.class);
- fail("Should have thrown NoUniqueBeanDefinitionException");
- }
- catch (NoUniqueBeanDefinitionException ex) {
- // expected
- }
- try {
- lbf.getBean(ConstructorDependency.class, 42);
- fail("Should have thrown NoUniqueBeanDefinitionException");
- }
- catch (NoUniqueBeanDefinitionException ex) {
- // expected
- }
-
- ObjectProvider provider = lbf.getBeanProvider(ConstructorDependency.class);
- try {
- provider.getObject();
- fail("Should have thrown NoUniqueBeanDefinitionException");
- }
- catch (NoUniqueBeanDefinitionException ex) {
- // expected
- }
- try {
- provider.getObject(42);
- fail("Should have thrown NoUniqueBeanDefinitionException");
- }
- catch (NoUniqueBeanDefinitionException ex) {
- // expected
- }
- try {
- provider.getIfAvailable();
- fail("Should have thrown NoUniqueBeanDefinitionException");
- }
- catch (NoUniqueBeanDefinitionException ex) {
- // expected
- }
- assertNull(provider.getIfUnique());
-
- Set resolved = new HashSet<>();
- for (ConstructorDependency instance : provider) {
- resolved.add(instance);
- }
- assertEquals(2, resolved.size());
- assertTrue(resolved.contains(lbf.getBean("bd1")));
- assertTrue(resolved.contains(lbf.getBean("bd2")));
-
- resolved = new HashSet<>();
- provider.forEach(resolved::add);
- assertEquals(2, resolved.size());
- assertTrue(resolved.contains(lbf.getBean("bd1")));
- assertTrue(resolved.contains(lbf.getBean("bd2")));
-
- resolved = provider.stream().collect(Collectors.toSet());
- assertEquals(2, resolved.size());
- assertTrue(resolved.contains(lbf.getBean("bd1")));
- assertTrue(resolved.contains(lbf.getBean("bd2")));
- }
-
- @Test
- public void testGetBeanByTypeInstanceWithPrimary() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- RootBeanDefinition bd1 = createConstructorDependencyBeanDefinition(99);
- RootBeanDefinition bd2 = createConstructorDependencyBeanDefinition(43);
- bd2.setPrimary(true);
- lbf.registerBeanDefinition("bd1", bd1);
- lbf.registerBeanDefinition("bd2", bd2);
-
- ConstructorDependency bean = lbf.getBean(ConstructorDependency.class);
- assertThat(bean.beanName, equalTo("bd2"));
- assertThat(bean.spouseAge, equalTo(43));
- bean = lbf.getBean(ConstructorDependency.class, 42);
- assertThat(bean.beanName, equalTo("bd2"));
- assertThat(bean.spouseAge, equalTo(42));
-
- ObjectProvider provider = lbf.getBeanProvider(ConstructorDependency.class);
- bean = provider.getObject();
- assertThat(bean.beanName, equalTo("bd2"));
- assertThat(bean.spouseAge, equalTo(43));
- bean = provider.getObject(42);
- assertThat(bean.beanName, equalTo("bd2"));
- assertThat(bean.spouseAge, equalTo(42));
- bean = provider.getIfAvailable();
- assertThat(bean.beanName, equalTo("bd2"));
- assertThat(bean.spouseAge, equalTo(43));
- bean = provider.getIfUnique();
- assertThat(bean.beanName, equalTo("bd2"));
- assertThat(bean.spouseAge, equalTo(43));
-
- Set resolved = new HashSet<>();
- for (ConstructorDependency instance : provider) {
- resolved.add(instance);
- }
- assertEquals(2, resolved.size());
- assertTrue(resolved.contains(lbf.getBean("bd1")));
- assertTrue(resolved.contains(lbf.getBean("bd2")));
-
- resolved = new HashSet<>();
- provider.forEach(resolved::add);
- assertEquals(2, resolved.size());
- assertTrue(resolved.contains(lbf.getBean("bd1")));
- assertTrue(resolved.contains(lbf.getBean("bd2")));
-
- resolved = provider.stream().collect(Collectors.toSet());
- assertEquals(2, resolved.size());
- assertTrue(resolved.contains(lbf.getBean("bd1")));
- assertTrue(resolved.contains(lbf.getBean("bd2")));
- }
-
- @Test
- public void testGetBeanByTypeInstanceWithMultiplePrimary() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- RootBeanDefinition bd1 = createConstructorDependencyBeanDefinition(99);
- RootBeanDefinition bd2 = createConstructorDependencyBeanDefinition(43);
- bd1.setPrimary(true);
- bd2.setPrimary(true);
- lbf.registerBeanDefinition("bd1", bd1);
- lbf.registerBeanDefinition("bd2", bd2);
-
- thrown.expect(NoUniqueBeanDefinitionException.class);
- thrown.expectMessage(containsString("more than one 'primary'"));
- lbf.getBean(ConstructorDependency.class, 42);
- }
-
- @Test
- public void testGetBeanByTypeInstanceFiltersOutNonAutowireCandidates() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- RootBeanDefinition bd1 = createConstructorDependencyBeanDefinition(99);
- RootBeanDefinition bd2 = createConstructorDependencyBeanDefinition(43);
- RootBeanDefinition na1 = createConstructorDependencyBeanDefinition(21);
- na1.setAutowireCandidate(false);
-
- lbf.registerBeanDefinition("bd1", bd1);
- lbf.registerBeanDefinition("na1", na1);
- ConstructorDependency actual = lbf.getBean(ConstructorDependency.class, 42); // na1 was filtered
- assertThat(actual.beanName, equalTo("bd1"));
-
- lbf.registerBeanDefinition("bd2", bd2);
- try {
- lbf.getBean(TestBean.class, 67);
- fail("Should have thrown NoSuchBeanDefinitionException");
- }
- catch (NoSuchBeanDefinitionException ex) {
- // expected
- }
- }
-
- @Test
- public void testBeanProviderSerialization() throws Exception {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- lbf.setSerializationId("test");
-
- ObjectProvider provider = lbf.getBeanProvider(ConstructorDependency.class);
- ObjectProvider deserialized = (ObjectProvider) SerializationTestUtils.serializeAndDeserialize(provider);
- try {
- deserialized.getObject();
- fail("Should have thrown NoSuchBeanDefinitionException");
- }
- catch (NoSuchBeanDefinitionException ex) {
- // expected
- }
- try {
- deserialized.getObject(42);
- fail("Should have thrown NoSuchBeanDefinitionException");
- }
- catch (NoSuchBeanDefinitionException ex) {
- // expected
- }
- assertNull(deserialized.getIfAvailable());
- assertNull(deserialized.getIfUnique());
- }
-
- @Test
- public void testGetBeanWithArgsNotCreatedForFactoryBeanChecking() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- RootBeanDefinition bd1 = new RootBeanDefinition(ConstructorDependency.class);
- bd1.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
- lbf.registerBeanDefinition("bd1", bd1);
- RootBeanDefinition bd2 = new RootBeanDefinition(ConstructorDependencyFactoryBean.class);
- bd2.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
- lbf.registerBeanDefinition("bd2", bd2);
-
- ConstructorDependency bean = lbf.getBean(ConstructorDependency.class, 42);
- assertThat(bean.beanName, equalTo("bd1"));
- assertThat(bean.spouseAge, equalTo(42));
-
- assertEquals(1, lbf.getBeanNamesForType(ConstructorDependency.class).length);
- assertEquals(1, lbf.getBeanNamesForType(ConstructorDependencyFactoryBean.class).length);
- assertEquals(1, lbf.getBeanNamesForType(ResolvableType.forClassWithGenerics(FactoryBean.class, Object.class)).length);
- assertEquals(0, lbf.getBeanNamesForType(ResolvableType.forClassWithGenerics(FactoryBean.class, String.class)).length);
+ public DefaultListableBeanFactory getInstance(@Nullable BeanFactory parentBeanFactory) {
+ return new DefaultListableBeanFactory(parentBeanFactory);
}
-
- private RootBeanDefinition createConstructorDependencyBeanDefinition(int age) {
- RootBeanDefinition bd = new RootBeanDefinition(ConstructorDependency.class);
- bd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
- bd.getConstructorArgumentValues().addGenericArgumentValue(age);
- return bd;
- }
-
- @Test
- public void testAutowireBeanByType() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- RootBeanDefinition bd = new RootBeanDefinition(TestBean.class);
- lbf.registerBeanDefinition("test", bd);
- DependenciesBean bean = (DependenciesBean)
- lbf.autowire(DependenciesBean.class, AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, true);
- TestBean test = (TestBean) lbf.getBean("test");
- assertEquals(test, bean.getSpouse());
- }
-
- /**
- * Verifies that a dependency on a {@link FactoryBean} can be autowired
- * by type , specifically addressing the JIRA issue raised in SPR-4040 .
- */
- @Test
- public void testAutowireBeanWithFactoryBeanByType() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- RootBeanDefinition bd = new RootBeanDefinition(LazyInitFactory.class);
- lbf.registerBeanDefinition("factoryBean", bd);
- LazyInitFactory factoryBean = (LazyInitFactory) lbf.getBean("&factoryBean");
- assertNotNull("The FactoryBean should have been registered.", factoryBean);
- FactoryBeanDependentBean bean = (FactoryBeanDependentBean) lbf.autowire(FactoryBeanDependentBean.class,
- AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, true);
- assertEquals("The FactoryBeanDependentBean should have been autowired 'by type' with the LazyInitFactory.",
- factoryBean, bean.getFactoryBean());
- }
-
- @Test
- public void testGetTypeForAbstractFactoryBean() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- RootBeanDefinition bd = new RootBeanDefinition(FactoryBeanThatShouldntBeCalled.class);
- bd.setAbstract(true);
- lbf.registerBeanDefinition("factoryBean", bd);
- assertNull(lbf.getType("factoryBean"));
- }
-
- @Test
- public void testGetBeanNamesForTypeBeforeFactoryBeanCreation() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- lbf.registerBeanDefinition("factoryBean", new RootBeanDefinition(FactoryBeanThatShouldntBeCalled.class));
- assertFalse(lbf.containsSingleton("factoryBean"));
-
- String[] beanNames = lbf.getBeanNamesForType(Runnable.class, false, false);
- assertEquals(1, beanNames.length);
- assertEquals("&factoryBean", beanNames[0]);
-
- beanNames = lbf.getBeanNamesForType(Callable.class, false, false);
- assertEquals(1, beanNames.length);
- assertEquals("&factoryBean", beanNames[0]);
-
- beanNames = lbf.getBeanNamesForType(RepositoryFactoryInformation.class, false, false);
- assertEquals(1, beanNames.length);
- assertEquals("&factoryBean", beanNames[0]);
-
- beanNames = lbf.getBeanNamesForType(FactoryBean.class, false, false);
- assertEquals(1, beanNames.length);
- assertEquals("&factoryBean", beanNames[0]);
- }
-
- @Test
- public void testGetBeanNamesForTypeAfterFactoryBeanCreation() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- lbf.registerBeanDefinition("factoryBean", new RootBeanDefinition(FactoryBeanThatShouldntBeCalled.class));
- lbf.getBean("&factoryBean");
-
- String[] beanNames = lbf.getBeanNamesForType(Runnable.class, false, false);
- assertEquals(1, beanNames.length);
- assertEquals("&factoryBean", beanNames[0]);
-
- beanNames = lbf.getBeanNamesForType(Callable.class, false, false);
- assertEquals(1, beanNames.length);
- assertEquals("&factoryBean", beanNames[0]);
-
- beanNames = lbf.getBeanNamesForType(RepositoryFactoryInformation.class, false, false);
- assertEquals(1, beanNames.length);
- assertEquals("&factoryBean", beanNames[0]);
-
- beanNames = lbf.getBeanNamesForType(FactoryBean.class, false, false);
- assertEquals(1, beanNames.length);
- assertEquals("&factoryBean", beanNames[0]);
- }
-
- /**
- * Verifies that a dependency on a {@link FactoryBean} can not
- * be autowired by name , as & is an illegal character in
- * Java method names. In other words, you can't name a method
- * {@code set&FactoryBean(...)}.
- */
- @Test(expected = TypeMismatchException.class)
- public void testAutowireBeanWithFactoryBeanByName() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- RootBeanDefinition bd = new RootBeanDefinition(LazyInitFactory.class);
- lbf.registerBeanDefinition("factoryBean", bd);
- LazyInitFactory factoryBean = (LazyInitFactory) lbf.getBean("&factoryBean");
- assertNotNull("The FactoryBean should have been registered.", factoryBean);
- lbf.autowire(FactoryBeanDependentBean.class, AutowireCapableBeanFactory.AUTOWIRE_BY_NAME, true);
- }
-
- @Test
- public void testAutowireBeanByTypeWithTwoMatches() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- RootBeanDefinition bd = new RootBeanDefinition(TestBean.class);
- RootBeanDefinition bd2 = new RootBeanDefinition(TestBean.class);
- lbf.registerBeanDefinition("test", bd);
- lbf.registerBeanDefinition("spouse", bd2);
- try {
- lbf.autowire(DependenciesBean.class, AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, true);
- fail("Should have thrown UnsatisfiedDependencyException");
- }
- catch (UnsatisfiedDependencyException ex) {
- // expected
- assertTrue(ex.getMessage().contains("test"));
- assertTrue(ex.getMessage().contains("spouse"));
- }
- }
-
- @Test
- public void testAutowireBeanByTypeWithDependencyCheck() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- try {
- lbf.autowire(DependenciesBean.class, AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, true);
- fail("Should have thrown UnsatisfiedDependencyException");
- }
- catch (UnsatisfiedDependencyException ex) {
- // expected
- }
- }
-
- @Test
- public void testAutowireBeanByTypeWithNoDependencyCheck() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- DependenciesBean bean = (DependenciesBean)
- lbf.autowire(DependenciesBean.class, AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, false);
- assertNull(bean.getSpouse());
- }
-
- @Test
- public void testAutowireBeanByTypeWithTwoMatchesAndOnePrimary() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- RootBeanDefinition bd = new RootBeanDefinition(TestBean.class);
- bd.setPrimary(true);
- RootBeanDefinition bd2 = new RootBeanDefinition(TestBean.class);
- lbf.registerBeanDefinition("test", bd);
- lbf.registerBeanDefinition("spouse", bd2);
-
- DependenciesBean bean = (DependenciesBean)
- lbf.autowire(DependenciesBean.class, AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, true);
- assertThat(bean.getSpouse(), equalTo(lbf.getBean("test")));
- }
-
- @Test
- public void testAutowireBeanByTypeWithTwoPrimaryCandidates() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- RootBeanDefinition bd = new RootBeanDefinition(TestBean.class);
- bd.setPrimary(true);
- RootBeanDefinition bd2 = new RootBeanDefinition(TestBean.class);
- bd2.setPrimary(true);
- lbf.registerBeanDefinition("test", bd);
- lbf.registerBeanDefinition("spouse", bd2);
-
- try {
- lbf.autowire(DependenciesBean.class, AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, true);
- fail("Should have thrown UnsatisfiedDependencyException");
- }
- catch (UnsatisfiedDependencyException ex) {
- // expected
- assertNotNull("Exception should have cause", ex.getCause());
- assertEquals("Wrong cause type", NoUniqueBeanDefinitionException.class, ex.getCause().getClass());
- }
- }
-
- @Test
- public void testAutowireBeanByTypeWithTwoMatchesAndPriority() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- lbf.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
- RootBeanDefinition bd = new RootBeanDefinition(HighPriorityTestBean.class);
- RootBeanDefinition bd2 = new RootBeanDefinition(LowPriorityTestBean.class);
- lbf.registerBeanDefinition("test", bd);
- lbf.registerBeanDefinition("spouse", bd2);
-
- DependenciesBean bean = (DependenciesBean)
- lbf.autowire(DependenciesBean.class, AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, true);
- assertThat(bean.getSpouse(), equalTo(lbf.getBean("test")));
- }
-
- @Test
- public void testAutowireBeanByTypeWithIdenticalPriorityCandidates() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- lbf.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
- RootBeanDefinition bd = new RootBeanDefinition(HighPriorityTestBean.class);
- RootBeanDefinition bd2 = new RootBeanDefinition(HighPriorityTestBean.class);
- lbf.registerBeanDefinition("test", bd);
- lbf.registerBeanDefinition("spouse", bd2);
-
- try {
- lbf.autowire(DependenciesBean.class, AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, true);
- fail("Should have thrown UnsatisfiedDependencyException");
- }
- catch (UnsatisfiedDependencyException ex) {
- // expected
- assertNotNull("Exception should have cause", ex.getCause());
- assertEquals("Wrong cause type", NoUniqueBeanDefinitionException.class, ex.getCause().getClass());
- assertTrue(ex.getMessage().contains("5")); // conflicting priority
- }
- }
-
- @Test
- public void testAutowireBeanByTypePrimaryTakesPrecedenceOverPriority() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- lbf.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
- RootBeanDefinition bd = new RootBeanDefinition(HighPriorityTestBean.class);
- RootBeanDefinition bd2 = new RootBeanDefinition(TestBean.class);
- bd2.setPrimary(true);
- lbf.registerBeanDefinition("test", bd);
- lbf.registerBeanDefinition("spouse", bd2);
-
- DependenciesBean bean = (DependenciesBean)
- lbf.autowire(DependenciesBean.class, AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, true);
- assertThat(bean.getSpouse(), equalTo(lbf.getBean("spouse")));
- }
-
- @Test
- public void testAutowireExistingBeanByName() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- RootBeanDefinition bd = new RootBeanDefinition(TestBean.class);
- lbf.registerBeanDefinition("spouse", bd);
- DependenciesBean existingBean = new DependenciesBean();
- lbf.autowireBeanProperties(existingBean, AutowireCapableBeanFactory.AUTOWIRE_BY_NAME, true);
- TestBean spouse = (TestBean) lbf.getBean("spouse");
- assertEquals(existingBean.getSpouse(), spouse);
- assertSame(spouse, BeanFactoryUtils.beanOfType(lbf, TestBean.class));
- }
-
- @Test
- public void testAutowireExistingBeanByNameWithDependencyCheck() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- RootBeanDefinition bd = new RootBeanDefinition(TestBean.class);
- lbf.registerBeanDefinition("spous", bd);
- DependenciesBean existingBean = new DependenciesBean();
- try {
- lbf.autowireBeanProperties(existingBean, AutowireCapableBeanFactory.AUTOWIRE_BY_NAME, true);
- fail("Should have thrown UnsatisfiedDependencyException");
- }
- catch (UnsatisfiedDependencyException ex) {
- // expected
- }
- }
-
- @Test
- public void testAutowireExistingBeanByNameWithNoDependencyCheck() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- RootBeanDefinition bd = new RootBeanDefinition(TestBean.class);
- lbf.registerBeanDefinition("spous", bd);
- DependenciesBean existingBean = new DependenciesBean();
- lbf.autowireBeanProperties(existingBean, AutowireCapableBeanFactory.AUTOWIRE_BY_NAME, false);
- assertNull(existingBean.getSpouse());
- }
-
- @Test
- public void testAutowireExistingBeanByType() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- RootBeanDefinition bd = new RootBeanDefinition(TestBean.class);
- lbf.registerBeanDefinition("test", bd);
- DependenciesBean existingBean = new DependenciesBean();
- lbf.autowireBeanProperties(existingBean, AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, true);
- TestBean test = (TestBean) lbf.getBean("test");
- assertEquals(existingBean.getSpouse(), test);
- }
-
- @Test
- public void testAutowireExistingBeanByTypeWithDependencyCheck() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- DependenciesBean existingBean = new DependenciesBean();
- try {
- lbf.autowireBeanProperties(existingBean, AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, true);
- fail("Should have thrown UnsatisfiedDependencyException");
- }
- catch (UnsatisfiedDependencyException expected) {
- }
- }
-
- @Test
- public void testAutowireExistingBeanByTypeWithNoDependencyCheck() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- DependenciesBean existingBean = new DependenciesBean();
- lbf.autowireBeanProperties(existingBean, AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, false);
- assertNull(existingBean.getSpouse());
- }
-
- @Test
- public void testInvalidAutowireMode() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- try {
- lbf.autowireBeanProperties(new TestBean(), AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR, false);
- fail("Should have thrown IllegalArgumentException");
- }
- catch (IllegalArgumentException expected) {
- }
- }
-
- @Test
- public void testApplyBeanPropertyValues() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- MutablePropertyValues pvs = new MutablePropertyValues();
- pvs.add("age", "99");
- RootBeanDefinition bd = new RootBeanDefinition(TestBean.class);
- bd.setPropertyValues(pvs);
- lbf.registerBeanDefinition("test", bd);
- TestBean tb = new TestBean();
- assertEquals(0, tb.getAge());
- lbf.applyBeanPropertyValues(tb, "test");
- assertEquals(99, tb.getAge());
- }
-
- @Test
- public void testApplyBeanPropertyValuesWithIncompleteDefinition() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- MutablePropertyValues pvs = new MutablePropertyValues();
- pvs.add("age", "99");
- RootBeanDefinition bd = new RootBeanDefinition();
- bd.setPropertyValues(pvs);
- lbf.registerBeanDefinition("test", bd);
- TestBean tb = new TestBean();
- assertEquals(0, tb.getAge());
- lbf.applyBeanPropertyValues(tb, "test");
- assertEquals(99, tb.getAge());
- assertNull(tb.getBeanFactory());
- assertNull(tb.getSpouse());
- }
-
- @Test
- public void testCreateBean() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- TestBean tb = lbf.createBean(TestBean.class);
- assertSame(lbf, tb.getBeanFactory());
- lbf.destroyBean(tb);
- }
-
- @Test
- public void testCreateBeanWithDisposableBean() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- DerivedTestBean tb = lbf.createBean(DerivedTestBean.class);
- assertSame(lbf, tb.getBeanFactory());
- lbf.destroyBean(tb);
- assertTrue(tb.wasDestroyed());
- }
-
- @Test
- public void testConfigureBean() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- MutablePropertyValues pvs = new MutablePropertyValues();
- pvs.add("age", "99");
- RootBeanDefinition bd = new RootBeanDefinition(TestBean.class);
- bd.setPropertyValues(pvs);
- lbf.registerBeanDefinition("test", bd);
- TestBean tb = new TestBean();
- assertEquals(0, tb.getAge());
- lbf.configureBean(tb, "test");
- assertEquals(99, tb.getAge());
- assertSame(lbf, tb.getBeanFactory());
- assertNull(tb.getSpouse());
- }
-
- @Test
- public void testConfigureBeanWithAutowiring() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- RootBeanDefinition bd = new RootBeanDefinition(TestBean.class);
- lbf.registerBeanDefinition("spouse", bd);
- MutablePropertyValues pvs = new MutablePropertyValues();
- pvs.add("age", "99");
- RootBeanDefinition tbd = new RootBeanDefinition(TestBean.class);
- tbd.setAutowireMode(RootBeanDefinition.AUTOWIRE_BY_NAME);
- lbf.registerBeanDefinition("test", tbd);
- TestBean tb = new TestBean();
- lbf.configureBean(tb, "test");
- assertSame(lbf, tb.getBeanFactory());
- TestBean spouse = (TestBean) lbf.getBean("spouse");
- assertEquals(spouse, tb.getSpouse());
- }
-
- @Test
- public void testExtensiveCircularReference() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- for (int i = 0; i < 1000; i++) {
- MutablePropertyValues pvs = new MutablePropertyValues();
- pvs.addPropertyValue(new PropertyValue("spouse", new RuntimeBeanReference("bean" + (i < 99 ? i + 1 : 0))));
- RootBeanDefinition bd = new RootBeanDefinition(TestBean.class);
- bd.setPropertyValues(pvs);
- lbf.registerBeanDefinition("bean" + i, bd);
- }
- lbf.preInstantiateSingletons();
- for (int i = 0; i < 1000; i++) {
- TestBean bean = (TestBean) lbf.getBean("bean" + i);
- TestBean otherBean = (TestBean) lbf.getBean("bean" + (i < 99 ? i + 1 : 0));
- assertTrue(bean.getSpouse() == otherBean);
- }
- }
-
- @Test
- public void testCircularReferenceThroughAutowiring() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- RootBeanDefinition bd = new RootBeanDefinition(ConstructorDependencyBean.class);
- bd.setAutowireMode(RootBeanDefinition.AUTOWIRE_CONSTRUCTOR);
- lbf.registerBeanDefinition("test", bd);
- try {
- lbf.preInstantiateSingletons();
- fail("Should have thrown UnsatisfiedDependencyException");
- }
- catch (UnsatisfiedDependencyException expected) {
- }
- }
-
- @Test
- public void testCircularReferenceThroughFactoryBeanAutowiring() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- RootBeanDefinition bd = new RootBeanDefinition(ConstructorDependencyFactoryBean.class);
- bd.setAutowireMode(RootBeanDefinition.AUTOWIRE_CONSTRUCTOR);
- lbf.registerBeanDefinition("test", bd);
- try {
- lbf.preInstantiateSingletons();
- fail("Should have thrown UnsatisfiedDependencyException");
- }
- catch (UnsatisfiedDependencyException expected) {
- }
- }
-
- @Test
- public void testCircularReferenceThroughFactoryBeanTypeCheck() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- RootBeanDefinition bd = new RootBeanDefinition(ConstructorDependencyFactoryBean.class);
- bd.setAutowireMode(RootBeanDefinition.AUTOWIRE_CONSTRUCTOR);
- lbf.registerBeanDefinition("test", bd);
- try {
- lbf.getBeansOfType(String.class);
- fail("Should have thrown UnsatisfiedDependencyException");
- }
- catch (UnsatisfiedDependencyException expected) {
- }
- }
-
- @Test
- public void testAvoidCircularReferenceThroughAutowiring() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- RootBeanDefinition bd = new RootBeanDefinition(ConstructorDependencyFactoryBean.class);
- bd.setAutowireMode(RootBeanDefinition.AUTOWIRE_CONSTRUCTOR);
- lbf.registerBeanDefinition("test", bd);
- RootBeanDefinition bd2 = new RootBeanDefinition(String.class);
- bd2.setAutowireMode(RootBeanDefinition.AUTOWIRE_CONSTRUCTOR);
- lbf.registerBeanDefinition("string", bd2);
- lbf.preInstantiateSingletons();
- }
-
- @Test
- public void testConstructorDependencyWithClassResolution() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- RootBeanDefinition bd = new RootBeanDefinition(ConstructorDependencyWithClassResolution.class);
- bd.getConstructorArgumentValues().addGenericArgumentValue("java.lang.String");
- lbf.registerBeanDefinition("test", bd);
- lbf.preInstantiateSingletons();
- }
-
- @Test
- public void testConstructorDependencyWithUnresolvableClass() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- RootBeanDefinition bd = new RootBeanDefinition(ConstructorDependencyWithClassResolution.class);
- bd.getConstructorArgumentValues().addGenericArgumentValue("java.lang.Strin");
- lbf.registerBeanDefinition("test", bd);
- try {
- lbf.preInstantiateSingletons();
- fail("Should have thrown UnsatisfiedDependencyException");
- }
- catch (UnsatisfiedDependencyException expected) {
- assertTrue(expected.toString().contains("java.lang.Strin"));
- }
- }
-
- @Test
- public void testBeanDefinitionWithInterface() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- lbf.registerBeanDefinition("test", new RootBeanDefinition(ITestBean.class));
- try {
- lbf.getBean("test");
- fail("Should have thrown BeanCreationException");
- }
- catch (BeanCreationException ex) {
- assertEquals("test", ex.getBeanName());
- assertTrue(ex.getMessage().toLowerCase().contains("interface"));
- }
- }
-
- @Test
- public void testBeanDefinitionWithAbstractClass() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- lbf.registerBeanDefinition("test", new RootBeanDefinition(AbstractBeanFactory.class));
- try {
- lbf.getBean("test");
- fail("Should have thrown BeanCreationException");
- }
- catch (BeanCreationException ex) {
- assertEquals("test", ex.getBeanName());
- assertTrue(ex.getMessage().toLowerCase().contains("abstract"));
- }
- }
-
- @Test
- public void testPrototypeFactoryBeanNotEagerlyCalled() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- lbf.registerBeanDefinition("test", new RootBeanDefinition(FactoryBeanThatShouldntBeCalled.class));
- lbf.preInstantiateSingletons();
- }
-
- @Test
- public void testLazyInitFactory() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- lbf.registerBeanDefinition("test", new RootBeanDefinition(LazyInitFactory.class));
- lbf.preInstantiateSingletons();
- LazyInitFactory factory = (LazyInitFactory) lbf.getBean("&test");
- assertFalse(factory.initialized);
- }
-
- @Test
- public void testSmartInitFactory() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- lbf.registerBeanDefinition("test", new RootBeanDefinition(EagerInitFactory.class));
- lbf.preInstantiateSingletons();
- EagerInitFactory factory = (EagerInitFactory) lbf.getBean("&test");
- assertTrue(factory.initialized);
- }
-
- @Test
- public void testPrototypeFactoryBeanNotEagerlyCalledInCaseOfBeanClassName() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- lbf.registerBeanDefinition("test",
- new RootBeanDefinition(FactoryBeanThatShouldntBeCalled.class.getName(), null, null));
- lbf.preInstantiateSingletons();
- }
-
- @Test
- public void testPrototypeStringCreatedRepeatedly() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- RootBeanDefinition stringDef = new RootBeanDefinition(String.class);
- stringDef.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
- stringDef.getConstructorArgumentValues().addGenericArgumentValue(new TypedStringValue("value"));
- lbf.registerBeanDefinition("string", stringDef);
- String val1 = lbf.getBean("string", String.class);
- String val2 = lbf.getBean("string", String.class);
- assertEquals("value", val1);
- assertEquals("value", val2);
- assertNotSame(val1, val2);
- }
-
- @Test
- public void testPrototypeWithArrayConversionForConstructor() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- List list = new ManagedList<>();
- list.add("myName");
- list.add("myBeanName");
- RootBeanDefinition bd = new RootBeanDefinition(DerivedTestBean.class);
- bd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
- bd.getConstructorArgumentValues().addGenericArgumentValue(list);
- lbf.registerBeanDefinition("test", bd);
- DerivedTestBean tb = (DerivedTestBean) lbf.getBean("test");
- assertEquals("myName", tb.getName());
- assertEquals("myBeanName", tb.getBeanName());
- DerivedTestBean tb2 = (DerivedTestBean) lbf.getBean("test");
- assertTrue(tb != tb2);
- assertEquals("myName", tb2.getName());
- assertEquals("myBeanName", tb2.getBeanName());
- }
-
- @Test
- public void testPrototypeWithArrayConversionForFactoryMethod() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- List list = new ManagedList<>();
- list.add("myName");
- list.add("myBeanName");
- RootBeanDefinition bd = new RootBeanDefinition(DerivedTestBean.class);
- bd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
- bd.setFactoryMethodName("create");
- bd.getConstructorArgumentValues().addGenericArgumentValue(list);
- lbf.registerBeanDefinition("test", bd);
- DerivedTestBean tb = (DerivedTestBean) lbf.getBean("test");
- assertEquals("myName", tb.getName());
- assertEquals("myBeanName", tb.getBeanName());
- DerivedTestBean tb2 = (DerivedTestBean) lbf.getBean("test");
- assertTrue(tb != tb2);
- assertEquals("myName", tb2.getName());
- assertEquals("myBeanName", tb2.getBeanName());
- }
-
- @Test
- public void testPrototypeCreationIsFastEnough() {
- Assume.group(TestGroup.PERFORMANCE);
- Assume.notLogging(factoryLog);
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- RootBeanDefinition rbd = new RootBeanDefinition(TestBean.class);
- rbd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
- lbf.registerBeanDefinition("test", rbd);
- lbf.freezeConfiguration();
- StopWatch sw = new StopWatch();
- sw.start("prototype");
- for (int i = 0; i < 100000; i++) {
- lbf.getBean("test");
- }
- sw.stop();
- // System.out.println(sw.getTotalTimeMillis());
- assertTrue("Prototype creation took too long: " + sw.getTotalTimeMillis(), sw.getTotalTimeMillis() < 3000);
- }
-
- @Test
- public void testPrototypeCreationWithDependencyCheckIsFastEnough() {
- Assume.group(TestGroup.PERFORMANCE);
- Assume.notLogging(factoryLog);
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- RootBeanDefinition rbd = new RootBeanDefinition(LifecycleBean.class);
- rbd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
- rbd.setDependencyCheck(RootBeanDefinition.DEPENDENCY_CHECK_OBJECTS);
- lbf.registerBeanDefinition("test", rbd);
- lbf.addBeanPostProcessor(new LifecycleBean.PostProcessor());
- lbf.freezeConfiguration();
- StopWatch sw = new StopWatch();
- sw.start("prototype");
- for (int i = 0; i < 100000; i++) {
- lbf.getBean("test");
- }
- sw.stop();
- // System.out.println(sw.getTotalTimeMillis());
- assertTrue("Prototype creation took too long: " + sw.getTotalTimeMillis(), sw.getTotalTimeMillis() < 3000);
- }
-
- @Test
- @Ignore // TODO re-enable when ConstructorResolver TODO sorted out
- public void testPrototypeCreationWithConstructorArgumentsIsFastEnough() {
- Assume.group(TestGroup.PERFORMANCE);
- Assume.notLogging(factoryLog);
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- RootBeanDefinition rbd = new RootBeanDefinition(TestBean.class);
- rbd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
- rbd.getConstructorArgumentValues().addGenericArgumentValue("juergen");
- rbd.getConstructorArgumentValues().addGenericArgumentValue("99");
- lbf.registerBeanDefinition("test", rbd);
- lbf.freezeConfiguration();
- StopWatch sw = new StopWatch();
- sw.start("prototype");
- for (int i = 0; i < 100000; i++) {
- TestBean tb = (TestBean) lbf.getBean("test");
- assertEquals("juergen", tb.getName());
- assertEquals(99, tb.getAge());
- }
- sw.stop();
- // System.out.println(sw.getTotalTimeMillis());
- assertTrue("Prototype creation took too long: " + sw.getTotalTimeMillis(), sw.getTotalTimeMillis() < 3000);
- }
-
- @Test
- public void testPrototypeCreationWithResolvedConstructorArgumentsIsFastEnough() {
- Assume.group(TestGroup.PERFORMANCE);
- Assume.notLogging(factoryLog);
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- RootBeanDefinition rbd = new RootBeanDefinition(TestBean.class);
- rbd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
- rbd.getConstructorArgumentValues().addGenericArgumentValue(new RuntimeBeanReference("spouse"));
- lbf.registerBeanDefinition("test", rbd);
- lbf.registerBeanDefinition("spouse", new RootBeanDefinition(TestBean.class));
- lbf.freezeConfiguration();
- TestBean spouse = (TestBean) lbf.getBean("spouse");
- StopWatch sw = new StopWatch();
- sw.start("prototype");
- for (int i = 0; i < 100000; i++) {
- TestBean tb = (TestBean) lbf.getBean("test");
- assertSame(spouse, tb.getSpouse());
- }
- sw.stop();
- // System.out.println(sw.getTotalTimeMillis());
- assertTrue("Prototype creation took too long: " + sw.getTotalTimeMillis(), sw.getTotalTimeMillis() < 4000);
- }
-
- @Test
- public void testPrototypeCreationWithPropertiesIsFastEnough() {
- Assume.group(TestGroup.PERFORMANCE);
- Assume.notLogging(factoryLog);
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- RootBeanDefinition rbd = new RootBeanDefinition(TestBean.class);
- rbd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
- rbd.getPropertyValues().add("name", "juergen");
- rbd.getPropertyValues().add("age", "99");
- lbf.registerBeanDefinition("test", rbd);
- lbf.freezeConfiguration();
- StopWatch sw = new StopWatch();
- sw.start("prototype");
- for (int i = 0; i < 100000; i++) {
- TestBean tb = (TestBean) lbf.getBean("test");
- assertEquals("juergen", tb.getName());
- assertEquals(99, tb.getAge());
- }
- sw.stop();
- // System.out.println(sw.getTotalTimeMillis());
- assertTrue("Prototype creation took too long: " + sw.getTotalTimeMillis(), sw.getTotalTimeMillis() < 4000);
- }
-
- @Test
- public void testPrototypeCreationWithResolvedPropertiesIsFastEnough() {
- Assume.group(TestGroup.PERFORMANCE);
- Assume.notLogging(factoryLog);
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- RootBeanDefinition rbd = new RootBeanDefinition(TestBean.class);
- rbd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
- rbd.getPropertyValues().add("spouse", new RuntimeBeanReference("spouse"));
- lbf.registerBeanDefinition("test", rbd);
- lbf.registerBeanDefinition("spouse", new RootBeanDefinition(TestBean.class));
- lbf.freezeConfiguration();
- TestBean spouse = (TestBean) lbf.getBean("spouse");
- StopWatch sw = new StopWatch();
- sw.start("prototype");
- for (int i = 0; i < 100000; i++) {
- TestBean tb = (TestBean) lbf.getBean("test");
- assertSame(spouse, tb.getSpouse());
- }
- sw.stop();
- // System.out.println(sw.getTotalTimeMillis());
- assertTrue("Prototype creation took too long: " + sw.getTotalTimeMillis(), sw.getTotalTimeMillis() < 4000);
- }
-
- @Test
- public void testSingletonLookupByNameIsFastEnough() {
- Assume.group(TestGroup.PERFORMANCE);
- Assume.notLogging(factoryLog);
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- lbf.registerBeanDefinition("test", new RootBeanDefinition(TestBean.class));
- lbf.freezeConfiguration();
- StopWatch sw = new StopWatch();
- sw.start("singleton");
- for (int i = 0; i < 1000000; i++) {
- lbf.getBean("test");
- }
- sw.stop();
- // System.out.println(sw.getTotalTimeMillis());
- assertTrue("Singleton lookup took too long: " + sw.getTotalTimeMillis(), sw.getTotalTimeMillis() < 1000);
- }
-
- @Test
- public void testSingletonLookupByTypeIsFastEnough() {
- Assume.group(TestGroup.PERFORMANCE);
- Assume.notLogging(factoryLog);
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- lbf.registerBeanDefinition("test", new RootBeanDefinition(TestBean.class));
- lbf.freezeConfiguration();
- StopWatch sw = new StopWatch();
- sw.start("singleton");
- for (int i = 0; i < 1000000; i++) {
- lbf.getBean(TestBean.class);
- }
- sw.stop();
- // System.out.println(sw.getTotalTimeMillis());
- assertTrue("Singleton lookup took too long: " + sw.getTotalTimeMillis(), sw.getTotalTimeMillis() < 1000);
- }
-
- @Test
- public void testBeanPostProcessorWithWrappedObjectAndDisposableBean() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- RootBeanDefinition bd = new RootBeanDefinition(BeanWithDisposableBean.class);
- lbf.registerBeanDefinition("test", bd);
- lbf.addBeanPostProcessor(new BeanPostProcessor() {
- @Override
- public Object postProcessBeforeInitialization(Object bean, String beanName) {
- return new TestBean();
- }
- @Override
- public Object postProcessAfterInitialization(Object bean, String beanName) {
- return bean;
- }
- });
- BeanWithDisposableBean.closed = false;
- lbf.preInstantiateSingletons();
- lbf.destroySingletons();
- assertTrue("Destroy method invoked", BeanWithDisposableBean.closed);
- }
-
- @Test
- public void testBeanPostProcessorWithWrappedObjectAndCloseable() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- RootBeanDefinition bd = new RootBeanDefinition(BeanWithCloseable.class);
- lbf.registerBeanDefinition("test", bd);
- lbf.addBeanPostProcessor(new BeanPostProcessor() {
- @Override
- public Object postProcessBeforeInitialization(Object bean, String beanName) {
- return new TestBean();
- }
- @Override
- public Object postProcessAfterInitialization(Object bean, String beanName) {
- return bean;
- }
- });
- BeanWithDisposableBean.closed = false;
- lbf.preInstantiateSingletons();
- lbf.destroySingletons();
- assertTrue("Destroy method invoked", BeanWithCloseable.closed);
- }
-
- @Test
- public void testBeanPostProcessorWithWrappedObjectAndDestroyMethod() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- RootBeanDefinition bd = new RootBeanDefinition(BeanWithDestroyMethod.class);
- bd.setDestroyMethodName("close");
- lbf.registerBeanDefinition("test", bd);
- lbf.addBeanPostProcessor(new BeanPostProcessor() {
- @Override
- public Object postProcessBeforeInitialization(Object bean, String beanName) {
- return new TestBean();
- }
- @Override
- public Object postProcessAfterInitialization(Object bean, String beanName) {
- return bean;
- }
- });
- BeanWithDestroyMethod.closeCount = 0;
- lbf.preInstantiateSingletons();
- lbf.destroySingletons();
- assertEquals("Destroy methods invoked", 1, BeanWithDestroyMethod.closeCount);
- }
-
- @Test
- public void testDestroyMethodOnInnerBean() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- RootBeanDefinition innerBd = new RootBeanDefinition(BeanWithDestroyMethod.class);
- innerBd.setDestroyMethodName("close");
- RootBeanDefinition bd = new RootBeanDefinition(BeanWithDestroyMethod.class);
- bd.setDestroyMethodName("close");
- bd.getPropertyValues().add("inner", innerBd);
- lbf.registerBeanDefinition("test", bd);
- BeanWithDestroyMethod.closeCount = 0;
- lbf.preInstantiateSingletons();
- lbf.destroySingletons();
- assertEquals("Destroy methods invoked", 2, BeanWithDestroyMethod.closeCount);
- }
-
- @Test
- public void testDestroyMethodOnInnerBeanAsPrototype() {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- RootBeanDefinition innerBd = new RootBeanDefinition(BeanWithDestroyMethod.class);
- innerBd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
- innerBd.setDestroyMethodName("close");
- RootBeanDefinition bd = new RootBeanDefinition(BeanWithDestroyMethod.class);
- bd.setDestroyMethodName("close");
- bd.getPropertyValues().add("inner", innerBd);
- lbf.registerBeanDefinition("test", bd);
- BeanWithDestroyMethod.closeCount = 0;
- lbf.preInstantiateSingletons();
- lbf.destroySingletons();
- assertEquals("Destroy methods invoked", 1, BeanWithDestroyMethod.closeCount);
- }
-
- @Test
- public void testFindTypeOfSingletonFactoryMethodOnBeanInstance() {
- findTypeOfPrototypeFactoryMethodOnBeanInstance(true);
- }
-
- @Test
- public void testFindTypeOfPrototypeFactoryMethodOnBeanInstance() {
- findTypeOfPrototypeFactoryMethodOnBeanInstance(false);
- }
-
- /**
- * @param singleton whether the bean created from the factory method on
- * the bean instance should be a singleton or prototype. This flag is
- * used to allow checking of the new ability in 1.2.4 to determine the type
- * of a prototype created from invoking a factory method on a bean instance
- * in the factory.
- */
- private void findTypeOfPrototypeFactoryMethodOnBeanInstance(boolean singleton) {
- String expectedNameFromProperties = "tony";
- String expectedNameFromArgs = "gordon";
-
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- RootBeanDefinition instanceFactoryDefinition = new RootBeanDefinition(BeanWithFactoryMethod.class);
- MutablePropertyValues pvs = new MutablePropertyValues();
- pvs.add("name", expectedNameFromProperties);
- instanceFactoryDefinition.setPropertyValues(pvs);
- lbf.registerBeanDefinition("factoryBeanInstance", instanceFactoryDefinition);
-
- RootBeanDefinition factoryMethodDefinitionWithProperties = new RootBeanDefinition();
- factoryMethodDefinitionWithProperties.setFactoryBeanName("factoryBeanInstance");
- factoryMethodDefinitionWithProperties.setFactoryMethodName("create");
- if (!singleton) {
- factoryMethodDefinitionWithProperties.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
- }
- lbf.registerBeanDefinition("fmWithProperties", factoryMethodDefinitionWithProperties);
-
- RootBeanDefinition factoryMethodDefinitionGeneric = new RootBeanDefinition();
- factoryMethodDefinitionGeneric.setFactoryBeanName("factoryBeanInstance");
- factoryMethodDefinitionGeneric.setFactoryMethodName("createGeneric");
- if (!singleton) {
- factoryMethodDefinitionGeneric.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
- }
- lbf.registerBeanDefinition("fmGeneric", factoryMethodDefinitionGeneric);
-
- RootBeanDefinition factoryMethodDefinitionWithArgs = new RootBeanDefinition();
- factoryMethodDefinitionWithArgs.setFactoryBeanName("factoryBeanInstance");
- factoryMethodDefinitionWithArgs.setFactoryMethodName("createWithArgs");
- ConstructorArgumentValues cvals = new ConstructorArgumentValues();
- cvals.addGenericArgumentValue(expectedNameFromArgs);
- factoryMethodDefinitionWithArgs.setConstructorArgumentValues(cvals);
- if (!singleton) {
- factoryMethodDefinitionWithArgs.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
- }
- lbf.registerBeanDefinition("fmWithArgs", factoryMethodDefinitionWithArgs);
-
- assertEquals(4, lbf.getBeanDefinitionCount());
- List tbNames = Arrays.asList(lbf.getBeanNamesForType(TestBean.class));
- assertTrue(tbNames.contains("fmWithProperties"));
- assertTrue(tbNames.contains("fmWithArgs"));
- assertEquals(2, tbNames.size());
-
- TestBean tb = (TestBean) lbf.getBean("fmWithProperties");
- TestBean second = (TestBean) lbf.getBean("fmWithProperties");
- if (singleton) {
- assertSame(tb, second);
- }
- else {
- assertNotSame(tb, second);
- }
- assertEquals(expectedNameFromProperties, tb.getName());
-
- tb = (TestBean) lbf.getBean("fmGeneric");
- second = (TestBean) lbf.getBean("fmGeneric");
- if (singleton) {
- assertSame(tb, second);
- }
- else {
- assertNotSame(tb, second);
- }
- assertEquals(expectedNameFromProperties, tb.getName());
-
- TestBean tb2 = (TestBean) lbf.getBean("fmWithArgs");
- second = (TestBean) lbf.getBean("fmWithArgs");
- if (singleton) {
- assertSame(tb2, second);
- }
- else {
- assertNotSame(tb2, second);
- }
- assertEquals(expectedNameFromArgs, tb2.getName());
- }
-
- @Test(expected = IllegalStateException.class)
- public void testScopingBeanToUnregisteredScopeResultsInAnException() {
- BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(TestBean.class);
- AbstractBeanDefinition beanDefinition = builder.getBeanDefinition();
- beanDefinition.setScope("he put himself so low could hardly look me in the face");
-
- DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
- factory.registerBeanDefinition("testBean", beanDefinition);
- factory.getBean("testBean");
- }
-
- @Test
- public void testExplicitScopeInheritanceForChildBeanDefinitions() {
- String theChildScope = "bonanza!";
-
- RootBeanDefinition parent = new RootBeanDefinition();
- parent.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
-
- AbstractBeanDefinition child = BeanDefinitionBuilder.childBeanDefinition("parent").getBeanDefinition();
- child.setBeanClass(TestBean.class);
- child.setScope(theChildScope);
-
- DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
- factory.registerBeanDefinition("parent", parent);
- factory.registerBeanDefinition("child", child);
-
- AbstractBeanDefinition def = (AbstractBeanDefinition) factory.getBeanDefinition("child");
- assertEquals("Child 'scope' not overriding parent scope (it must).", theChildScope, def.getScope());
- }
-
- @Test
- public void testScopeInheritanceForChildBeanDefinitions() {
- RootBeanDefinition parent = new RootBeanDefinition();
- parent.setScope("bonanza!");
-
- AbstractBeanDefinition child = new ChildBeanDefinition("parent");
- child.setBeanClass(TestBean.class);
-
- DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
- factory.registerBeanDefinition("parent", parent);
- factory.registerBeanDefinition("child", child);
-
- BeanDefinition def = factory.getMergedBeanDefinition("child");
- assertEquals("Child 'scope' not inherited", "bonanza!", def.getScope());
- }
-
- @Test
- public void testFieldSettingWithInstantiationAwarePostProcessorNoShortCircuit() {
- doTestFieldSettingWithInstantiationAwarePostProcessor(false);
- }
-
- @Test
- public void testFieldSettingWithInstantiationAwarePostProcessorWithShortCircuit() {
- doTestFieldSettingWithInstantiationAwarePostProcessor(true);
- }
-
- private void doTestFieldSettingWithInstantiationAwarePostProcessor(final boolean skipPropertyPopulation) {
- DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- RootBeanDefinition bd = new RootBeanDefinition(TestBean.class);
- int ageSetByPropertyValue = 27;
- bd.getPropertyValues().addPropertyValue(new PropertyValue("age", new Integer(ageSetByPropertyValue)));
- lbf.registerBeanDefinition("test", bd);
- final String nameSetOnField = "nameSetOnField";
- lbf.addBeanPostProcessor(new InstantiationAwareBeanPostProcessorAdapter() {
- @Override
- public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
- TestBean tb = (TestBean) bean;
- try {
- Field f = TestBean.class.getDeclaredField("name");
- f.setAccessible(true);
- f.set(tb, nameSetOnField);
- return !skipPropertyPopulation;
- }
- catch (Exception ex) {
- fail("Unexpected exception: " + ex);
- // Keep compiler happy about return
- throw new IllegalStateException();
- }
- }
- });
- lbf.preInstantiateSingletons();
- TestBean tb = (TestBean) lbf.getBean("test");
- assertEquals("Name was set on field by IAPP", nameSetOnField, tb.getName());
- if (!skipPropertyPopulation) {
- assertEquals("Property value still set", ageSetByPropertyValue, tb.getAge());
- }
- else {
- assertEquals("Property value was NOT set and still has default value", 0, tb.getAge());
- }
- }
-
- @SuppressWarnings("unchecked")
- @Test
- public void testInitSecurityAwarePrototypeBean() {
- final DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
- RootBeanDefinition bd = new RootBeanDefinition(TestSecuredBean.class);
- bd.setScope(ConfigurableBeanFactory.SCOPE_PROTOTYPE);
- bd.setInitMethodName("init");
- lbf.registerBeanDefinition("test", bd);
- final Subject subject = new Subject();
- subject.getPrincipals().add(new TestPrincipal("user1"));
-
- TestSecuredBean bean = (TestSecuredBean) Subject.doAsPrivileged(subject,
- new PrivilegedAction() {
- @Override
- public Object run() {
- return lbf.getBean("test");
- }
- }, null);
- assertNotNull(bean);
- assertEquals("user1", bean.getUserName());
- }
-
- @Test
- public void testContainsBeanReturnsTrueEvenForAbstractBeanDefinition() {
- DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
- bf.registerBeanDefinition("abs", BeanDefinitionBuilder
- .rootBeanDefinition(TestBean.class).setAbstract(true).getBeanDefinition());
- assertThat(bf.containsBean("abs"), equalTo(true));
- assertThat(bf.containsBean("bogus"), equalTo(false));
- }
-
- @Test
- public void resolveEmbeddedValue() {
- DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
- StringValueResolver r1 = mock(StringValueResolver.class);
- StringValueResolver r2 = mock(StringValueResolver.class);
- StringValueResolver r3 = mock(StringValueResolver.class);
- bf.addEmbeddedValueResolver(r1);
- bf.addEmbeddedValueResolver(r2);
- bf.addEmbeddedValueResolver(r3);
- given(r1.resolveStringValue("A")).willReturn("B");
- given(r2.resolveStringValue("B")).willReturn(null);
- given(r3.resolveStringValue(isNull())).willThrow(new IllegalArgumentException());
-
- bf.resolveEmbeddedValue("A");
-
- verify(r1).resolveStringValue("A");
- verify(r2).resolveStringValue("B");
- verify(r3, never()).resolveStringValue(isNull());
- }
-
- @Test
- public void populatedJavaUtilOptionalBean() {
- DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
- RootBeanDefinition bd = new RootBeanDefinition(Optional.class);
- bd.setFactoryMethodName("of");
- bd.getConstructorArgumentValues().addGenericArgumentValue("CONTENT");
- bf.registerBeanDefinition("optionalBean", bd);
- assertEquals(Optional.of("CONTENT"), bf.getBean(Optional.class));
- }
-
- @Test
- public void emptyJavaUtilOptionalBean() {
- DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
- RootBeanDefinition bd = new RootBeanDefinition(Optional.class);
- bd.setFactoryMethodName("empty");
- bf.registerBeanDefinition("optionalBean", bd);
- assertSame(Optional.empty(), bf.getBean(Optional.class));
- }
-
- @Test
- public void testNonPublicEnum() {
- DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
- RootBeanDefinition bd = new RootBeanDefinition(NonPublicEnumHolder.class);
- bd.getConstructorArgumentValues().addGenericArgumentValue("VALUE_1");
- bf.registerBeanDefinition("holderBean", bd);
- NonPublicEnumHolder holder = (NonPublicEnumHolder) bf.getBean("holderBean");
- assertEquals(NonPublicEnum.VALUE_1, holder.getNonPublicEnum());
- }
-
- /**
- * Test that by-type bean lookup caching is working effectively by searching for a
- * bean of type B 10K times within a container having 1K additional beans of type A.
- * Prior to by-type caching, each bean lookup would traverse the entire container
- * (all 1001 beans), performing expensive assignability checks, etc. Now these
- * operations are necessary only once, providing a dramatic performance improvement.
- * On load-free modern hardware (e.g. an 8-core MPB), this method should complete well
- * under the 1000 ms timeout, usually ~= 300ms. With caching removed and on the same
- * hardware the method will take ~13000 ms. See SPR-6870.
- */
- @Test(timeout = 1000)
- public void testByTypeLookupIsFastEnough() {
- Assume.group(TestGroup.PERFORMANCE);
- DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
-
- for (int i = 0; i < 1000; i++) {
- bf.registerBeanDefinition("a" + i, new RootBeanDefinition(A.class));
- }
- bf.registerBeanDefinition("b", new RootBeanDefinition(B.class));
-
- bf.freezeConfiguration();
-
- for (int i = 0; i < 10000; i++) {
- bf.getBean(B.class);
- }
- }
-
- @Test(timeout = 1000)
- public void testRegistrationOfManyBeanDefinitionsIsFastEnough() {
- Assume.group(TestGroup.PERFORMANCE);
- DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
- bf.registerBeanDefinition("b", new RootBeanDefinition(B.class));
- // bf.getBean("b");
-
- for (int i = 0; i < 100000; i++) {
- bf.registerBeanDefinition("a" + i, new RootBeanDefinition(A.class));
- }
- }
-
- @Test(timeout = 1000)
- public void testRegistrationOfManySingletonsIsFastEnough() {
- Assume.group(TestGroup.PERFORMANCE);
- DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
- bf.registerBeanDefinition("b", new RootBeanDefinition(B.class));
- // bf.getBean("b");
-
- for (int i = 0; i < 100000; i++) {
- bf.registerSingleton("a" + i, new A());
- }
- }
-
-
- static class A { }
-
- static class B { }
-
-
- public static class NoDependencies {
-
- private NoDependencies() {
- }
- }
-
-
- public static class ConstructorDependency implements BeanNameAware {
-
- public TestBean spouse;
-
- public int spouseAge;
-
- private String beanName;
-
- public ConstructorDependency(TestBean spouse) {
- this.spouse = spouse;
- }
-
- public ConstructorDependency(int spouseAge) {
- this.spouseAge = spouseAge;
- }
-
- @SuppressWarnings("unused")
- private ConstructorDependency(TestBean spouse, TestBean otherSpouse) {
- throw new IllegalArgumentException("Should never be called");
- }
-
- @Override
- public void setBeanName(String name) {
- this.beanName = name;
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
- ConstructorDependency that = (ConstructorDependency) o;
- return spouseAge == that.spouseAge &&
- Objects.equals(spouse, that.spouse) &&
- Objects.equals(beanName, that.beanName);
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(spouse, spouseAge, beanName);
- }
- }
-
-
- public static class UnsatisfiedConstructorDependency {
-
- public UnsatisfiedConstructorDependency(TestBean t, SideEffectBean b) {
- }
- }
-
-
- public static class ConstructorDependencyBean {
-
- public ConstructorDependencyBean(ConstructorDependencyBean dependency) {
- }
- }
-
-
- public static class ConstructorDependencyFactoryBean implements FactoryBean {
-
- public ConstructorDependencyFactoryBean(String dependency) {
- }
-
- @Override
- public Object getObject() {
- return "test";
- }
-
- @Override
- public Class> getObjectType() {
- return String.class;
- }
-
- @Override
- public boolean isSingleton() {
- return true;
- }
- }
-
-
- public static class ConstructorDependencyWithClassResolution {
-
- public ConstructorDependencyWithClassResolution(Class> clazz) {
- }
-
- public ConstructorDependencyWithClassResolution() {
- }
- }
-
-
- public static class BeanWithDisposableBean implements DisposableBean {
-
- private static boolean closed;
-
- @Override
- public void destroy() {
- closed = true;
- }
- }
-
-
- public static class BeanWithCloseable implements Closeable {
-
- private static boolean closed;
-
- @Override
- public void close() {
- closed = true;
- }
- }
-
-
- public static abstract class BaseClassWithDestroyMethod {
-
- public abstract BaseClassWithDestroyMethod close();
- }
-
-
- public static class BeanWithDestroyMethod extends BaseClassWithDestroyMethod {
-
- private static int closeCount = 0;
-
- private BeanWithDestroyMethod inner;
-
- public void setInner(BeanWithDestroyMethod inner) {
- this.inner = inner;
- }
-
- @Override
- public BeanWithDestroyMethod close() {
- closeCount++;
- return this;
- }
- }
-
-
- public static class BeanWithFactoryMethod {
-
- private String name;
-
- public void setName(String name) {
- this.name = name;
- }
-
- public TestBean create() {
- TestBean tb = new TestBean();
- tb.setName(this.name);
- return tb;
- }
-
- public TestBean createWithArgs(String arg) {
- TestBean tb = new TestBean();
- tb.setName(arg);
- return tb;
- }
-
- public Object createGeneric() {
- return create();
- }
- }
-
-
- public interface Repository {
- }
-
-
- public interface RepositoryFactoryInformation {
- }
-
-
- public static abstract class RepositoryFactoryBeanSupport, S, ID extends Serializable>
- implements RepositoryFactoryInformation, FactoryBean {
- }
-
-
- public static class FactoryBeanThatShouldntBeCalled, S, ID extends Serializable>
- extends RepositoryFactoryBeanSupport implements Runnable, Callable {
-
- @Override
- public T getObject() {
- throw new IllegalStateException();
- }
-
- @Override
- public Class> getObjectType() {
- return null;
- }
-
- @Override
- public boolean isSingleton() {
- return false;
- }
-
- @Override
- public void run() {
- throw new IllegalStateException();
- }
-
- @Override
- public T call() {
- throw new IllegalStateException();
- }
- }
-
-
- public static class LazyInitFactory implements FactoryBean {
-
- public boolean initialized = false;
-
- @Override
- public Object getObject() {
- this.initialized = true;
- return "";
- }
-
- @Override
- public Class> getObjectType() {
- return String.class;
- }
-
- @Override
- public boolean isSingleton() {
- return true;
- }
- }
-
-
- public static class EagerInitFactory implements SmartFactoryBean {
-
- public boolean initialized = false;
-
- @Override
- public Object getObject() {
- this.initialized = true;
- return "";
- }
-
- @Override
- public Class> getObjectType() {
- return String.class;
- }
-
- @Override
- public boolean isSingleton() {
- return true;
- }
-
- @Override
- public boolean isPrototype() {
- return false;
- }
-
- @Override
- public boolean isEagerInit() {
- return true;
- }
- }
-
-
- public static class TestBeanFactory {
-
- public static boolean initialized = false;
-
- public TestBeanFactory() {
- initialized = true;
- }
-
- public static TestBean createTestBean() {
- return new TestBean();
- }
-
- public TestBean createTestBeanNonStatic() {
- return new TestBean();
- }
- }
-
-
- public static class ArrayBean {
-
- private Integer[] integerArray;
-
- private Resource[] resourceArray;
-
- public ArrayBean() {
- }
-
- public ArrayBean(Integer[] integerArray) {
- this.integerArray = integerArray;
- }
-
- public ArrayBean(Integer[] integerArray, Resource[] resourceArray) {
- this.integerArray = integerArray;
- this.resourceArray = resourceArray;
- }
-
- public Integer[] getIntegerArray() {
- return this.integerArray;
- }
-
- public void setResourceArray(Resource[] resourceArray) {
- this.resourceArray = resourceArray;
- }
-
- public Resource[] getResourceArray() {
- return this.resourceArray;
- }
- }
-
-
- /**
- * Bean with a dependency on a {@link FactoryBean}.
- */
- @SuppressWarnings("unused")
- private static class FactoryBeanDependentBean {
-
- private FactoryBean> factoryBean;
-
- public final FactoryBean> getFactoryBean() {
- return this.factoryBean;
- }
-
- public final void setFactoryBean(final FactoryBean> factoryBean) {
- this.factoryBean = factoryBean;
- }
- }
-
-
- private static class CustomTypeConverter implements TypeConverter {
-
- private final NumberFormat numberFormat;
-
- public CustomTypeConverter(NumberFormat numberFormat) {
- this.numberFormat = numberFormat;
- }
-
- @Override
- @SuppressWarnings("unchecked")
- public Object convertIfNecessary(Object value, @Nullable Class requiredType) {
- if (value instanceof String && Float.class.isAssignableFrom(requiredType)) {
- try {
- return new Float(this.numberFormat.parse((String) value).floatValue());
- }
- catch (ParseException ex) {
- throw new TypeMismatchException(value, requiredType, ex);
- }
- }
- else if (value instanceof String && int.class.isAssignableFrom(requiredType)) {
- return new Integer(5);
- }
- else {
- return value;
- }
- }
-
- @Override
- @SuppressWarnings("unchecked")
- public Object convertIfNecessary(Object value, @Nullable Class requiredType, @Nullable MethodParameter methodParam) {
- return convertIfNecessary(value, requiredType);
- }
-
- @Override
- @SuppressWarnings("unchecked")
- public Object convertIfNecessary(Object value, @Nullable Class requiredType, @Nullable Field field) {
- return convertIfNecessary(value, requiredType);
- }
- }
-
-
- private static class TestPrincipal implements Principal {
-
- private String name;
-
- public TestPrincipal(String name) {
- this.name = name;
- }
-
- @Override
- public String getName() {
- return this.name;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == this) {
- return true;
- }
- if (!(obj instanceof TestPrincipal)) {
- return false;
- }
- TestPrincipal p = (TestPrincipal) obj;
- return this.name.equals(p.name);
- }
-
- @Override
- public int hashCode() {
- return this.name.hashCode();
- }
- }
-
-
- @SuppressWarnings("unused")
- private static class TestSecuredBean {
-
- private String userName;
-
- public void init() {
- AccessControlContext acc = AccessController.getContext();
- Subject subject = Subject.getSubject(acc);
- if (subject == null) {
- return;
- }
- setNameFromPrincipal(subject.getPrincipals());
- }
-
- private void setNameFromPrincipal(Set principals) {
- if (principals == null) {
- return;
- }
- for (Iterator it = principals.iterator(); it.hasNext();) {
- Principal p = it.next();
- this.userName = p.getName();
- return;
- }
- }
-
- public String getUserName() {
- return this.userName;
- }
- }
-
-
- @SuppressWarnings("unused")
- private static class KnowsIfInstantiated {
-
- private static boolean instantiated;
-
- public static void clearInstantiationRecord() {
- instantiated = false;
- }
-
- public static boolean wasInstantiated() {
- return instantiated;
- }
-
- public KnowsIfInstantiated() {
- instantiated = true;
- }
-
- }
-
-
- @Priority(5)
- private static class HighPriorityTestBean extends TestBean {
- }
-
-
- @Priority(500)
- private static class LowPriorityTestBean extends TestBean {
- }
-
-
- private static class NullTestBeanFactoryBean implements FactoryBean {
-
- @Override
- public TestBean getObject() {
- return null;
- }
-
- @Override
- public Class> getObjectType() {
- return TestBean.class;
- }
-
- @Override
- public boolean isSingleton() {
- return true;
- }
- }
-
-
- private static class TestBeanRecipient {
-
- public TestBean testBean;
-
- public TestBeanRecipient(TestBean testBean) {
- this.testBean = testBean;
- }
- }
-
-
- enum NonPublicEnum {
-
- VALUE_1, VALUE_2;
- }
-
-
- static class NonPublicEnumHolder {
-
- final NonPublicEnum nonPublicEnum;
-
- public NonPublicEnumHolder(NonPublicEnum nonPublicEnum) {
- this.nonPublicEnum = nonPublicEnum;
- }
-
- public NonPublicEnum getNonPublicEnum() {
- return nonPublicEnum;
- }
- }
-
}
diff --git a/spring-beans/src/test/java/org/springframework/beans/factory/support/ScalableDefaultListableBeanFactoryTests.java b/spring-beans/src/test/java/org/springframework/beans/factory/support/ScalableDefaultListableBeanFactoryTests.java
new file mode 100644
index 000000000000..631e70c3996c
--- /dev/null
+++ b/spring-beans/src/test/java/org/springframework/beans/factory/support/ScalableDefaultListableBeanFactoryTests.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2002-2018 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.beans.factory.support;
+
+import java.util.List;
+import org.junit.Test;
+import org.springframework.beans.factory.AbstractDefaultListableBeanFactoryTests;
+import org.springframework.beans.factory.BeanFactory;
+import org.springframework.lang.Nullable;
+
+import java.util.Collections;
+import java.util.Set;
+import java.util.function.Function;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Test class for the {@link ScalableDefaultListableBeanFactory}.
+ * Tests for properties population and autowire behavior
+ *
+ * @author Rahul Shinde
+ */
+public class ScalableDefaultListableBeanFactoryTests extends AbstractDefaultListableBeanFactoryTests {
+
+ public DefaultListableBeanFactory getInstance() {
+ return new ScalableDefaultListableBeanFactory();
+ }
+
+ public DefaultListableBeanFactory getInstance(@Nullable BeanFactory parentBeanFactory) {
+ return new ScalableDefaultListableBeanFactory(parentBeanFactory);
+ }
+
+ interface IA {
+ }
+
+ interface IB {
+ }
+
+ interface IAB extends IA, IB {
+ }
+
+ private class ClassA implements IA {
+ }
+
+ private class ClassAB implements IAB {
+ }
+
+ private class ClassAWithB implements IA, IB {
+ }
+
+ @Test
+ public void testGetSuperTypes() {
+ Function, Set>> superTypeMapper = ScalableDefaultListableBeanFactory::getSuperTypes;
+
+ Set> clazzes;
+ clazzes = superTypeMapper.apply(IA.class);
+ assertEquals(1, clazzes.size());
+ assertTrue(clazzes.contains(Object.class));
+
+ clazzes = superTypeMapper.apply(ClassA.class);
+ assertEquals(2, clazzes.size());
+ assertTrue(clazzes.contains(IA.class));
+
+ clazzes = superTypeMapper.apply(ClassAB.class);
+ assertEquals(4, clazzes.size());
+ List> resultAB = new java.util.ArrayList<>();
+ Collections.addAll(resultAB, IA.class, IB.class, IAB.class);
+ assertTrue(clazzes.containsAll(resultAB));
+
+ clazzes = superTypeMapper.apply(ClassAWithB.class);
+ assertEquals(3, clazzes.size());
+ List> resultAWB = new java.util.ArrayList<>();
+ Collections.addAll(resultAWB, IA.class, IB.class, Object.class);
+ assertTrue(clazzes.containsAll(resultAWB));
+ }
+}