Package org.springframework.beans.factory.xml

Source Code of org.springframework.beans.factory.xml.XmlBeanFactoryTests$ConstructorArrayTestBean

/*
* Copyright 2002-2014 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.xml;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StringWriter;
import java.lang.reflect.Method;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.Map;

import org.apache.commons.logging.LogFactory;
import org.junit.Test;
import org.xml.sax.InputSource;

import org.springframework.aop.framework.ProxyFactory;
import org.springframework.aop.support.AopUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.FatalBeanException;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.factory.BeanCreationException;
import org.springframework.beans.factory.BeanCurrentlyInCreationException;
import org.springframework.beans.factory.BeanDefinitionStoreException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanIsAbstractException;
import org.springframework.beans.factory.CannotLoadBeanClassException;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.UnsatisfiedDependencyException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.support.MethodReplacer;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.UrlResource;
import org.springframework.core.io.support.EncodedResource;
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.IndexedTestBean;
import org.springframework.tests.sample.beans.ResourceTestBean;
import org.springframework.tests.sample.beans.TestBean;
import org.springframework.tests.sample.beans.factory.DummyFactory;
import org.springframework.util.ClassUtils;
import org.springframework.util.FileCopyUtils;
import org.springframework.util.SerializationTestUtils;
import org.springframework.util.StopWatch;

import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;

/**
* Miscellaneous tests for XML bean definitions.
*
* @author Juergen Hoeller
* @author Rod Johnson
* @author Rick Evans
* @author Chris Beams
* @author Sam Brannen
*/
public final class XmlBeanFactoryTests {

  private static final Class<?> CLASS = XmlBeanFactoryTests.class;
  private static final String CLASSNAME = CLASS.getSimpleName();

  private static final ClassPathResource AUTOWIRE_CONTEXT = classPathResource("-autowire.xml");
  private static final ClassPathResource CHILD_CONTEXT = classPathResource("-child.xml");
  private static final ClassPathResource CLASS_NOT_FOUND_CONTEXT = classPathResource("-classNotFound.xml");
  private static final ClassPathResource COMPLEX_FACTORY_CIRCLE_CONTEXT = classPathResource("-complexFactoryCircle.xml");
  private static final ClassPathResource CONSTRUCTOR_ARG_CONTEXT = classPathResource("-constructorArg.xml");
  private static final ClassPathResource CONSTRUCTOR_OVERRIDES_CONTEXT = classPathResource("-constructorOverrides.xml");
  private static final ClassPathResource DELEGATION_OVERRIDES_CONTEXT = classPathResource("-delegationOverrides.xml");
  private static final ClassPathResource DEP_CARG_AUTOWIRE_CONTEXT = classPathResource("-depCargAutowire.xml");
  private static final ClassPathResource DEP_CARG_INNER_CONTEXT = classPathResource("-depCargInner.xml");
  private static final ClassPathResource DEP_CARG_CONTEXT = classPathResource("-depCarg.xml");
  private static final ClassPathResource DEP_DEPENDSON_INNER_CONTEXT = classPathResource("-depDependsOnInner.xml");
  private static final ClassPathResource DEP_DEPENDSON_CONTEXT = classPathResource("-depDependsOn.xml");
  private static final ClassPathResource DEP_PROP = classPathResource("-depProp.xml");
  private static final ClassPathResource DEP_PROP_ABN_CONTEXT = classPathResource("-depPropAutowireByName.xml");
  private static final ClassPathResource DEP_PROP_ABT_CONTEXT = classPathResource("-depPropAutowireByType.xml");
  private static final ClassPathResource DEP_PROP_MIDDLE_CONTEXT = classPathResource("-depPropInTheMiddle.xml");
  private static final ClassPathResource DEP_PROP_INNER_CONTEXT = classPathResource("-depPropInner.xml");
  private static final ClassPathResource DEP_MATERIALIZE_CONTEXT = classPathResource("-depMaterializeThis.xml");
  private static final ClassPathResource FACTORY_CIRCLE_CONTEXT = classPathResource("-factoryCircle.xml");
  private static final ClassPathResource INITIALIZERS_CONTEXT = classPathResource("-initializers.xml");
  private static final ClassPathResource INVALID_CONTEXT = classPathResource("-invalid.xml");
  private static final ClassPathResource INVALID_NO_SUCH_METHOD_CONTEXT = classPathResource("-invalidOverridesNoSuchMethod.xml");
  private static final ClassPathResource COLLECTIONS_XSD_CONTEXT = classPathResource("-localCollectionsUsingXsd.xml");
  private static final ClassPathResource MISSING_CONTEXT = classPathResource("-missing.xml");
  private static final ClassPathResource OVERRIDES_CONTEXT = classPathResource("-overrides.xml");
  private static final ClassPathResource PARENT_CONTEXT = classPathResource("-parent.xml");
  private static final ClassPathResource NO_SUCH_FACTORY_METHOD_CONTEXT = classPathResource("-noSuchFactoryMethod.xml");
  private static final ClassPathResource RECURSIVE_IMPORT_CONTEXT = classPathResource("-recursiveImport.xml");
  private static final ClassPathResource RESOURCE_CONTEXT = classPathResource("-resource.xml");
  private static final ClassPathResource SATISFIED_ALL_DEP_CONTEXT = classPathResource("-satisfiedAllDepCheck.xml");
  private static final ClassPathResource SATISFIED_OBJECT_DEP_CONTEXT = classPathResource("-satisfiedObjectDepCheck.xml");
  private static final ClassPathResource SATISFIED_SIMPLE_DEP_CONTEXT = classPathResource("-satisfiedSimpleDepCheck.xml");
  private static final ClassPathResource TEST_WITH_DUP_NAMES_CONTEXT = classPathResource("-testWithDuplicateNames.xml");
  private static final ClassPathResource TEST_WITH_DUP_NAME_IN_ALIAS_CONTEXT = classPathResource("-testWithDuplicateNameInAlias.xml");
  private static final ClassPathResource UNSATISFIED_ALL_DEP_CONTEXT = classPathResource("-unsatisfiedAllDepCheckMissingObjects.xml");
  private static final ClassPathResource UNSATISFIED_OBJECT_DEP_CONTEXT = classPathResource("-unsatisfiedObjectDepCheck.xml");
  private static final ClassPathResource UNSATISFIED_SIMPLE_DEP_CONTEXT = classPathResource("-unsatisfiedSimpleDepCheck.xml");
  private static final ClassPathResource REFTYPES_CONTEXT = classPathResource("-reftypes.xml");
  private static final ClassPathResource DEFAULT_LAZY_CONTEXT = classPathResource("-defaultLazyInit.xml");
  private static final ClassPathResource DEFAULT_AUTOWIRE_CONTEXT = classPathResource("-defaultAutowire.xml");

  private static ClassPathResource classPathResource(String suffix) {
    return new ClassPathResource(CLASSNAME + suffix, CLASS);
  }

  /* SPR-2368 */
  @Test
  public void testCollectionsReferredToAsRefLocals() throws Exception {
    DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
    new XmlBeanDefinitionReader(factory).loadBeanDefinitions(COLLECTIONS_XSD_CONTEXT);
    factory.preInstantiateSingletons();
  }

  @Test
  public void testRefToSeparatePrototypeInstances() throws Exception {
    DefaultListableBeanFactory xbf = new DefaultListableBeanFactory();
    XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(xbf);
    reader.setValidationMode(XmlBeanDefinitionReader.VALIDATION_NONE);
    reader.loadBeanDefinitions(REFTYPES_CONTEXT);

    TestBean emma = (TestBean) xbf.getBean("emma");
    TestBean georgia = (TestBean) xbf.getBean("georgia");
    ITestBean emmasJenks = emma.getSpouse();
    ITestBean georgiasJenks = georgia.getSpouse();
    assertTrue("Emma and georgia think they have a different boyfriend", emmasJenks != georgiasJenks);
    assertTrue("Emmas jenks has right name", emmasJenks.getName().equals("Andrew"));
    assertTrue("Emmas doesn't equal new ref", emmasJenks != xbf.getBean("jenks"));
    assertTrue("Georgias jenks has right name", emmasJenks.getName().equals("Andrew"));
    assertTrue("They are object equal", emmasJenks.equals(georgiasJenks));
    assertTrue("They object equal direct ref", emmasJenks.equals(xbf.getBean("jenks")));
  }

  @Test
  public void testRefToSingleton() throws Exception {
    DefaultListableBeanFactory xbf = new DefaultListableBeanFactory();
    XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(xbf);
    reader.setValidationMode(XmlBeanDefinitionReader.VALIDATION_NONE);
    reader.loadBeanDefinitions(new EncodedResource(REFTYPES_CONTEXT, "ISO-8859-1"));

    TestBean jen = (TestBean) xbf.getBean("jenny");
    TestBean dave = (TestBean) xbf.getBean("david");
    TestBean jenks = (TestBean) xbf.getBean("jenks");
    ITestBean davesJen = dave.getSpouse();
    ITestBean jenksJen = jenks.getSpouse();
    assertTrue("1 jen instance", davesJen == jenksJen);
    assertTrue("1 jen instance", davesJen == jen);
  }

  @Test
  public void testInnerBeans() throws IOException {
    DefaultListableBeanFactory xbf = new DefaultListableBeanFactory();
    XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(xbf);

    reader.setValidationMode(XmlBeanDefinitionReader.VALIDATION_NONE);
    InputStream inputStream = getClass().getResourceAsStream(REFTYPES_CONTEXT.getPath());
    try {
      reader.loadBeanDefinitions(new InputSource(inputStream));
    }
    finally {
      inputStream.close();
    }

    // Let's create the outer bean named "innerBean",
    // to check whether it doesn't create any conflicts
    // with the actual inner beans named "innerBean".
    xbf.getBean("innerBean");

    TestBean hasInnerBeans = (TestBean) xbf.getBean("hasInnerBeans");
    assertEquals(5, hasInnerBeans.getAge());
    TestBean inner1 = (TestBean) hasInnerBeans.getSpouse();
    assertNotNull(inner1);
    assertEquals("innerBean#1", inner1.getBeanName());
    assertEquals("inner1", inner1.getName());
    assertEquals(6, inner1.getAge());

    assertNotNull(hasInnerBeans.getFriends());
    Object[] friends = hasInnerBeans.getFriends().toArray();
    assertEquals(3, friends.length);
    DerivedTestBean inner2 = (DerivedTestBean) friends[0];
    assertEquals("inner2", inner2.getName());
    assertTrue(inner2.getBeanName().startsWith(DerivedTestBean.class.getName()));
    assertFalse(xbf.containsBean("innerBean#1"));
    assertNotNull(inner2);
    assertEquals(7, inner2.getAge());
    TestBean innerFactory = (TestBean) friends[1];
    assertEquals(DummyFactory.SINGLETON_NAME, innerFactory.getName());
    TestBean inner5 = (TestBean) friends[2];
    assertEquals("innerBean#2", inner5.getBeanName());

    assertNotNull(hasInnerBeans.getSomeMap());
    assertEquals(2, hasInnerBeans.getSomeMap().size());
    TestBean inner3 = (TestBean) hasInnerBeans.getSomeMap().get("someKey");
    assertEquals("Jenny", inner3.getName());
    assertEquals(30, inner3.getAge());
    TestBean inner4 = (TestBean) hasInnerBeans.getSomeMap().get("someOtherKey");
    assertEquals("inner4", inner4.getName());
    assertEquals(9, inner4.getAge());

    TestBean hasInnerBeansForConstructor = (TestBean) xbf.getBean("hasInnerBeansForConstructor");
    TestBean innerForConstructor = (TestBean) hasInnerBeansForConstructor.getSpouse();
    assertNotNull(innerForConstructor);
    assertEquals("innerBean#3", innerForConstructor.getBeanName());
    assertEquals("inner1", innerForConstructor.getName());
    assertEquals(6, innerForConstructor.getAge());

    hasInnerBeansForConstructor = (TestBean) xbf.getBean("hasInnerBeansAsPrototype");
    innerForConstructor = (TestBean) hasInnerBeansForConstructor.getSpouse();
    assertNotNull(innerForConstructor);
    assertEquals("innerBean", innerForConstructor.getBeanName());
    assertEquals("inner1", innerForConstructor.getName());
    assertEquals(6, innerForConstructor.getAge());

    hasInnerBeansForConstructor = (TestBean) xbf.getBean("hasInnerBeansAsPrototype");
    innerForConstructor = (TestBean) hasInnerBeansForConstructor.getSpouse();
    assertNotNull(innerForConstructor);
    assertEquals("innerBean", innerForConstructor.getBeanName());
    assertEquals("inner1", innerForConstructor.getName());
    assertEquals(6, innerForConstructor.getAge());

    xbf.destroySingletons();
    assertTrue(inner1.wasDestroyed());
    assertTrue(inner2.wasDestroyed());
    assertTrue(innerFactory.getName() == null);
    assertTrue(inner5.wasDestroyed());
  }

  @Test
  public void testInnerBeansWithoutDestroy() {
    DefaultListableBeanFactory xbf = new DefaultListableBeanFactory();
    XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(xbf);
    reader.setValidationMode(XmlBeanDefinitionReader.VALIDATION_NONE);
    reader.loadBeanDefinitions(REFTYPES_CONTEXT);

    // Let's create the outer bean named "innerBean",
    // to check whether it doesn't create any conflicts
    // with the actual inner beans named "innerBean".
    xbf.getBean("innerBean");

    TestBean hasInnerBeans = (TestBean) xbf.getBean("hasInnerBeansWithoutDestroy");
    assertEquals(5, hasInnerBeans.getAge());
    TestBean inner1 = (TestBean) hasInnerBeans.getSpouse();
    assertNotNull(inner1);
    assertTrue(inner1.getBeanName().startsWith("innerBean"));
    assertEquals("inner1", inner1.getName());
    assertEquals(6, inner1.getAge());

    assertNotNull(hasInnerBeans.getFriends());
    Object[] friends = hasInnerBeans.getFriends().toArray();
    assertEquals(3, friends.length);
    DerivedTestBean inner2 = (DerivedTestBean) friends[0];
    assertEquals("inner2", inner2.getName());
    assertTrue(inner2.getBeanName().startsWith(DerivedTestBean.class.getName()));
    assertNotNull(inner2);
    assertEquals(7, inner2.getAge());
    TestBean innerFactory = (TestBean) friends[1];
    assertEquals(DummyFactory.SINGLETON_NAME, innerFactory.getName());
    TestBean inner5 = (TestBean) friends[2];
    assertTrue(inner5.getBeanName().startsWith("innerBean"));
  }

  @Test
  public void testFailsOnInnerBean() {
    DefaultListableBeanFactory xbf = new DefaultListableBeanFactory();
    XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(xbf);
    reader.setValidationMode(XmlBeanDefinitionReader.VALIDATION_NONE);
    reader.loadBeanDefinitions(REFTYPES_CONTEXT);

    try {
      xbf.getBean("failsOnInnerBean");
    }
    catch (BeanCreationException ex) {
      // Check whether message contains outer bean name.
      ex.printStackTrace();
      assertTrue(ex.getMessage().contains("failsOnInnerBean"));
      assertTrue(ex.getMessage().contains("someMap"));
    }

    try {
      xbf.getBean("failsOnInnerBeanForConstructor");
    }
    catch (BeanCreationException ex) {
      // Check whether message contains outer bean name.
      ex.printStackTrace();
      assertTrue(ex.getMessage().contains("failsOnInnerBeanForConstructor"));
      assertTrue(ex.getMessage().contains("constructor argument"));
    }
  }

  @Test
  public void testInheritanceFromParentFactoryPrototype() throws Exception {
    DefaultListableBeanFactory parent = new DefaultListableBeanFactory();
    new XmlBeanDefinitionReader(parent).loadBeanDefinitions(PARENT_CONTEXT);
    DefaultListableBeanFactory child = new DefaultListableBeanFactory(parent);
    new XmlBeanDefinitionReader(child).loadBeanDefinitions(CHILD_CONTEXT);
    assertEquals(TestBean.class, child.getType("inheritsFromParentFactory"));
    TestBean inherits = (TestBean) child.getBean("inheritsFromParentFactory");
    // Name property value is overridden
    assertTrue(inherits.getName().equals("override"));
    // Age property is inherited from bean in parent factory
    assertTrue(inherits.getAge() == 1);
    TestBean inherits2 = (TestBean) child.getBean("inheritsFromParentFactory");
    assertFalse(inherits2 == inherits);
  }

  @Test
  public void testInheritanceWithDifferentClass() throws Exception {
    DefaultListableBeanFactory parent = new DefaultListableBeanFactory();
    new XmlBeanDefinitionReader(parent).loadBeanDefinitions(PARENT_CONTEXT);
    DefaultListableBeanFactory child = new DefaultListableBeanFactory(parent);
    new XmlBeanDefinitionReader(child).loadBeanDefinitions(CHILD_CONTEXT);
    assertEquals(DerivedTestBean.class, child.getType("inheritsWithClass"));
    DerivedTestBean inherits = (DerivedTestBean) child.getBean("inheritsWithDifferentClass");
    // Name property value is overridden
    assertTrue(inherits.getName().equals("override"));
    // Age property is inherited from bean in parent factory
    assertTrue(inherits.getAge() == 1);
    assertTrue(inherits.wasInitialized());
  }

  @Test
  public void testInheritanceWithClass() throws Exception {
    DefaultListableBeanFactory parent = new DefaultListableBeanFactory();
    new XmlBeanDefinitionReader(parent).loadBeanDefinitions(PARENT_CONTEXT);
    DefaultListableBeanFactory child = new DefaultListableBeanFactory(parent);
    new XmlBeanDefinitionReader(child).loadBeanDefinitions(CHILD_CONTEXT);
    assertEquals(DerivedTestBean.class, child.getType("inheritsWithClass"));
    DerivedTestBean inherits = (DerivedTestBean) child.getBean("inheritsWithClass");
    // Name property value is overridden
    assertTrue(inherits.getName().equals("override"));
    // Age property is inherited from bean in parent factory
    assertTrue(inherits.getAge() == 1);
    assertTrue(inherits.wasInitialized());
  }

  @Test
  public void testPrototypeInheritanceFromParentFactoryPrototype() throws Exception {
    DefaultListableBeanFactory parent = new DefaultListableBeanFactory();
    new XmlBeanDefinitionReader(parent).loadBeanDefinitions(PARENT_CONTEXT);
    DefaultListableBeanFactory child = new DefaultListableBeanFactory(parent);
    new XmlBeanDefinitionReader(child).loadBeanDefinitions(CHILD_CONTEXT);
    assertEquals(TestBean.class, child.getType("prototypeInheritsFromParentFactoryPrototype"));
    TestBean inherits = (TestBean) child.getBean("prototypeInheritsFromParentFactoryPrototype");
    // Name property value is overridden
    assertTrue(inherits.getName().equals("prototype-override"));
    // Age property is inherited from bean in parent factory
    assertTrue(inherits.getAge() == 2);
    TestBean inherits2 = (TestBean) child.getBean("prototypeInheritsFromParentFactoryPrototype");
    assertFalse(inherits2 == inherits);
    inherits2.setAge(13);
    assertTrue(inherits2.getAge() == 13);
    // Shouldn't have changed first instance
    assertTrue(inherits.getAge() == 2);
  }

  @Test
  public void testPrototypeInheritanceFromParentFactorySingleton() throws Exception {
    DefaultListableBeanFactory parent = new DefaultListableBeanFactory();
    new XmlBeanDefinitionReader(parent).loadBeanDefinitions(PARENT_CONTEXT);
    DefaultListableBeanFactory child = new DefaultListableBeanFactory(parent);
    new XmlBeanDefinitionReader(child).loadBeanDefinitions(CHILD_CONTEXT);
    TestBean inherits = (TestBean) child.getBean("protoypeInheritsFromParentFactorySingleton");
    // Name property value is overridden
    assertTrue(inherits.getName().equals("prototypeOverridesInheritedSingleton"));
    // Age property is inherited from bean in parent factory
    assertTrue(inherits.getAge() == 1);
    TestBean inherits2 = (TestBean) child.getBean("protoypeInheritsFromParentFactorySingleton");
    assertFalse(inherits2 == inherits);
    inherits2.setAge(13);
    assertTrue(inherits2.getAge() == 13);
    // Shouldn't have changed first instance
    assertTrue(inherits.getAge() == 1);
  }

  @Test
  public void testAutowireModeNotInherited() {
    DefaultListableBeanFactory xbf = new DefaultListableBeanFactory();
    XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(xbf);
    reader.loadBeanDefinitions(OVERRIDES_CONTEXT);

    TestBean david = (TestBean) xbf.getBean("magicDavid");
    // the parent bean is autowiring
    assertNotNull(david.getSpouse());

    TestBean derivedDavid = (TestBean) xbf.getBean("magicDavidDerived");
    // this fails while it inherits from the child bean
    assertNull("autowiring not propagated along child relationships", derivedDavid.getSpouse());
  }

  @Test
  public void testAbstractParentBeans() {
    DefaultListableBeanFactory parent = new DefaultListableBeanFactory();
    new XmlBeanDefinitionReader(parent).loadBeanDefinitions(PARENT_CONTEXT);
    parent.preInstantiateSingletons();
    assertTrue(parent.isSingleton("inheritedTestBeanWithoutClass"));

    // abstract beans should not match
    Map<?, ?> tbs = parent.getBeansOfType(TestBean.class);
    assertEquals(2, tbs.size());
    assertTrue(tbs.containsKey("inheritedTestBeanPrototype"));
    assertTrue(tbs.containsKey("inheritedTestBeanSingleton"));

    // abstract bean should throw exception on creation attempt
    try {
      parent.getBean("inheritedTestBeanWithoutClass");
      fail("Should have thrown BeanIsAbstractException");
    }
    catch (BeanIsAbstractException ex) {
      // expected
    }

    // non-abstract bean should work, even if it serves as parent
    assertTrue(parent.getBean("inheritedTestBeanPrototype") instanceof TestBean);
  }

  @Test
  public void testDependenciesMaterializeThis() throws Exception {
    DefaultListableBeanFactory xbf = new DefaultListableBeanFactory();
    new XmlBeanDefinitionReader(xbf).loadBeanDefinitions(DEP_MATERIALIZE_CONTEXT);

    assertEquals(2, xbf.getBeansOfType(DummyBo.class, true, false).size());
    assertEquals(3, xbf.getBeansOfType(DummyBo.class, true, true).size());
    assertEquals(3, xbf.getBeansOfType(DummyBo.class, true, false).size());
    assertEquals(3, xbf.getBeansOfType(DummyBo.class).size());
    assertEquals(2, xbf.getBeansOfType(DummyBoImpl.class, true, true).size());
    assertEquals(1, xbf.getBeansOfType(DummyBoImpl.class, false, true).size());
    assertEquals(2, xbf.getBeansOfType(DummyBoImpl.class).size());

    DummyBoImpl bos = (DummyBoImpl) xbf.getBean("boSingleton");
    DummyBoImpl bop = (DummyBoImpl) xbf.getBean("boPrototype");
    assertNotSame(bos, bop);
    assertTrue(bos.dao == bop.dao);
  }

  @Test
  public void testChildOverridesParentBean() throws Exception {
    DefaultListableBeanFactory parent = new DefaultListableBeanFactory();
    new XmlBeanDefinitionReader(parent).loadBeanDefinitions(PARENT_CONTEXT);
    DefaultListableBeanFactory child = new DefaultListableBeanFactory(parent);
    new XmlBeanDefinitionReader(child).loadBeanDefinitions(CHILD_CONTEXT);
    TestBean inherits = (TestBean) child.getBean("inheritedTestBean");
    // Name property value is overridden
    assertTrue(inherits.getName().equals("overrideParentBean"));
    // Age property is inherited from bean in parent factory
    assertTrue(inherits.getAge() == 1);
    TestBean inherits2 = (TestBean) child.getBean("inheritedTestBean");
    assertTrue(inherits2 != inherits);
  }

  /**
   * Check that a prototype can't inherit from a bogus parent.
   * If a singleton does this the factory will fail to load.
   */
  @Test
  public void testBogusParentageFromParentFactory() throws Exception {
    DefaultListableBeanFactory parent = new DefaultListableBeanFactory();
    new XmlBeanDefinitionReader(parent).loadBeanDefinitions(PARENT_CONTEXT);
    DefaultListableBeanFactory child = new DefaultListableBeanFactory(parent);
    new XmlBeanDefinitionReader(child).loadBeanDefinitions(CHILD_CONTEXT);
    try {
      child.getBean("bogusParent", TestBean.class);
      fail();
    }
    catch (BeanDefinitionStoreException ex) {
      // check exception message contains the name
      assertTrue(ex.getMessage().indexOf("bogusParent") != -1);
      assertTrue(ex.getCause() instanceof NoSuchBeanDefinitionException);
    }
  }

  /**
   * Note that prototype/singleton distinction is <b>not</b> inherited.
   * It's possible for a subclass singleton not to return independent
   * instances even if derived from a prototype
   */
  @Test
  public void testSingletonInheritsFromParentFactoryPrototype() throws Exception {
    DefaultListableBeanFactory parent = new DefaultListableBeanFactory();
    new XmlBeanDefinitionReader(parent).loadBeanDefinitions(PARENT_CONTEXT);
    DefaultListableBeanFactory child = new DefaultListableBeanFactory(parent);
    new XmlBeanDefinitionReader(child).loadBeanDefinitions(CHILD_CONTEXT);
    TestBean inherits = (TestBean) child.getBean("singletonInheritsFromParentFactoryPrototype");
    // Name property value is overridden
    assertTrue(inherits.getName().equals("prototype-override"));
    // Age property is inherited from bean in parent factory
    assertTrue(inherits.getAge() == 2);
    TestBean inherits2 = (TestBean) child.getBean("singletonInheritsFromParentFactoryPrototype");
    assertTrue(inherits2 == inherits);
  }

  @Test
  public void testSingletonFromParent() {
    DefaultListableBeanFactory parent = new DefaultListableBeanFactory();
    new XmlBeanDefinitionReader(parent).loadBeanDefinitions(PARENT_CONTEXT);
    TestBean beanFromParent = (TestBean) parent.getBean("inheritedTestBeanSingleton");
    DefaultListableBeanFactory child = new DefaultListableBeanFactory(parent);
    new XmlBeanDefinitionReader(child).loadBeanDefinitions(CHILD_CONTEXT);
    TestBean beanFromChild = (TestBean) child.getBean("inheritedTestBeanSingleton");
    assertTrue("singleton from parent and child is the same", beanFromParent == beanFromChild);
  }

  @Test
  public void testNestedPropertyValue() {
    DefaultListableBeanFactory parent = new DefaultListableBeanFactory();
    new XmlBeanDefinitionReader(parent).loadBeanDefinitions(PARENT_CONTEXT);
    DefaultListableBeanFactory child = new DefaultListableBeanFactory(parent);
    new XmlBeanDefinitionReader(child).loadBeanDefinitions(CHILD_CONTEXT);
    IndexedTestBean bean = (IndexedTestBean) child.getBean("indexedTestBean");
    assertEquals("name applied correctly", "myname", bean.getArray()[0].getName());
  }

  @Test
  public void testCircularReferences() {
    DefaultListableBeanFactory xbf = new DefaultListableBeanFactory();
    XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(xbf);
    reader.setValidationMode(XmlBeanDefinitionReader.VALIDATION_NONE);
    reader.loadBeanDefinitions(REFTYPES_CONTEXT);
    TestBean jenny = (TestBean) xbf.getBean("jenny");
    TestBean david = (TestBean) xbf.getBean("david");
    TestBean ego = (TestBean) xbf.getBean("ego");
    TestBean complexInnerEgo = (TestBean) xbf.getBean("complexInnerEgo");
    TestBean complexEgo = (TestBean) xbf.getBean("complexEgo");
    assertTrue("Correct circular reference", jenny.getSpouse() == david);
    assertTrue("Correct circular reference", david.getSpouse() == jenny);
    assertTrue("Correct circular reference", ego.getSpouse() == ego);
    assertTrue("Correct circular reference", complexInnerEgo.getSpouse().getSpouse() == complexInnerEgo);
    assertTrue("Correct circular reference", complexEgo.getSpouse().getSpouse() == complexEgo);
  }

  @Test
  public void testCircularReferenceWithFactoryBeanFirst() {
    DefaultListableBeanFactory xbf = new DefaultListableBeanFactory();
    XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(xbf);
    reader.setValidationMode(XmlBeanDefinitionReader.VALIDATION_NONE);
    reader.loadBeanDefinitions(REFTYPES_CONTEXT);
    xbf.getBean("egoBridge");
    TestBean complexEgo = (TestBean) xbf.getBean("complexEgo");
    assertTrue("Correct circular reference", complexEgo.getSpouse().getSpouse() == complexEgo);
  }

  @Test
  public void testCircularReferenceWithTwoFactoryBeans() {
    DefaultListableBeanFactory xbf = new DefaultListableBeanFactory();
    XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(xbf);
    reader.setValidationMode(XmlBeanDefinitionReader.VALIDATION_NONE);
    reader.loadBeanDefinitions(REFTYPES_CONTEXT);
    TestBean ego1 = (TestBean) xbf.getBean("ego1");
    assertTrue("Correct circular reference", ego1.getSpouse().getSpouse() == ego1);
    TestBean ego3 = (TestBean) xbf.getBean("ego3");
    assertTrue("Correct circular reference", ego3.getSpouse().getSpouse() == ego3);
  }

  @Test
  public void testCircularReferencesWithNotAllowed() {
    DefaultListableBeanFactory xbf = new DefaultListableBeanFactory();
    xbf.setAllowCircularReferences(false);
    XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(xbf);
    reader.setValidationMode(XmlBeanDefinitionReader.VALIDATION_NONE);
    reader.loadBeanDefinitions(REFTYPES_CONTEXT);
    try {
      xbf.getBean("jenny");
      fail("Should have thrown BeanCreationException");
    }
    catch (BeanCreationException ex) {
      assertTrue(ex.contains(BeanCurrentlyInCreationException.class));
    }
  }

  @Test
  public void testCircularReferencesWithWrapping() {
    DefaultListableBeanFactory xbf = new DefaultListableBeanFactory();
    XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(xbf);
    reader.setValidationMode(XmlBeanDefinitionReader.VALIDATION_NONE);
    reader.loadBeanDefinitions(REFTYPES_CONTEXT);
    xbf.addBeanPostProcessor(new WrappingPostProcessor());
    try {
      xbf.getBean("jenny");
      fail("Should have thrown BeanCreationException");
    }
    catch (BeanCreationException ex) {
      assertTrue(ex.contains(BeanCurrentlyInCreationException.class));
    }
  }

  @Test
  public void testCircularReferencesWithWrappingAndRawInjectionAllowed() {
    DefaultListableBeanFactory xbf = new DefaultListableBeanFactory();
    xbf.setAllowRawInjectionDespiteWrapping(true);
    XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(xbf);
    reader.setValidationMode(XmlBeanDefinitionReader.VALIDATION_NONE);
    reader.loadBeanDefinitions(REFTYPES_CONTEXT);
    xbf.addBeanPostProcessor(new WrappingPostProcessor());

    ITestBean jenny = (ITestBean) xbf.getBean("jenny");
    ITestBean david = (ITestBean) xbf.getBean("david");
    assertTrue(AopUtils.isAopProxy(jenny));
    assertTrue(AopUtils.isAopProxy(david));
    assertSame(david, jenny.getSpouse());
    assertNotSame(jenny, david.getSpouse());
    assertEquals("Jenny", david.getSpouse().getName());
    assertSame(david, david.getSpouse().getSpouse());
    assertTrue(AopUtils.isAopProxy(jenny.getSpouse()));
    assertTrue(!AopUtils.isAopProxy(david.getSpouse()));
  }

  @Test
  public void testFactoryReferenceCircle() {
    DefaultListableBeanFactory xbf = new DefaultListableBeanFactory();
    new XmlBeanDefinitionReader(xbf).loadBeanDefinitions(FACTORY_CIRCLE_CONTEXT);
    TestBean tb = (TestBean) xbf.getBean("singletonFactory");
    DummyFactory db = (DummyFactory) xbf.getBean("&singletonFactory");
    assertTrue(tb == db.getOtherTestBean());
  }

  @Test
  public void testFactoryReferenceWithDoublePrefix() {
    DefaultListableBeanFactory xbf = new DefaultListableBeanFactory();
    new XmlBeanDefinitionReader(xbf).loadBeanDefinitions(FACTORY_CIRCLE_CONTEXT);
    assertThat(xbf.getBean("&&singletonFactory"), instanceOf(DummyFactory.class));
  }

  @Test
  public void testComplexFactoryReferenceCircle() {
    DefaultListableBeanFactory xbf = new DefaultListableBeanFactory();
    new XmlBeanDefinitionReader(xbf).loadBeanDefinitions(COMPLEX_FACTORY_CIRCLE_CONTEXT);
    xbf.getBean("proxy1");
    // check that unused instances from autowiring got removed
    assertEquals(4, xbf.getSingletonCount());
    // properly create the remaining two instances
    xbf.getBean("proxy2");
    assertEquals(5, xbf.getSingletonCount());
  }

  @Test(expected = BeanCreationException.class)
  public void noSuchFactoryBeanMethod() {
    DefaultListableBeanFactory xbf = new DefaultListableBeanFactory();
    new XmlBeanDefinitionReader(xbf).loadBeanDefinitions(NO_SUCH_FACTORY_METHOD_CONTEXT);
    assertNotNull(xbf.getBean("defaultTestBean"));
  }

  @Test
  public void testInitMethodIsInvoked() throws Exception {
    DefaultListableBeanFactory xbf = new DefaultListableBeanFactory();
    new XmlBeanDefinitionReader(xbf).loadBeanDefinitions(INITIALIZERS_CONTEXT);
    DoubleInitializer in = (DoubleInitializer) xbf.getBean("init-method1");
    // Initializer should have doubled value
    assertEquals(14, in.getNum());
  }

  /**
   * Test that if a custom initializer throws an exception, it's handled correctly
   */
  @Test
  public void testInitMethodThrowsException() {
    DefaultListableBeanFactory xbf = new DefaultListableBeanFactory();
    new XmlBeanDefinitionReader(xbf).loadBeanDefinitions(INITIALIZERS_CONTEXT);
    try {
      xbf.getBean("init-method2");
      fail();
    }
    catch (BeanCreationException ex) {
      assertTrue(ex.getResourceDescription().indexOf("initializers.xml") != -1);
      assertEquals("init-method2", ex.getBeanName());
      assertTrue(ex.getCause() instanceof IOException);
    }
  }

  @Test
  public void testNoSuchInitMethod() throws Exception {
    DefaultListableBeanFactory xbf = new DefaultListableBeanFactory();
    new XmlBeanDefinitionReader(xbf).loadBeanDefinitions(INITIALIZERS_CONTEXT);
    try {
      xbf.getBean("init-method3");
      fail();
    }
    catch (FatalBeanException ex) {
      // check message is helpful
      assertTrue(ex.getMessage().indexOf("initializers.xml") != -1);
      assertTrue(ex.getMessage().indexOf("init-method3") != -1);
      assertTrue(ex.getMessage().indexOf("init") != -1);
    }
  }

  /**
   * Check that InitializingBean method is called first.
   */
  @Test
  public void testInitializingBeanAndInitMethod() throws Exception {
    InitAndIB.constructed = false;
    DefaultListableBeanFactory xbf = new DefaultListableBeanFactory();
    new XmlBeanDefinitionReader(xbf).loadBeanDefinitions(INITIALIZERS_CONTEXT);
    assertFalse(InitAndIB.constructed);
    xbf.preInstantiateSingletons();
    assertFalse(InitAndIB.constructed);
    InitAndIB iib = (InitAndIB) xbf.getBean("init-and-ib");
    assertTrue(InitAndIB.constructed);
    assertTrue(iib.afterPropertiesSetInvoked && iib.initMethodInvoked);
    assertTrue(!iib.destroyed && !iib.customDestroyed);
    xbf.destroySingletons();
    assertTrue(iib.destroyed && iib.customDestroyed);
    xbf.destroySingletons();
    assertTrue(iib.destroyed && iib.customDestroyed);
  }

  /**
   * Check that InitializingBean method is not called twice.
   */
  @Test
  public void testInitializingBeanAndSameInitMethod() throws Exception {
    InitAndIB.constructed = false;
    DefaultListableBeanFactory xbf = new DefaultListableBeanFactory();
    new XmlBeanDefinitionReader(xbf).loadBeanDefinitions(INITIALIZERS_CONTEXT);
    assertFalse(InitAndIB.constructed);
    xbf.preInstantiateSingletons();
    assertFalse(InitAndIB.constructed);
    InitAndIB iib = (InitAndIB) xbf.getBean("ib-same-init");
    assertTrue(InitAndIB.constructed);
    assertTrue(iib.afterPropertiesSetInvoked && !iib.initMethodInvoked);
    assertTrue(!iib.destroyed && !iib.customDestroyed);
    xbf.destroySingletons();
    assertTrue(iib.destroyed && !iib.customDestroyed);
    xbf.destroySingletons();
    assertTrue(iib.destroyed && !iib.customDestroyed);
  }

  @Test
  public void testDefaultLazyInit() throws Exception {
    InitAndIB.constructed = false;
    DefaultListableBeanFactory xbf = new DefaultListableBeanFactory();
    new XmlBeanDefinitionReader(xbf).loadBeanDefinitions(DEFAULT_LAZY_CONTEXT);
    assertFalse(InitAndIB.constructed);
    xbf.preInstantiateSingletons();
    assertTrue(InitAndIB.constructed);
    try {
      xbf.getBean("lazy-and-bad");
    }
    catch (BeanCreationException ex) {
      assertTrue(ex.getCause() instanceof IOException);
    }
  }

  @Test(expected = BeanDefinitionStoreException.class)
  public void noSuchXmlFile() throws Exception {
    DefaultListableBeanFactory xbf = new DefaultListableBeanFactory();
    new XmlBeanDefinitionReader(xbf).loadBeanDefinitions(MISSING_CONTEXT);
  }

  @Test(expected = BeanDefinitionStoreException.class)
  public void invalidXmlFile() throws Exception {
    DefaultListableBeanFactory xbf = new DefaultListableBeanFactory();
    new XmlBeanDefinitionReader(xbf).loadBeanDefinitions(INVALID_CONTEXT);
  }

  @Test(expected = UnsatisfiedDependencyException.class)
  public void unsatisfiedObjectDependencyCheck() throws Exception {
    DefaultListableBeanFactory xbf = new DefaultListableBeanFactory();
    new XmlBeanDefinitionReader(xbf).loadBeanDefinitions(UNSATISFIED_OBJECT_DEP_CONTEXT);
    xbf.getBean("a", DependenciesBean.class);
  }

  @Test(expected = UnsatisfiedDependencyException.class)
  public void unsatisfiedSimpleDependencyCheck() throws Exception {
    DefaultListableBeanFactory xbf = new DefaultListableBeanFactory();
    new XmlBeanDefinitionReader(xbf).loadBeanDefinitions(UNSATISFIED_SIMPLE_DEP_CONTEXT);
    xbf.getBean("a", DependenciesBean.class);
  }

  @Test
  public void testSatisfiedObjectDependencyCheck() throws Exception {
    DefaultListableBeanFactory xbf = new DefaultListableBeanFactory();
    new XmlBeanDefinitionReader(xbf).loadBeanDefinitions(SATISFIED_OBJECT_DEP_CONTEXT);
    DependenciesBean a = (DependenciesBean) xbf.getBean("a");
    assertNotNull(a.getSpouse());
    assertEquals(xbf, a.getBeanFactory());
  }

  @Test
  public void testSatisfiedSimpleDependencyCheck() throws Exception {
    DefaultListableBeanFactory xbf = new DefaultListableBeanFactory();
    new XmlBeanDefinitionReader(xbf).loadBeanDefinitions(SATISFIED_SIMPLE_DEP_CONTEXT);
    DependenciesBean a = (DependenciesBean) xbf.getBean("a");
    assertEquals(a.getAge(), 33);
  }

  @Test(expected = UnsatisfiedDependencyException.class)
  public void unsatisfiedAllDependencyCheck() throws Exception {
    DefaultListableBeanFactory xbf = new DefaultListableBeanFactory();
    new XmlBeanDefinitionReader(xbf).loadBeanDefinitions(UNSATISFIED_ALL_DEP_CONTEXT);
    xbf.getBean("a", DependenciesBean.class);
  }

  @Test
  public void testSatisfiedAllDependencyCheck() throws Exception {
    DefaultListableBeanFactory xbf = new DefaultListableBeanFactory();
    new XmlBeanDefinitionReader(xbf).loadBeanDefinitions(SATISFIED_ALL_DEP_CONTEXT);
    DependenciesBean a = (DependenciesBean) xbf.getBean("a");
    assertEquals(a.getAge(), 33);
    assertNotNull(a.getName());
    assertNotNull(a.getSpouse());
  }

  @Test
  public void testAutowire() throws Exception {
    DefaultListableBeanFactory xbf = new DefaultListableBeanFactory();
    new XmlBeanDefinitionReader(xbf).loadBeanDefinitions(AUTOWIRE_CONTEXT);
    TestBean spouse = new TestBean("kerry", 0);
    xbf.registerSingleton("spouse", spouse);
    doTestAutowire(xbf);
  }

  @Test
  public void testAutowireWithParent() throws Exception {
    DefaultListableBeanFactory xbf = new DefaultListableBeanFactory();
    new XmlBeanDefinitionReader(xbf).loadBeanDefinitions(AUTOWIRE_CONTEXT);
    DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
    MutablePropertyValues pvs = new MutablePropertyValues();
    pvs.add("name", "kerry");
    RootBeanDefinition bd = new RootBeanDefinition(TestBean.class);
    bd.setPropertyValues(pvs);
    lbf.registerBeanDefinition("spouse", bd);
    xbf.setParentBeanFactory(lbf);
    doTestAutowire(xbf);
  }

  private void doTestAutowire(DefaultListableBeanFactory xbf) throws Exception {
    DependenciesBean rod1 = (DependenciesBean) xbf.getBean("rod1");
    TestBean kerry = (TestBean) xbf.getBean("spouse");
    // should have been autowired
    assertEquals(kerry, rod1.getSpouse());

    DependenciesBean rod1a = (DependenciesBean) xbf.getBean("rod1a");
    // should have been autowired
    assertEquals(kerry, rod1a.getSpouse());

    DependenciesBean rod2 = (DependenciesBean) xbf.getBean("rod2");
    // should have been autowired
    assertEquals(kerry, rod2.getSpouse());

    DependenciesBean rod2a = (DependenciesBean) xbf.getBean("rod2a");
    // should have been set explicitly
    assertEquals(kerry, rod2a.getSpouse());

    ConstructorDependenciesBean rod3 = (ConstructorDependenciesBean) xbf.getBean("rod3");
    IndexedTestBean other = (IndexedTestBean) xbf.getBean("other");
    // should have been autowired
    assertEquals(kerry, rod3.getSpouse1());
    assertEquals(kerry, rod3.getSpouse2());
    assertEquals(other, rod3.getOther());

    ConstructorDependenciesBean rod3a = (ConstructorDependenciesBean) xbf.getBean("rod3a");
    // should have been autowired
    assertEquals(kerry, rod3a.getSpouse1());
    assertEquals(kerry, rod3a.getSpouse2());
    assertEquals(other, rod3a.getOther());

    try {
      xbf.getBean("rod4", ConstructorDependenciesBean.class);
      fail("Must have thrown a FatalBeanException");
    }
    catch (FatalBeanException expected) {
      // expected
    }

    DependenciesBean rod5 = (DependenciesBean) xbf.getBean("rod5");
    // Should not have been autowired
    assertNull(rod5.getSpouse());

    BeanFactory appCtx = (BeanFactory) xbf.getBean("childAppCtx");
    assertTrue(appCtx.containsBean("rod1"));
    assertTrue(appCtx.containsBean("jenny"));
  }

  @Test
  public void testAutowireWithDefault() throws Exception {
    DefaultListableBeanFactory xbf = new DefaultListableBeanFactory();
    new XmlBeanDefinitionReader(xbf).loadBeanDefinitions(DEFAULT_AUTOWIRE_CONTEXT);

    DependenciesBean rod1 = (DependenciesBean) xbf.getBean("rod1");
    // should have been autowired
    assertNotNull(rod1.getSpouse());
    assertTrue(rod1.getSpouse().getName().equals("Kerry"));

    DependenciesBean rod2 = (DependenciesBean) xbf.getBean("rod2");
    // should have been autowired
    assertNotNull(rod2.getSpouse());
    assertTrue(rod2.getSpouse().getName().equals("Kerry"));

    try {
      xbf.getBean("rod3", DependenciesBean.class);
      fail("Must have thrown UnsatisfiedDependencyException");
    }
    catch (UnsatisfiedDependencyException expected) {
    }
  }

  @Test
  public void testAutowireByConstructor() throws Exception {
    DefaultListableBeanFactory xbf = new DefaultListableBeanFactory();
    new XmlBeanDefinitionReader(xbf).loadBeanDefinitions(CONSTRUCTOR_ARG_CONTEXT);
    ConstructorDependenciesBean rod1 = (ConstructorDependenciesBean) xbf.getBean("rod1");
    TestBean kerry = (TestBean) xbf.getBean("kerry2");
    // should have been autowired
    assertEquals(kerry, rod1.getSpouse1());
    assertEquals(0, rod1.getAge());
    assertEquals(null, rod1.getName());

    ConstructorDependenciesBean rod2 = (ConstructorDependenciesBean) xbf.getBean("rod2");
    TestBean kerry1 = (TestBean) xbf.getBean("kerry1");
    TestBean kerry2 = (TestBean) xbf.getBean("kerry2");
    // should have been autowired
    assertEquals(kerry2, rod2.getSpouse1());
    assertEquals(kerry1, rod2.getSpouse2());
    assertEquals(0, rod2.getAge());
    assertEquals(null, rod2.getName());

    ConstructorDependenciesBean rod = (ConstructorDependenciesBean) xbf.getBean("rod3");
    IndexedTestBean other = (IndexedTestBean) xbf.getBean("other");
    // should have been autowired
    assertEquals(kerry, rod.getSpouse1());
    assertEquals(kerry, rod.getSpouse2());
    assertEquals(other, rod.getOther());
    assertEquals(0, rod.getAge());
    assertEquals(null, rod.getName());

    xbf.getBean("rod4", ConstructorDependenciesBean.class);
    // should have been autowired
    assertEquals(kerry, rod.getSpouse1());
    assertEquals(kerry, rod.getSpouse2());
    assertEquals(other, rod.getOther());
    assertEquals(0, rod.getAge());
    assertEquals(null, rod.getName());
  }

  @Test
  public void testAutowireByConstructorWithSimpleValues() throws Exception {
    DefaultListableBeanFactory xbf = new DefaultListableBeanFactory();
    new XmlBeanDefinitionReader(xbf).loadBeanDefinitions(CONSTRUCTOR_ARG_CONTEXT);

    ConstructorDependenciesBean rod5 = (ConstructorDependenciesBean) xbf.getBean("rod5");
    TestBean kerry1 = (TestBean) xbf.getBean("kerry1");
    TestBean kerry2 = (TestBean) xbf.getBean("kerry2");
    IndexedTestBean other = (IndexedTestBean) xbf.getBean("other");
    // should have been autowired
    assertEquals(kerry2, rod5.getSpouse1());
    assertEquals(kerry1, rod5.getSpouse2());
    assertEquals(other, rod5.getOther());
    assertEquals(99, rod5.getAge());
    assertEquals("myname", rod5.getName());

    DerivedConstructorDependenciesBean rod6 = (DerivedConstructorDependenciesBean) xbf.getBean("rod6");
    // should have been autowired
    assertTrue(rod6.initialized);
    assertTrue(!rod6.destroyed);
    assertEquals(kerry2, rod6.getSpouse1());
    assertEquals(kerry1, rod6.getSpouse2());
    assertEquals(other, rod6.getOther());
    assertEquals(0, rod6.getAge());
    assertEquals(null, rod6.getName());

    xbf.destroySingletons();
    assertTrue(rod6.destroyed);
  }

  @Test
  public void testRelatedCausesFromConstructorResolution() {
    DefaultListableBeanFactory xbf = new DefaultListableBeanFactory();
    new XmlBeanDefinitionReader(xbf).loadBeanDefinitions(CONSTRUCTOR_ARG_CONTEXT);

    try {
      xbf.getBean("rod2Accessor");
    }
    catch (BeanCreationException ex) {
      assertTrue(ex.toString().indexOf("touchy") != -1);
      ex.printStackTrace();
      assertNull(ex.getRelatedCauses());
    }
  }

  @Test
  public void testConstructorArgResolution() {
    DefaultListableBeanFactory xbf = new DefaultListableBeanFactory();
    new XmlBeanDefinitionReader(xbf).loadBeanDefinitions(CONSTRUCTOR_ARG_CONTEXT);
    TestBean kerry1 = (TestBean) xbf.getBean("kerry1");
    TestBean kerry2 = (TestBean) xbf.getBean("kerry2");

    ConstructorDependenciesBean rod9 = (ConstructorDependenciesBean) xbf.getBean("rod9");
    assertEquals(99, rod9.getAge());
    ConstructorDependenciesBean rod9a = (ConstructorDependenciesBean) xbf.getBean("rod9", 98);
    assertEquals(98, rod9a.getAge());
    ConstructorDependenciesBean rod9b = (ConstructorDependenciesBean) xbf.getBean("rod9", "myName");
    assertEquals("myName", rod9b.getName());
    ConstructorDependenciesBean rod9c = (ConstructorDependenciesBean) xbf.getBean("rod9", 97);
    assertEquals(97, rod9c.getAge());

    ConstructorDependenciesBean rod10 = (ConstructorDependenciesBean) xbf.getBean("rod10");
    assertEquals(null, rod10.getName());

    ConstructorDependenciesBean rod11 = (ConstructorDependenciesBean) xbf.getBean("rod11");
    assertEquals(kerry2, rod11.getSpouse1());

    ConstructorDependenciesBean rod12 = (ConstructorDependenciesBean) xbf.getBean("rod12");
    assertEquals(kerry1, rod12.getSpouse1());
    assertNull(rod12.getSpouse2());

    ConstructorDependenciesBean rod13 = (ConstructorDependenciesBean) xbf.getBean("rod13");
    assertEquals(kerry1, rod13.getSpouse1());
    assertEquals(kerry2, rod13.getSpouse2());

    ConstructorDependenciesBean rod14 = (ConstructorDependenciesBean) xbf.getBean("rod14");
    assertEquals(kerry1, rod14.getSpouse1());
    assertEquals(kerry2, rod14.getSpouse2());

    ConstructorDependenciesBean rod15 = (ConstructorDependenciesBean) xbf.getBean("rod15");
    assertEquals(kerry2, rod15.getSpouse1());
    assertEquals(kerry1, rod15.getSpouse2());

    ConstructorDependenciesBean rod16 = (ConstructorDependenciesBean) xbf.getBean("rod16");
    assertEquals(kerry2, rod16.getSpouse1());
    assertEquals(kerry1, rod16.getSpouse2());
    assertEquals(29, rod16.getAge());

    ConstructorDependenciesBean rod17 = (ConstructorDependenciesBean) xbf.getBean("rod17");
    assertEquals(kerry1, rod17.getSpouse1());
    assertEquals(kerry2, rod17.getSpouse2());
    assertEquals(29, rod17.getAge());
  }

  @Test
  public void testPrototypeWithExplicitArguments() {
    DefaultListableBeanFactory xbf = new DefaultListableBeanFactory();
    new XmlBeanDefinitionReader(xbf).loadBeanDefinitions(CONSTRUCTOR_ARG_CONTEXT);
    SimpleConstructorArgBean cd1 = (SimpleConstructorArgBean) xbf.getBean("rod18");
    assertEquals(0, cd1.getAge());
    SimpleConstructorArgBean cd2 = (SimpleConstructorArgBean) xbf.getBean("rod18", 98);
    assertEquals(98, cd2.getAge());
    SimpleConstructorArgBean cd3 = (SimpleConstructorArgBean) xbf.getBean("rod18", "myName");
    assertEquals("myName", cd3.getName());
    SimpleConstructorArgBean cd4 = (SimpleConstructorArgBean) xbf.getBean("rod18");
    assertEquals(0, cd4.getAge());
    SimpleConstructorArgBean cd5 = (SimpleConstructorArgBean) xbf.getBean("rod18", 97);
    assertEquals(97, cd5.getAge());
  }

  @Test
  public void testConstructorArgWithSingleMatch() {
    DefaultListableBeanFactory xbf = new DefaultListableBeanFactory();
    new XmlBeanDefinitionReader(xbf).loadBeanDefinitions(CONSTRUCTOR_ARG_CONTEXT);
    File file = (File) xbf.getBean("file");
    assertEquals(File.separator + "test", file.getPath());
  }

  @Test(expected = BeanCreationException.class)
  public void throwsExceptionOnTooManyArguments() throws Exception {
    DefaultListableBeanFactory xbf = new DefaultListableBeanFactory();
    new XmlBeanDefinitionReader(xbf).loadBeanDefinitions(CONSTRUCTOR_ARG_CONTEXT);
    xbf.getBean("rod7", ConstructorDependenciesBean.class);
  }

  @Test(expected = UnsatisfiedDependencyException.class)
  public void throwsExceptionOnAmbiguousResolution() throws Exception {
    DefaultListableBeanFactory xbf = new DefaultListableBeanFactory();
    new XmlBeanDefinitionReader(xbf).loadBeanDefinitions(CONSTRUCTOR_ARG_CONTEXT);
    xbf.getBean("rod8", ConstructorDependenciesBean.class);
  }

  @Test
  public void testDependsOn() {
    doTestDependencies(DEP_DEPENDSON_CONTEXT, 1);
  }

  @Test
  public void testDependsOnInInnerBean() {
    doTestDependencies(DEP_DEPENDSON_INNER_CONTEXT, 4);
  }

  @Test
  public void testDependenciesThroughConstructorArguments() {
    doTestDependencies(DEP_CARG_CONTEXT, 1);
  }

  @Test
  public void testDependenciesThroughConstructorArgumentAutowiring() {
    doTestDependencies(DEP_CARG_AUTOWIRE_CONTEXT, 1);
  }

  @Test
  public void testDependenciesThroughConstructorArgumentsInInnerBean() {
    doTestDependencies(DEP_CARG_INNER_CONTEXT, 1);
  }

  @Test
  public void testDependenciesThroughProperties() {
    doTestDependencies(DEP_PROP, 1);
  }

  @Test
  public void testDependenciesThroughPropertiesWithInTheMiddle() {
    doTestDependencies(DEP_PROP_MIDDLE_CONTEXT, 1);
  }

  @Test
  public void testDependenciesThroughPropertyAutowiringByName() {
    doTestDependencies(DEP_PROP_ABN_CONTEXT, 1);
  }

  @Test
  public void testDependenciesThroughPropertyAutowiringByType() {
    doTestDependencies(DEP_PROP_ABT_CONTEXT, 1);
  }

  @Test
  public void testDependenciesThroughPropertiesInInnerBean() {
    doTestDependencies(DEP_PROP_INNER_CONTEXT, 1);
  }

  private void doTestDependencies(ClassPathResource resource, int nrOfHoldingBeans) {
    PreparingBean1.prepared = false;
    PreparingBean1.destroyed = false;
    PreparingBean2.prepared = false;
    PreparingBean2.destroyed = false;
    DependingBean.destroyCount = 0;
    HoldingBean.destroyCount = 0;
    DefaultListableBeanFactory xbf = new DefaultListableBeanFactory();
    new XmlBeanDefinitionReader(xbf).loadBeanDefinitions(resource);
    xbf.preInstantiateSingletons();
    xbf.destroySingletons();
    assertTrue(PreparingBean1.prepared);
    assertTrue(PreparingBean1.destroyed);
    assertTrue(PreparingBean2.prepared);
    assertTrue(PreparingBean2.destroyed);
    assertEquals(nrOfHoldingBeans, DependingBean.destroyCount);
    if (!xbf.getBeansOfType(HoldingBean.class, false, false).isEmpty()) {
      assertEquals(nrOfHoldingBeans, HoldingBean.destroyCount);
    }
  }

  /**
   * When using a BeanFactory. singletons are of course not pre-instantiated.
   * So rubbish class names in bean defs must now not be 'resolved' when the
   * bean def is being parsed, 'cos everything on a bean def is now lazy, but
   * must rather only be picked up when the bean is instantiated.
   */
  @Test
  public void testClassNotFoundWithDefaultBeanClassLoader() {
    DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
    new XmlBeanDefinitionReader(factory).loadBeanDefinitions(CLASS_NOT_FOUND_CONTEXT);
    // cool, no errors, so the rubbish class name in the bean def was not resolved
    try {
      // let's resolve the bean definition; must blow up
      factory.getBean("classNotFound");
      fail("Must have thrown a CannotLoadBeanClassException");
    }
    catch (CannotLoadBeanClassException ex) {
      assertTrue(ex.getResourceDescription().indexOf("classNotFound.xml") != -1);
      assertTrue(ex.getCause() instanceof ClassNotFoundException);
    }
  }

  @Test
  public void testClassNotFoundWithNoBeanClassLoader() {
    DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
    XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(bf);
    reader.setBeanClassLoader(null);
    reader.loadBeanDefinitions(CLASS_NOT_FOUND_CONTEXT);
    assertEquals("WhatALotOfRubbish", bf.getBeanDefinition("classNotFound").getBeanClassName());
  }

  @Test
  public void testResourceAndInputStream() throws IOException {
    DefaultListableBeanFactory xbf = new DefaultListableBeanFactory();
    new XmlBeanDefinitionReader(xbf).loadBeanDefinitions(RESOURCE_CONTEXT);
    // comes from "resourceImport.xml"
    ResourceTestBean resource1 = (ResourceTestBean) xbf.getBean("resource1");
    // comes from "resource.xml"
    ResourceTestBean resource2 = (ResourceTestBean) xbf.getBean("resource2");

    assertTrue(resource1.getResource() instanceof ClassPathResource);
    StringWriter writer = new StringWriter();
    FileCopyUtils.copy(new InputStreamReader(resource1.getResource().getInputStream()), writer);
    assertEquals("test", writer.toString());
    writer = new StringWriter();
    FileCopyUtils.copy(new InputStreamReader(resource1.getInputStream()), writer);
    assertEquals("test", writer.toString());
    writer = new StringWriter();
    FileCopyUtils.copy(new InputStreamReader(resource2.getResource().getInputStream()), writer);
    assertEquals("test", writer.toString());
    writer = new StringWriter();
    FileCopyUtils.copy(new InputStreamReader(resource2.getInputStream()), writer);
    assertEquals("test", writer.toString());
  }

  @Test
  public void testClassPathResourceWithImport() {
    DefaultListableBeanFactory xbf = new DefaultListableBeanFactory();
    new XmlBeanDefinitionReader(xbf).loadBeanDefinitions(RESOURCE_CONTEXT);
    // comes from "resourceImport.xml"
    xbf.getBean("resource1", ResourceTestBean.class);
    // comes from "resource.xml"
    xbf.getBean("resource2", ResourceTestBean.class);
  }

  @Test
  public void testUrlResourceWithImport() {
    URL url = getClass().getResource(RESOURCE_CONTEXT.getPath());
    DefaultListableBeanFactory xbf = new DefaultListableBeanFactory();
    new XmlBeanDefinitionReader(xbf).loadBeanDefinitions(new UrlResource(url));
    // comes from "resourceImport.xml"
    xbf.getBean("resource1", ResourceTestBean.class);
    // comes from "resource.xml"
    xbf.getBean("resource2", ResourceTestBean.class);
  }

  @Test
  public void testFileSystemResourceWithImport() throws URISyntaxException {
    String file = getClass().getResource(RESOURCE_CONTEXT.getPath()).toURI().getPath();
    DefaultListableBeanFactory xbf = new DefaultListableBeanFactory();
    new XmlBeanDefinitionReader(xbf).loadBeanDefinitions(new FileSystemResource(file));
    // comes from "resourceImport.xml"
    xbf.getBean("resource1", ResourceTestBean.class);
    // comes from "resource.xml"
    xbf.getBean("resource2", ResourceTestBean.class);
  }

  @Test(expected = BeanDefinitionStoreException.class)
  public void recursiveImport() {
    DefaultListableBeanFactory xbf = new DefaultListableBeanFactory();
    new XmlBeanDefinitionReader(xbf).loadBeanDefinitions(RECURSIVE_IMPORT_CONTEXT);
  }

  /**
   * @since 3.2.8 and 4.0.2
   * @see <a href="https://jira.spring.io/browse/SPR-10785">SPR-10785</a> and <a
   *      href="https://jira.spring.io/browse/SPR-11420">SPR-11420</a>
   */
  @Test
  public void methodInjectedBeanMustBeOfSameEnhancedCglibSubclassTypeAcrossBeanFactories() {
    Class<?> firstClass = null;

    for (int i = 0; i < 10; i++) {
      DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
      new XmlBeanDefinitionReader(bf).loadBeanDefinitions(OVERRIDES_CONTEXT);

      final Class<?> currentClass = bf.getBean("overrideOneMethod").getClass();
      assertTrue("Method injected bean class [" + currentClass + "] must be a CGLIB enhanced subclass.",
        ClassUtils.isCglibProxyClass(currentClass));

      if (firstClass == null) {
        firstClass = currentClass;
      }
      else {
        assertEquals(firstClass, currentClass);
      }
    }
  }

  @Test
  public void lookupOverrideMethodsWithSetterInjection() {
    DefaultListableBeanFactory xbf = new DefaultListableBeanFactory();
    XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(xbf);
    reader.loadBeanDefinitions(OVERRIDES_CONTEXT);

    lookupOverrideMethodsWithSetterInjection(xbf, "overrideOneMethod", true);
    // Should work identically on subclass definition, in which lookup
    // methods are inherited
    lookupOverrideMethodsWithSetterInjection(xbf, "overrideInheritedMethod", true);

    // Check cost of repeated construction of beans with method overrides
    // Will pick up misuse of CGLIB
    int howMany = 100;
    StopWatch sw = new StopWatch();
    sw.start("Look up " + howMany + " prototype bean instances with method overrides");
    for (int i = 0; i < howMany; i++) {
      lookupOverrideMethodsWithSetterInjection(xbf, "overrideOnPrototype", false);
    }
    sw.stop();
    // System.out.println(sw);
    if (!LogFactory.getLog(DefaultListableBeanFactory.class).isDebugEnabled()) {
      assertTrue(sw.getTotalTimeMillis() < 2000);
    }

    // Now test distinct bean with swapped value in factory, to ensure the two are independent
    OverrideOneMethod swappedOom = (OverrideOneMethod) xbf.getBean("overrideOneMethodSwappedReturnValues");

    TestBean tb = swappedOom.getPrototypeDependency();
    assertEquals("David", tb.getName());
    tb = swappedOom.protectedOverrideSingleton();
    assertEquals("Jenny", tb.getName());
  }

  private void lookupOverrideMethodsWithSetterInjection(BeanFactory xbf,
      String beanName, boolean singleton) {
    OverrideOneMethod oom = (OverrideOneMethod) xbf.getBean(beanName);

    if (singleton) {
      assertSame(oom, xbf.getBean(beanName));
    }
    else {
      assertNotSame(oom, xbf.getBean(beanName));
    }

    TestBean jenny1 = oom.getPrototypeDependency();
    assertEquals("Jenny", jenny1.getName());
    TestBean jenny2 = oom.getPrototypeDependency();
    assertEquals("Jenny", jenny2.getName());
    assertNotSame(jenny1, jenny2);

    // Check that the bean can invoke the overridden method on itself
    // This differs from Spring's AOP support, which has a distinct notion
    // of a "target" object, meaning that the target needs explicit knowledge
    // of AOP proxying to invoke an advised method on itself.
    TestBean jenny3 = oom.invokesOverriddenMethodOnSelf();
    assertEquals("Jenny", jenny3.getName());
    assertNotSame(jenny1, jenny3);

    // Now try protected method, and singleton
    TestBean dave1 = oom.protectedOverrideSingleton();
    assertEquals("David", dave1.getName());
    TestBean dave2 = oom.protectedOverrideSingleton();
    assertEquals("David", dave2.getName());
    assertSame(dave1, dave2);
  }

  @Test
  public void testReplaceMethodOverrideWithSetterInjection() {
    DefaultListableBeanFactory xbf = new DefaultListableBeanFactory();
    XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(xbf);
    reader.loadBeanDefinitions(DELEGATION_OVERRIDES_CONTEXT);

    OverrideOneMethod oom = (OverrideOneMethod) xbf.getBean("overrideOneMethod");

    // Same contract as for overrides.xml
    TestBean jenny1 = oom.getPrototypeDependency();
    assertEquals("Jenny", jenny1.getName());
    TestBean jenny2 = oom.getPrototypeDependency();
    assertEquals("Jenny", jenny2.getName());
    assertNotSame(jenny1, jenny2);

    TestBean notJenny = oom.getPrototypeDependency("someParam");
    assertTrue(!"Jenny".equals(notJenny.getName()));

    // Now try protected method, and singleton
    TestBean dave1 = oom.protectedOverrideSingleton();
    assertEquals("David", dave1.getName());
    TestBean dave2 = oom.protectedOverrideSingleton();
    assertEquals("David", dave2.getName());
    assertSame(dave1, dave2);

    // Check unadvised behaviour
    String str = "woierowijeiowiej";
    assertEquals(str, oom.echo(str));

    // Now test replace
    String s = "this is not a palindrome";
    String reverse = new StringBuffer(s).reverse().toString();
    assertEquals("Should have overridden to reverse, not echo", reverse, oom.replaceMe(s));

    assertEquals("Should have overridden no-arg overloaded replaceMe method to return fixed value",
        FixedMethodReplacer.VALUE, oom.replaceMe());

    OverrideOneMethodSubclass ooms = (OverrideOneMethodSubclass) xbf.getBean("replaceVoidMethod");
    DoSomethingReplacer dos = (DoSomethingReplacer) xbf.getBean("doSomethingReplacer");
    assertEquals(null, dos.lastArg);
    String s1 = "";
    String s2 = "foo bar black sheep";
    ooms.doSomething(s1);
    assertEquals(s1, dos.lastArg);
    ooms.doSomething(s2);
    assertEquals(s2, dos.lastArg);
  }

  @Test
  public void lookupOverrideOneMethodWithConstructorInjection() {
    DefaultListableBeanFactory xbf = new DefaultListableBeanFactory();
    XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(xbf);
    reader.loadBeanDefinitions(CONSTRUCTOR_OVERRIDES_CONTEXT);

    ConstructorInjectedOverrides cio = (ConstructorInjectedOverrides) xbf.getBean("constructorOverrides");

    // Check that the setter was invoked...
    // We should be able to combine Constructor and
    // Setter Injection
    assertEquals("Setter string was set", "from property element", cio.getSetterString());

    // Jenny is a singleton
    TestBean jenny = (TestBean) xbf.getBean("jenny");
    assertSame(jenny, cio.getTestBean());
    assertSame(jenny, cio.getTestBean());
    FactoryMethods fm1 = cio.createFactoryMethods();
    FactoryMethods fm2 = cio.createFactoryMethods();
    assertNotSame("FactoryMethods reference is to a prototype", fm1, fm2);
    assertSame("The two prototypes hold the same singleton reference",
        fm1.getTestBean(), fm2.getTestBean());
  }

  @Test
  public void testRejectsOverrideOfBogusMethodName() {
    DefaultListableBeanFactory xbf = new DefaultListableBeanFactory();
    XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(xbf);
    try {
      reader.loadBeanDefinitions(INVALID_NO_SUCH_METHOD_CONTEXT);
      xbf.getBean("constructorOverrides");
      fail("Shouldn't allow override of bogus method");
    }
    catch (BeanDefinitionStoreException ex) {
      // Check that the bogus method name was included in the error message
      assertTrue("Bogus method name correctly reported", ex.getMessage().indexOf("bogusMethod") != -1);
    }
  }

  @Test
  public void serializableMethodReplacerAndSuperclass() throws Exception {
    DefaultListableBeanFactory xbf = new DefaultListableBeanFactory();
    XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(xbf);
    reader.loadBeanDefinitions(DELEGATION_OVERRIDES_CONTEXT);
    SerializableMethodReplacerCandidate s = (SerializableMethodReplacerCandidate) xbf.getBean("serializableReplacer");
    String forwards = "this is forwards";
    String backwards = new StringBuffer(forwards).reverse().toString();
    assertEquals(backwards, s.replaceMe(forwards));
    // SPR-356: lookup methods & method replacers are not serializable.
    assertFalse(
        "Lookup methods and method replacers are not meant to be serializable.",
        SerializationTestUtils.isSerializable(s));
  }

  @Test
  public void testInnerBeanInheritsScopeFromConcreteChildDefinition() {
    DefaultListableBeanFactory xbf = new DefaultListableBeanFactory();
    XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(xbf);
    reader.loadBeanDefinitions(OVERRIDES_CONTEXT);
    TestBean jenny = (TestBean) xbf.getBean("jennyChild");
    assertEquals(1, jenny.getFriends().size());
    assertTrue(jenny.getFriends().iterator().next() instanceof TestBean);
  }

  @Test
  public void testConstructorArgWithSingleSimpleTypeMatch() {
    DefaultListableBeanFactory xbf = new DefaultListableBeanFactory();
    new XmlBeanDefinitionReader(xbf).loadBeanDefinitions(CONSTRUCTOR_ARG_CONTEXT);

    SingleSimpleTypeConstructorBean bean = (SingleSimpleTypeConstructorBean) xbf.getBean("beanWithBoolean");
    assertTrue(bean.isSingleBoolean());

    SingleSimpleTypeConstructorBean bean2 = (SingleSimpleTypeConstructorBean) xbf.getBean("beanWithBoolean2");
    assertTrue(bean2.isSingleBoolean());
  }

  @Test
  public void testConstructorArgWithDoubleSimpleTypeMatch() {
    DefaultListableBeanFactory xbf = new DefaultListableBeanFactory();
    new XmlBeanDefinitionReader(xbf).loadBeanDefinitions(CONSTRUCTOR_ARG_CONTEXT);

    SingleSimpleTypeConstructorBean bean = (SingleSimpleTypeConstructorBean) xbf.getBean("beanWithBooleanAndString");
    assertTrue(bean.isSecondBoolean());
    assertEquals("A String", bean.getTestString());

    SingleSimpleTypeConstructorBean bean2 = (SingleSimpleTypeConstructorBean) xbf.getBean("beanWithBooleanAndString2");
    assertTrue(bean2.isSecondBoolean());
    assertEquals("A String", bean2.getTestString());
  }

  @Test
  public void testDoubleBooleanAutowire() {
    DefaultListableBeanFactory xbf = new DefaultListableBeanFactory();
    new XmlBeanDefinitionReader(xbf).loadBeanDefinitions(CONSTRUCTOR_ARG_CONTEXT);
    DoubleBooleanConstructorBean bean = (DoubleBooleanConstructorBean) xbf.getBean("beanWithDoubleBoolean");
    assertEquals(Boolean.TRUE, bean.boolean1);
    assertEquals(Boolean.FALSE, bean.boolean2);
  }

  @Test
  public void testDoubleBooleanAutowireWithIndex() {
    DefaultListableBeanFactory xbf = new DefaultListableBeanFactory();
    new XmlBeanDefinitionReader(xbf).loadBeanDefinitions(CONSTRUCTOR_ARG_CONTEXT);
    DoubleBooleanConstructorBean bean = (DoubleBooleanConstructorBean) xbf.getBean("beanWithDoubleBooleanAndIndex");
    assertEquals(Boolean.FALSE, bean.boolean1);
    assertEquals(Boolean.TRUE, bean.boolean2);
  }

  @Test
  public void testLenientDependencyMatching() {
    DefaultListableBeanFactory xbf = new DefaultListableBeanFactory();
    new XmlBeanDefinitionReader(xbf).loadBeanDefinitions(CONSTRUCTOR_ARG_CONTEXT);
    LenientDependencyTestBean bean = (LenientDependencyTestBean) xbf.getBean("lenientDependencyTestBean");
    assertTrue(bean.tb instanceof DerivedTestBean);
  }

  @Test
  public void testLenientDependencyMatchingFactoryMethod() {
    DefaultListableBeanFactory xbf = new DefaultListableBeanFactory();
    new XmlBeanDefinitionReader(xbf).loadBeanDefinitions(CONSTRUCTOR_ARG_CONTEXT);
    LenientDependencyTestBean bean = (LenientDependencyTestBean) xbf.getBean("lenientDependencyTestBeanFactoryMethod");
    assertTrue(bean.tb instanceof DerivedTestBean);
  }

  @Test
  public void testNonLenientDependencyMatching() {
    DefaultListableBeanFactory xbf = new DefaultListableBeanFactory();
    new XmlBeanDefinitionReader(xbf).loadBeanDefinitions(CONSTRUCTOR_ARG_CONTEXT);
    AbstractBeanDefinition bd = (AbstractBeanDefinition) xbf.getBeanDefinition("lenientDependencyTestBean");
    bd.setLenientConstructorResolution(false);
    try {
      xbf.getBean("lenientDependencyTestBean");
      fail("Should have thrown BeanCreationException");
    }
    catch (BeanCreationException ex) {
      // expected
      ex.printStackTrace();
      assertTrue(ex.getMostSpecificCause().getMessage().contains("Ambiguous"));
    }
  }

  @Test
  public void testNonLenientDependencyMatchingFactoryMethod() {
    DefaultListableBeanFactory xbf = new DefaultListableBeanFactory();
    new XmlBeanDefinitionReader(xbf).loadBeanDefinitions(CONSTRUCTOR_ARG_CONTEXT);
    AbstractBeanDefinition bd = (AbstractBeanDefinition) xbf.getBeanDefinition("lenientDependencyTestBeanFactoryMethod");
    bd.setLenientConstructorResolution(false);
    try {
      xbf.getBean("lenientDependencyTestBeanFactoryMethod");
      fail("Should have thrown BeanCreationException");
    }
    catch (BeanCreationException ex) {
      // expected
      ex.printStackTrace();
      assertTrue(ex.getMostSpecificCause().getMessage().contains("Ambiguous"));
    }
  }

  @Test
  public void testJavaLangStringConstructor() {
    DefaultListableBeanFactory xbf = new DefaultListableBeanFactory();
    new XmlBeanDefinitionReader(xbf).loadBeanDefinitions(CONSTRUCTOR_ARG_CONTEXT);
    AbstractBeanDefinition bd = (AbstractBeanDefinition) xbf.getBeanDefinition("string");
    bd.setLenientConstructorResolution(false);
    String str = (String) xbf.getBean("string");
    assertEquals("test", str);
  }

  @Test
  public void testCustomStringConstructor() {
    DefaultListableBeanFactory xbf = new DefaultListableBeanFactory();
    new XmlBeanDefinitionReader(xbf).loadBeanDefinitions(CONSTRUCTOR_ARG_CONTEXT);
    AbstractBeanDefinition bd = (AbstractBeanDefinition) xbf.getBeanDefinition("stringConstructor");
    bd.setLenientConstructorResolution(false);
    StringConstructorTestBean tb = (StringConstructorTestBean) xbf.getBean("stringConstructor");
    assertEquals("test", tb.name);
  }

  @Test
  public void testPrimitiveConstructorArray() {
    DefaultListableBeanFactory xbf = new DefaultListableBeanFactory();
    new XmlBeanDefinitionReader(xbf).loadBeanDefinitions(CONSTRUCTOR_ARG_CONTEXT);
    ConstructorArrayTestBean bean = (ConstructorArrayTestBean) xbf.getBean("constructorArray");
    assertTrue(bean.array instanceof int[]);
    assertEquals(1, ((int[]) bean.array).length);
    assertEquals(1, ((int[]) bean.array)[0]);
  }

  @Test
  public void testIndexedPrimitiveConstructorArray() {
    DefaultListableBeanFactory xbf = new DefaultListableBeanFactory();
    new XmlBeanDefinitionReader(xbf).loadBeanDefinitions(CONSTRUCTOR_ARG_CONTEXT);
    ConstructorArrayTestBean bean = (ConstructorArrayTestBean) xbf.getBean("indexedConstructorArray");
    assertTrue(bean.array instanceof int[]);
    assertEquals(1, ((int[]) bean.array).length);
    assertEquals(1, ((int[]) bean.array)[0]);
  }

  @Test
  public void testStringConstructorArrayNoType() {
    DefaultListableBeanFactory xbf = new DefaultListableBeanFactory();
    new XmlBeanDefinitionReader(xbf).loadBeanDefinitions(CONSTRUCTOR_ARG_CONTEXT);
    ConstructorArrayTestBean bean = (ConstructorArrayTestBean) xbf.getBean("constructorArrayNoType");
    assertTrue(bean.array instanceof String[]);
    assertEquals(0, ((String[]) bean.array).length);
  }

  @Test
  public void testStringConstructorArrayNoTypeNonLenient() {
    DefaultListableBeanFactory xbf = new DefaultListableBeanFactory();
    new XmlBeanDefinitionReader(xbf).loadBeanDefinitions(CONSTRUCTOR_ARG_CONTEXT);
    AbstractBeanDefinition bd = (AbstractBeanDefinition) xbf.getBeanDefinition("constructorArrayNoType");
    bd.setLenientConstructorResolution(false);
    ConstructorArrayTestBean bean = (ConstructorArrayTestBean) xbf.getBean("constructorArrayNoType");
    assertTrue(bean.array instanceof String[]);
    assertEquals(0, ((String[]) bean.array).length);
  }

  @Test
  public void testWithDuplicateName() throws Exception {
    DefaultListableBeanFactory xbf = new DefaultListableBeanFactory();
    try {
      new XmlBeanDefinitionReader(xbf).loadBeanDefinitions(TEST_WITH_DUP_NAMES_CONTEXT);
      fail("Duplicate name not detected");
    }
    catch (BeansException ex) {
      assertTrue(ex.getMessage().contains("Bean name 'foo'"));
    }
  }

  @Test
  public void testWithDuplicateNameInAlias() throws Exception {
    DefaultListableBeanFactory xbf = new DefaultListableBeanFactory();
    try {
      new XmlBeanDefinitionReader(xbf).loadBeanDefinitions(TEST_WITH_DUP_NAME_IN_ALIAS_CONTEXT);
      fail("Duplicate name not detected");
    }
    catch (BeansException e) {
      assertTrue(e.getMessage().contains("Bean name 'foo'"));
    }
  }

  @Test
  public void testOverrideMethodByArgTypeAttribute() {
    DefaultListableBeanFactory xbf = new DefaultListableBeanFactory();
    XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(xbf);
    reader.loadBeanDefinitions(DELEGATION_OVERRIDES_CONTEXT);
    OverrideOneMethod oom = (OverrideOneMethod) xbf.getBean("overrideOneMethodByAttribute");
    assertEquals("should not replace", "replaceMe:1", oom.replaceMe(1));
    assertEquals("should replace", "cba", oom.replaceMe("abc"));
  }

  @Test
  public void testOverrideMethodByArgTypeElement() {
    DefaultListableBeanFactory xbf = new DefaultListableBeanFactory();
    XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(xbf);
    reader.loadBeanDefinitions(DELEGATION_OVERRIDES_CONTEXT);
    OverrideOneMethod oom = (OverrideOneMethod) xbf.getBean("overrideOneMethodByElement");
    assertEquals("should not replace", "replaceMe:1", oom.replaceMe(1));
    assertEquals("should replace", "cba", oom.replaceMe("abc"));
  }

  public static class DoSomethingReplacer implements MethodReplacer {

    public Object lastArg;

    @Override
    public Object reimplement(Object obj, Method method, Object[] args) throws Throwable {
      assertEquals(1, args.length);
      assertEquals("doSomething", method.getName());
      lastArg = args[0];
      return null;
    }
  }


  public static class BadInitializer {

    /** Init method */
    public void init2() throws IOException {
      throw new IOException();
    }
  }


  public static class DoubleInitializer {

    private int num;

    public int getNum() {
      return num;
    }

    public void setNum(int i) {
      num = i;
    }

    /** Init method */
    public void init() {
      this.num *= 2;
    }
  }


  public static class InitAndIB implements InitializingBean, DisposableBean {

    public static boolean constructed;

    public boolean afterPropertiesSetInvoked, initMethodInvoked, destroyed, customDestroyed;

    public InitAndIB() {
      constructed = true;
    }

    @Override
    public void afterPropertiesSet() {
      if (this.initMethodInvoked) {
        fail();
      }
      if (this.afterPropertiesSetInvoked) {
        throw new IllegalStateException("Already initialized");
      }
      this.afterPropertiesSetInvoked = true;
    }

    /** Init method */
    public void customInit() throws IOException {
      if (!this.afterPropertiesSetInvoked) {
        fail();
      }
      if (this.initMethodInvoked) {
        throw new IllegalStateException("Already customInitialized");
      }
      this.initMethodInvoked = true;
    }

    @Override
    public void destroy() {
      if (this.customDestroyed) {
        fail();
      }
      if (this.destroyed) {
        throw new IllegalStateException("Already destroyed");
      }
      this.destroyed = true;
    }

    public void customDestroy() {
      if (!this.destroyed) {
        fail();
      }
      if (this.customDestroyed) {
        throw new IllegalStateException("Already customDestroyed");
      }
      this.customDestroyed = true;
    }
  }


  public static class PreparingBean1 implements DisposableBean {

    public static boolean prepared = false;

    public static boolean destroyed = false;

    public PreparingBean1() {
      prepared = true;
    }

    @Override
    public void destroy() {
      destroyed = true;
    }
  }


  public static class PreparingBean2 implements DisposableBean {

    public static boolean prepared = false;

    public static boolean destroyed = false;

    public PreparingBean2() {
      prepared = true;
    }

    @Override
    public void destroy() {
      destroyed = true;
    }
  }


  public static class DependingBean implements InitializingBean, DisposableBean {

    public static int destroyCount = 0;

    public boolean destroyed = false;

    public DependingBean() {
    }

    public DependingBean(PreparingBean1 bean1, PreparingBean2 bean2) {
    }

    public void setBean1(PreparingBean1 bean1) {
    }

    public void setBean2(PreparingBean2 bean2) {
    }

    public void setInTheMiddleBean(InTheMiddleBean bean) {
    }

    @Override
    public void afterPropertiesSet() {
      if (!(PreparingBean1.prepared && PreparingBean2.prepared)) {
        throw new IllegalStateException("Need prepared PreparingBeans!");
      }
    }

    @Override
    public void destroy() {
      if (PreparingBean1.destroyed || PreparingBean2.destroyed) {
        throw new IllegalStateException("Should not be destroyed after PreparingBeans");
      }
      destroyed = true;
      destroyCount++;
    }
  }


  public static class InTheMiddleBean {

    public void setBean1(PreparingBean1 bean1) {
    }

    public void setBean2(PreparingBean2 bean2) {
    }
  }


  public static class HoldingBean implements DisposableBean {

    public static int destroyCount = 0;

    private DependingBean dependingBean;

    public boolean destroyed = false;

    public void setDependingBean(DependingBean dependingBean) {
      this.dependingBean = dependingBean;
    }

    @Override
    public void destroy() {
      if (this.dependingBean.destroyed) {
        throw new IllegalStateException("Should not be destroyed after DependingBean");
      }
      this.destroyed = true;
      destroyCount++;
    }
  }


  public static class DoubleBooleanConstructorBean {

    private Boolean boolean1;
    private Boolean boolean2;

    public DoubleBooleanConstructorBean(Boolean b1, Boolean b2) {
      this.boolean1 = b1;
      this.boolean2 = b2;
    }

    public DoubleBooleanConstructorBean(String s1, String s2) {
      throw new IllegalStateException("Don't pick this constructor");
    }

    public static DoubleBooleanConstructorBean create(Boolean b1, Boolean b2) {
      return new DoubleBooleanConstructorBean(b1, b2);
    }

    public static DoubleBooleanConstructorBean create(String s1, String s2) {
      return new DoubleBooleanConstructorBean(s1, s2);
    }
  }


  public static class LenientDependencyTestBean {

    public final ITestBean tb;

    public LenientDependencyTestBean(ITestBean tb) {
      this.tb = tb;
    }

    public LenientDependencyTestBean(TestBean tb) {
      this.tb = tb;
    }

    public LenientDependencyTestBean(DerivedTestBean tb) {
      this.tb = tb;
    }

    @SuppressWarnings("rawtypes")
    public LenientDependencyTestBean(Map[] m) {
      throw new IllegalStateException("Don't pick this constructor");
    }

    public static LenientDependencyTestBean create(ITestBean tb) {
      return new LenientDependencyTestBean(tb);
    }

    public static LenientDependencyTestBean create(TestBean tb) {
      return new LenientDependencyTestBean(tb);
    }

    public static LenientDependencyTestBean create(DerivedTestBean tb) {
      return new LenientDependencyTestBean(tb);
    }
  }


  public static class ConstructorArrayTestBean {

    public final Object array;

    public ConstructorArrayTestBean(int[] array) {
      this.array = array;
    }

    public ConstructorArrayTestBean(float[] array) {
      this.array = array;
    }

    public ConstructorArrayTestBean(short[] array) {
      this.array = array;
    }

    public ConstructorArrayTestBean(String[] array) {
      this.array = array;
    }
  }


  public static class StringConstructorTestBean {

    public final String name;

    public StringConstructorTestBean(String name) {
      this.name = name;
    }
  }


  public static class WrappingPostProcessor implements BeanPostProcessor {

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
      return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
      ProxyFactory pf = new ProxyFactory(bean);
      return pf.getProxy();
    }
  }

}
TOP

Related Classes of org.springframework.beans.factory.xml.XmlBeanFactoryTests$ConstructorArrayTestBean

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.
y>