@Test
  public void testFactoryMethodsSingletonOnTargetClass() {
    DefaultListableBeanFactory xbf = new DefaultListableBeanFactory();
    XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(xbf);
    reader.loadBeanDefinitions(new ClassPathResource("factory-methods.xml", getClass()));

    TestBean tb = (TestBean) xbf.getBean("defaultTestBean");
    assertEquals("defaultInstance", tb.getName());
    assertEquals(1, tb.getAge());

    FactoryMethods fm = (FactoryMethods) xbf.getBean("default");
    assertEquals(0, fm.getNum());
    assertEquals("default", fm.getName());
    assertEquals("defaultInstance", fm.getTestBean().getName());
    assertEquals("setterString", fm.getStringValue());

    fm = (FactoryMethods) xbf.getBean("testBeanOnly");
    assertEquals(0, fm.getNum());
    assertEquals("default", fm.getName());
    // This comes from the test bean
    assertEquals("Juergen", fm.getTestBean().getName());

    fm = (FactoryMethods) xbf.getBean("full");
    assertEquals(27, fm.getNum());
    assertEquals("gotcha", fm.getName());
    assertEquals("Juergen", fm.getTestBean().getName());

    FactoryMethods fm2 = (FactoryMethods) xbf.getBean("full");
    assertSame(fm, fm2);

    xbf.destroySingletons();
    assertTrue(tb.wasDestroyed());
  }
  /** Tests where the static factory method is on a different class. */
  @Test
  public void testFactoryMethodsOnExternalClass() {
    DefaultListableBeanFactory xbf = new DefaultListableBeanFactory();
    XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(xbf);
    reader.loadBeanDefinitions(new ClassPathResource("factory-methods.xml", getClass()));

    assertEquals(TestBean.class, xbf.getType("externalFactoryMethodWithoutArgs"));
    assertEquals(TestBean.class, xbf.getType("externalFactoryMethodWithArgs"));
    String[] names = xbf.getBeanNamesForType(TestBean.class);
    assertTrue(Arrays.asList(names).contains("externalFactoryMethodWithoutArgs"));
    assertTrue(Arrays.asList(names).contains("externalFactoryMethodWithArgs"));

    TestBean tb = (TestBean) xbf.getBean("externalFactoryMethodWithoutArgs");
    assertEquals(2, tb.getAge());
    assertEquals("Tristan", tb.getName());
    tb = (TestBean) xbf.getBean("externalFactoryMethodWithArgs");
    assertEquals(33, tb.getAge());
    assertEquals("Rod", tb.getName());

    assertEquals(TestBean.class, xbf.getType("externalFactoryMethodWithoutArgs"));
    assertEquals(TestBean.class, xbf.getType("externalFactoryMethodWithArgs"));
    names = xbf.getBeanNamesForType(TestBean.class);
    assertTrue(Arrays.asList(names).contains("externalFactoryMethodWithoutArgs"));
    assertTrue(Arrays.asList(names).contains("externalFactoryMethodWithArgs"));
  }
  @Test
  public void testPrivateFactoryMethod() {
    DefaultListableBeanFactory xbf = new DefaultListableBeanFactory();
    XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(xbf);
    reader.loadBeanDefinitions(new ClassPathResource("factory-methods.xml", getClass()));

    TestBean tb = (TestBean) xbf.getBean("defaultTestBean.private");
    assertEquals(1, tb.getAge());
  }
  @Test
  public void testCanSpecifyFactoryMethodArgumentsOnFactoryMethodPrototype() {
    DefaultListableBeanFactory xbf = new DefaultListableBeanFactory();
    XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(xbf);
    reader.loadBeanDefinitions(new ClassPathResource("factory-methods.xml", getClass()));
    TestBean tbArg = new TestBean();
    tbArg.setName("arg1");
    TestBean tbArg2 = new TestBean();
    tbArg2.setName("arg2");

    FactoryMethods fm1 = (FactoryMethods) xbf.getBean("testBeanOnlyPrototype", tbArg);
    assertEquals(0, fm1.getNum());
    assertEquals("default", fm1.getName());
    // This comes from the test bean
    assertEquals("arg1", fm1.getTestBean().getName());

    FactoryMethods fm2 = (FactoryMethods) xbf.getBean("testBeanOnlyPrototype", tbArg2);
    assertEquals("arg2", fm2.getTestBean().getName());
    assertEquals(fm1.getNum(), fm2.getNum());
    assertEquals(fm2.getStringValue(), "testBeanOnlyPrototypeDISetterString");
    assertEquals(fm2.getStringValue(), fm2.getStringValue());
    // The TestBean reference is resolved to a prototype in the factory
    assertSame(fm2.getTestBean(), fm2.getTestBean());
    assertNotSame(fm1, fm2);

    FactoryMethods fm3 =
        (FactoryMethods) xbf.getBean("testBeanOnlyPrototype", tbArg2, new Integer(1), "myName");
    assertEquals(1, fm3.getNum());
    assertEquals("myName", fm3.getName());
    assertEquals("arg2", fm3.getTestBean().getName());

    FactoryMethods fm4 = (FactoryMethods) xbf.getBean("testBeanOnlyPrototype", tbArg);
    assertEquals(0, fm4.getNum());
    assertEquals("default", fm4.getName());
    assertEquals("arg1", fm4.getTestBean().getName());
  }