Moved tests from testsuite to beans

This commit is contained in:
Arjen Poutsma 2008-10-29 18:20:29 +00:00
parent e31ad80a0b
commit eae7267929
12 changed files with 1226 additions and 56 deletions

View File

@ -0,0 +1,329 @@
/*
* Copyright 2002-2008 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.beans.PropertyEditorSupport;
import java.util.StringTokenizer;
import junit.framework.TestCase;
import junit.framework.Assert;
import org.springframework.beans.BeansException;
import org.springframework.beans.PropertyBatchUpdateException;
import org.springframework.beans.TestBean;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
/**
* Subclasses must implement setUp() to initialize bean factory
* and any other variables they need.
*
* @author Rod Johnson
* @author Juergen Hoeller
*/
public abstract class AbstractBeanFactoryTests extends TestCase {
protected abstract BeanFactory getBeanFactory();
/**
* Roderick beans inherits from rod, overriding name only.
*/
public void testInheritance() {
assertTrue(getBeanFactory().containsBean("rod"));
assertTrue(getBeanFactory().containsBean("roderick"));
TestBean rod = (TestBean) getBeanFactory().getBean("rod");
TestBean roderick = (TestBean) getBeanFactory().getBean("roderick");
assertTrue("not == ", rod != roderick);
assertTrue("rod.name is Rod", rod.getName().equals("Rod"));
assertTrue("rod.age is 31", rod.getAge() == 31);
assertTrue("roderick.name is Roderick", roderick.getName().equals("Roderick"));
assertTrue("roderick.age was inherited", roderick.getAge() == rod.getAge());
}
public void testGetBeanWithNullArg() {
try {
getBeanFactory().getBean(null);
fail("Can't get null bean");
}
catch (IllegalArgumentException ex) {
// OK
}
}
/**
* Test that InitializingBean objects receive the afterPropertiesSet() callback
*/
public void testInitializingBeanCallback() {
MustBeInitialized mbi = (MustBeInitialized) getBeanFactory().getBean("mustBeInitialized");
// The dummy business method will throw an exception if the
// afterPropertiesSet() callback wasn't invoked
mbi.businessMethod();
}
/**
* Test that InitializingBean/BeanFactoryAware/DisposableBean objects receive the
* afterPropertiesSet() callback before BeanFactoryAware callbacks
*/
public void testLifecycleCallbacks() {
LifecycleBean lb = (LifecycleBean) getBeanFactory().getBean("lifecycle");
Assert.assertEquals("lifecycle", lb.getBeanName());
// The dummy business method will throw an exception if the
// necessary callbacks weren't invoked in the right order.
lb.businessMethod();
assertTrue("Not destroyed", !lb.isDestroyed());
}
public void testFindsValidInstance() {
try {
Object o = getBeanFactory().getBean("rod");
assertTrue("Rod bean is a TestBean", o instanceof TestBean);
TestBean rod = (TestBean) o;
assertTrue("rod.name is Rod", rod.getName().equals("Rod"));
assertTrue("rod.age is 31", rod.getAge() == 31);
}
catch (Exception ex) {
ex.printStackTrace();
fail("Shouldn't throw exception on getting valid instance");
}
}
public void testGetInstanceByMatchingClass() {
try {
Object o = getBeanFactory().getBean("rod", TestBean.class);
assertTrue("Rod bean is a TestBean", o instanceof TestBean);
}
catch (Exception ex) {
ex.printStackTrace();
fail("Shouldn't throw exception on getting valid instance with matching class");
}
}
public void testGetInstanceByNonmatchingClass() {
try {
Object o = getBeanFactory().getBean("rod", BeanFactory.class);
fail("Rod bean is not of type BeanFactory; getBeanInstance(rod, BeanFactory.class) should throw BeanNotOfRequiredTypeException");
}
catch (BeanNotOfRequiredTypeException ex) {
// So far, so good
assertTrue("Exception has correct bean name", ex.getBeanName().equals("rod"));
assertTrue("Exception requiredType must be BeanFactory.class", ex.getRequiredType().equals(BeanFactory.class));
assertTrue("Exception actualType as TestBean.class", TestBean.class.isAssignableFrom(ex.getActualType()));
assertTrue("Actual type is correct", ex.getActualType() == getBeanFactory().getBean("rod").getClass());
}
catch (Exception ex) {
ex.printStackTrace();
fail("Shouldn't throw exception on getting valid instance");
}
}
public void testGetSharedInstanceByMatchingClass() {
try {
Object o = getBeanFactory().getBean("rod", TestBean.class);
assertTrue("Rod bean is a TestBean", o instanceof TestBean);
}
catch (Exception ex) {
ex.printStackTrace();
fail("Shouldn't throw exception on getting valid instance with matching class");
}
}
public void testGetSharedInstanceByMatchingClassNoCatch() {
Object o = getBeanFactory().getBean("rod", TestBean.class);
assertTrue("Rod bean is a TestBean", o instanceof TestBean);
}
public void testGetSharedInstanceByNonmatchingClass() {
try {
Object o = getBeanFactory().getBean("rod", BeanFactory.class);
fail("Rod bean is not of type BeanFactory; getBeanInstance(rod, BeanFactory.class) should throw BeanNotOfRequiredTypeException");
}
catch (BeanNotOfRequiredTypeException ex) {
// So far, so good
assertTrue("Exception has correct bean name", ex.getBeanName().equals("rod"));
assertTrue("Exception requiredType must be BeanFactory.class", ex.getRequiredType().equals(BeanFactory.class));
assertTrue("Exception actualType as TestBean.class", TestBean.class.isAssignableFrom(ex.getActualType()));
}
catch (Exception ex) {
ex.printStackTrace();
fail("Shouldn't throw exception on getting valid instance");
}
}
public void testSharedInstancesAreEqual() {
try {
Object o = getBeanFactory().getBean("rod");
assertTrue("Rod bean1 is a TestBean", o instanceof TestBean);
Object o1 = getBeanFactory().getBean("rod");
assertTrue("Rod bean2 is a TestBean", o1 instanceof TestBean);
assertTrue("Object equals applies", o == o1);
}
catch (Exception ex) {
ex.printStackTrace();
fail("Shouldn't throw exception on getting valid instance");
}
}
public void testPrototypeInstancesAreIndependent() {
TestBean tb1 = (TestBean) getBeanFactory().getBean("kathy");
TestBean tb2 = (TestBean) getBeanFactory().getBean("kathy");
assertTrue("ref equal DOES NOT apply", tb1 != tb2);
assertTrue("object equal true", tb1.equals(tb2));
tb1.setAge(1);
tb2.setAge(2);
assertTrue("1 age independent = 1", tb1.getAge() == 1);
assertTrue("2 age independent = 2", tb2.getAge() == 2);
assertTrue("object equal now false", !tb1.equals(tb2));
}
public void testNotThere() {
assertFalse(getBeanFactory().containsBean("Mr Squiggle"));
try {
Object o = getBeanFactory().getBean("Mr Squiggle");
fail("Can't find missing bean");
}
catch (BeansException ex) {
//ex.printStackTrace();
//fail("Shouldn't throw exception on getting valid instance");
}
}
public void testValidEmpty() {
try {
Object o = getBeanFactory().getBean("validEmpty");
assertTrue("validEmpty bean is a TestBean", o instanceof TestBean);
TestBean ve = (TestBean) o;
assertTrue("Valid empty has defaults", ve.getName() == null && ve.getAge() == 0 && ve.getSpouse() == null);
}
catch (BeansException ex) {
ex.printStackTrace();
fail("Shouldn't throw exception on valid empty");
}
}
public void xtestTypeMismatch() {
try {
Object o = getBeanFactory().getBean("typeMismatch");
fail("Shouldn't succeed with type mismatch");
}
catch (BeanCreationException wex) {
assertEquals("typeMismatch", wex.getBeanName());
assertTrue(wex.getCause() instanceof PropertyBatchUpdateException);
PropertyBatchUpdateException ex = (PropertyBatchUpdateException) wex.getCause();
// Further tests
assertTrue("Has one error ", ex.getExceptionCount() == 1);
assertTrue("Error is for field age", ex.getPropertyAccessException("age") != null);
assertTrue("We have rejected age in exception", ex.getPropertyAccessException("age").getPropertyChangeEvent().getNewValue().equals("34x"));
}
}
public void testGrandparentDefinitionFoundInBeanFactory() throws Exception {
TestBean dad = (TestBean) getBeanFactory().getBean("father");
assertTrue("Dad has correct name", dad.getName().equals("Albert"));
}
public void testFactorySingleton() throws Exception {
assertTrue(getBeanFactory().isSingleton("&singletonFactory"));
assertTrue(getBeanFactory().isSingleton("singletonFactory"));
TestBean tb = (TestBean) getBeanFactory().getBean("singletonFactory");
assertTrue("Singleton from factory has correct name, not " + tb.getName(), tb.getName().equals(DummyFactory.SINGLETON_NAME));
DummyFactory factory = (DummyFactory) getBeanFactory().getBean("&singletonFactory");
TestBean tb2 = (TestBean) getBeanFactory().getBean("singletonFactory");
assertTrue("Singleton references ==", tb == tb2);
assertTrue("FactoryBean is BeanFactoryAware", factory.getBeanFactory() != null);
}
public void testFactoryPrototype() throws Exception {
assertTrue(getBeanFactory().isSingleton("&prototypeFactory"));
assertFalse(getBeanFactory().isSingleton("prototypeFactory"));
TestBean tb = (TestBean) getBeanFactory().getBean("prototypeFactory");
assertTrue(!tb.getName().equals(DummyFactory.SINGLETON_NAME));
TestBean tb2 = (TestBean) getBeanFactory().getBean("prototypeFactory");
assertTrue("Prototype references !=", tb != tb2);
}
/**
* Check that we can get the factory bean itself.
* This is only possible if we're dealing with a factory
* @throws Exception
*/
public void testGetFactoryItself() throws Exception {
DummyFactory factory = (DummyFactory) getBeanFactory().getBean("&singletonFactory");
assertTrue(factory != null);
}
/**
* Check that afterPropertiesSet gets called on factory
* @throws Exception
*/
public void testFactoryIsInitialized() throws Exception {
TestBean tb = (TestBean) getBeanFactory().getBean("singletonFactory");
DummyFactory factory = (DummyFactory) getBeanFactory().getBean("&singletonFactory");
assertTrue("Factory was initialized because it implemented InitializingBean", factory.wasInitialized());
}
/**
* It should be illegal to dereference a normal bean
* as a factory
*/
public void testRejectsFactoryGetOnNormalBean() {
try {
getBeanFactory().getBean("&rod");
fail("Shouldn't permit factory get on normal bean");
}
catch (BeanIsNotAFactoryException ex) {
// Ok
}
}
// TODO: refactor in AbstractBeanFactory (tests for AbstractBeanFactory)
// and rename this class
public void testAliasing() {
BeanFactory bf = getBeanFactory();
if (!(bf instanceof ConfigurableBeanFactory)) {
return;
}
ConfigurableBeanFactory cbf = (ConfigurableBeanFactory) bf;
String alias = "rods alias";
try {
cbf.getBean(alias);
fail("Shouldn't permit factory get on normal bean");
}
catch (NoSuchBeanDefinitionException ex) {
// Ok
assertTrue(alias.equals(ex.getBeanName()));
}
// Create alias
cbf.registerAlias("rod", alias);
Object rod = getBeanFactory().getBean("rod");
Object aliasRod = getBeanFactory().getBean(alias);
assertTrue(rod == aliasRod);
}
public static class TestBeanEditor extends PropertyEditorSupport {
public void setAsText(String text) {
TestBean tb = new TestBean();
StringTokenizer st = new StringTokenizer(text, "_");
tb.setName(st.nextToken());
tb.setAge(Integer.parseInt(st.nextToken()));
setValue(tb);
}
}
}

View File

@ -0,0 +1,86 @@
/*
* Copyright 2002-2007 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 junit.framework.Assert;
import org.springframework.beans.TestBean;
/**
* @author Rod Johnson
* @author Juergen Hoeller
*/
public abstract class AbstractListableBeanFactoryTests extends AbstractBeanFactoryTests {
/** Subclasses must initialize this */
protected ListableBeanFactory getListableBeanFactory() {
BeanFactory bf = getBeanFactory();
if (!(bf instanceof ListableBeanFactory)) {
throw new IllegalStateException("ListableBeanFactory required");
}
return (ListableBeanFactory) bf;
}
/**
* Subclasses can override this.
*/
public void testCount() {
assertCount(13);
}
protected final void assertCount(int count) {
String[] defnames = getListableBeanFactory().getBeanDefinitionNames();
Assert.assertTrue("We should have " + count + " beans, not " + defnames.length, defnames.length == count);
}
public void assertTestBeanCount(int count) {
String[] defNames = getListableBeanFactory().getBeanNamesForType(TestBean.class, true, false);
Assert.assertTrue("We should have " + count + " beans for class org.springframework.beans.TestBean, not " +
defNames.length, defNames.length == count);
int countIncludingFactoryBeans = count + 2;
String[] names = getListableBeanFactory().getBeanNamesForType(TestBean.class, true, true);
Assert.assertTrue("We should have " + countIncludingFactoryBeans +
" beans for class org.springframework.beans.TestBean, not " + names.length,
names.length == countIncludingFactoryBeans);
}
public void testGetDefinitionsForNoSuchClass() {
String[] defnames = getListableBeanFactory().getBeanNamesForType(String.class);
Assert.assertTrue("No string definitions", defnames.length == 0);
}
/**
* Check that count refers to factory class, not bean class. (We don't know
* what type factories may return, and it may even change over time.)
*/
public void testGetCountForFactoryClass() {
Assert.assertTrue("Should have 2 factories, not " +
getListableBeanFactory().getBeanNamesForType(FactoryBean.class).length,
getListableBeanFactory().getBeanNamesForType(FactoryBean.class).length == 2);
Assert.assertTrue("Should have 2 factories, not " +
getListableBeanFactory().getBeanNamesForType(FactoryBean.class).length,
getListableBeanFactory().getBeanNamesForType(FactoryBean.class).length == 2);
}
public void testContainsBeanDefinition() {
Assert.assertTrue(getListableBeanFactory().containsBeanDefinition("rod"));
Assert.assertTrue(getListableBeanFactory().containsBeanDefinition("roderick"));
}
}

View File

@ -0,0 +1,172 @@
/*
* Copyright 2002-2007 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 org.springframework.beans.BeansException;
import org.springframework.beans.TestBean;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
/**
* Simple factory to allow testing of FactoryBean support in AbstractBeanFactory.
* Depending on whether its singleton property is set, it will return a singleton
* or a prototype instance.
*
* <p>Implements InitializingBean interface, so we can check that
* factories get this lifecycle callback if they want.
*
* @author Rod Johnson
* @since 10.03.2003
*/
public class DummyFactory
implements FactoryBean, BeanNameAware, BeanFactoryAware, InitializingBean, DisposableBean {
public static final String SINGLETON_NAME = "Factory singleton";
private static boolean prototypeCreated;
/**
* Clear static state.
*/
public static void reset() {
prototypeCreated = false;
}
/**
* Default is for factories to return a singleton instance.
*/
private boolean singleton = true;
private String beanName;
private AutowireCapableBeanFactory beanFactory;
private boolean postProcessed;
private boolean initialized;
private TestBean testBean;
private TestBean otherTestBean;
public DummyFactory() {
this.testBean = new TestBean();
this.testBean.setName(SINGLETON_NAME);
this.testBean.setAge(25);
}
/**
* Return if the bean managed by this factory is a singleton.
* @see FactoryBean#isSingleton()
*/
public boolean isSingleton() {
return this.singleton;
}
/**
* Set if the bean managed by this factory is a singleton.
*/
public void setSingleton(boolean singleton) {
this.singleton = singleton;
}
public void setBeanName(String beanName) {
this.beanName = beanName;
}
public String getBeanName() {
return beanName;
}
public void setBeanFactory(BeanFactory beanFactory) {
this.beanFactory = (AutowireCapableBeanFactory) beanFactory;
this.beanFactory.applyBeanPostProcessorsBeforeInitialization(this.testBean, this.beanName);
}
public BeanFactory getBeanFactory() {
return beanFactory;
}
public void setPostProcessed(boolean postProcessed) {
this.postProcessed = postProcessed;
}
public boolean isPostProcessed() {
return postProcessed;
}
public void setOtherTestBean(TestBean otherTestBean) {
this.otherTestBean = otherTestBean;
this.testBean.setSpouse(otherTestBean);
}
public TestBean getOtherTestBean() {
return otherTestBean;
}
public void afterPropertiesSet() {
if (initialized) {
throw new RuntimeException("Cannot call afterPropertiesSet twice on the one bean");
}
this.initialized = true;
}
/**
* Was this initialized by invocation of the
* afterPropertiesSet() method from the InitializingBean interface?
*/
public boolean wasInitialized() {
return initialized;
}
public static boolean wasPrototypeCreated() {
return prototypeCreated;
}
/**
* Return the managed object, supporting both singleton
* and prototype mode.
* @see FactoryBean#getObject()
*/
public Object getObject() throws BeansException {
if (isSingleton()) {
return this.testBean;
}
else {
TestBean prototype = new TestBean("prototype created at " + System.currentTimeMillis(), 11);
if (this.beanFactory != null) {
this.beanFactory.applyBeanPostProcessorsBeforeInitialization(prototype, this.beanName);
}
prototypeCreated = true;
return prototype;
}
}
public Class getObjectType() {
return TestBean.class;
}
public void destroy() {
if (this.testBean != null) {
this.testBean.setName(null);
}
}
}

View File

@ -0,0 +1,158 @@
/*
* Copyright 2002-2007 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 org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
/**
* Simple test of BeanFactory initialization and lifecycle callbacks.
*
* @author Rod Johnson
* @author Colin Sampaleanu
* @since 12.03.2003
*/
public class LifecycleBean implements BeanNameAware, BeanFactoryAware, InitializingBean, DisposableBean {
protected boolean initMethodDeclared = false;
protected String beanName;
protected BeanFactory owningFactory;
protected boolean postProcessedBeforeInit;
protected boolean inited;
protected boolean initedViaDeclaredInitMethod;
protected boolean postProcessedAfterInit;
protected boolean destroyed;
public void setInitMethodDeclared(boolean initMethodDeclared) {
this.initMethodDeclared = initMethodDeclared;
}
public boolean isInitMethodDeclared() {
return initMethodDeclared;
}
public void setBeanName(String name) {
this.beanName = name;
}
public String getBeanName() {
return beanName;
}
public void setBeanFactory(BeanFactory beanFactory) {
this.owningFactory = beanFactory;
}
public void postProcessBeforeInit() {
if (this.inited || this.initedViaDeclaredInitMethod) {
throw new RuntimeException("Factory called postProcessBeforeInit after afterPropertiesSet");
}
if (this.postProcessedBeforeInit) {
throw new RuntimeException("Factory called postProcessBeforeInit twice");
}
this.postProcessedBeforeInit = true;
}
public void afterPropertiesSet() {
if (this.owningFactory == null) {
throw new RuntimeException("Factory didn't call setBeanFactory before afterPropertiesSet on lifecycle bean");
}
if (!this.postProcessedBeforeInit) {
throw new RuntimeException("Factory didn't call postProcessBeforeInit before afterPropertiesSet on lifecycle bean");
}
if (this.initedViaDeclaredInitMethod) {
throw new RuntimeException("Factory initialized via declared init method before initializing via afterPropertiesSet");
}
if (this.inited) {
throw new RuntimeException("Factory called afterPropertiesSet twice");
}
this.inited = true;
}
public void declaredInitMethod() {
if (!this.inited) {
throw new RuntimeException("Factory didn't call afterPropertiesSet before declared init method");
}
if (this.initedViaDeclaredInitMethod) {
throw new RuntimeException("Factory called declared init method twice");
}
this.initedViaDeclaredInitMethod = true;
}
public void postProcessAfterInit() {
if (!this.inited) {
throw new RuntimeException("Factory called postProcessAfterInit before afterPropertiesSet");
}
if (this.initMethodDeclared && !this.initedViaDeclaredInitMethod) {
throw new RuntimeException("Factory called postProcessAfterInit before calling declared init method");
}
if (this.postProcessedAfterInit) {
throw new RuntimeException("Factory called postProcessAfterInit twice");
}
this.postProcessedAfterInit = true;
}
/**
* Dummy business method that will fail unless the factory
* managed the bean's lifecycle correctly
*/
public void businessMethod() {
if (!this.inited || (this.initMethodDeclared && !this.initedViaDeclaredInitMethod) ||
!this.postProcessedAfterInit) {
throw new RuntimeException("Factory didn't initialize lifecycle object correctly");
}
}
public void destroy() {
if (this.destroyed) {
throw new IllegalStateException("Already destroyed");
}
this.destroyed = true;
}
public boolean isDestroyed() {
return destroyed;
}
public static class PostProcessor implements BeanPostProcessor {
public Object postProcessBeforeInitialization(Object bean, String name) throws BeansException {
if (bean instanceof LifecycleBean) {
((LifecycleBean) bean).postProcessBeforeInit();
}
return bean;
}
public Object postProcessAfterInitialization(Object bean, String name) throws BeansException {
if (bean instanceof LifecycleBean) {
((LifecycleBean) bean).postProcessAfterInit();
}
return bean;
}
}
}

View File

@ -0,0 +1,44 @@
/*
* Copyright 2002-2005 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;
/**
* Simple test of BeanFactory initialization
* @author Rod Johnson
* @since 12.03.2003
*/
public class MustBeInitialized implements InitializingBean {
private boolean inited;
/**
* @see InitializingBean#afterPropertiesSet()
*/
public void afterPropertiesSet() throws Exception {
this.inited = true;
}
/**
* Dummy business method that will fail unless the factory
* managed the bean's lifecycle correctly
*/
public void businessMethod() {
if (!this.inited)
throw new RuntimeException("Factory didn't call afterPropertiesSet() on MustBeInitialized object");
}
}

View File

@ -0,0 +1,66 @@
/*
* Copyright 2002-2005 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 org.springframework.beans.TestBean;
import org.springframework.beans.factory.DummyFactory;
/**
* @author Juergen Hoeller
* @since 21.07.2003
*/
public class DummyReferencer {
private TestBean testBean1;
private TestBean testBean2;
private DummyFactory dummyFactory;
public DummyReferencer() {
}
public DummyReferencer(DummyFactory dummyFactory) {
this.dummyFactory = dummyFactory;
}
public void setDummyFactory(DummyFactory dummyFactory) {
this.dummyFactory = dummyFactory;
}
public DummyFactory getDummyFactory() {
return dummyFactory;
}
public void setTestBean1(TestBean testBean1) {
this.testBean1 = testBean1;
}
public TestBean getTestBean1() {
return testBean1;
}
public void setTestBean2(TestBean testBean2) {
this.testBean2 = testBean2;
}
public TestBean getTestBean2() {
return testBean2;
}
}

View File

@ -0,0 +1,162 @@
/*
* Copyright 2002-2007 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 org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.config.BeanPostProcessor;
/**
* Simple test of BeanFactory initialization and lifecycle callbacks.
*
* @author Rod Johnson
* @author Juergen Hoeller
*/
class ProtectedLifecycleBean implements BeanNameAware, BeanFactoryAware, InitializingBean, DisposableBean {
protected boolean initMethodDeclared = false;
protected String beanName;
protected BeanFactory owningFactory;
protected boolean postProcessedBeforeInit;
protected boolean inited;
protected boolean initedViaDeclaredInitMethod;
protected boolean postProcessedAfterInit;
protected boolean destroyed;
public void setInitMethodDeclared(boolean initMethodDeclared) {
this.initMethodDeclared = initMethodDeclared;
}
public boolean isInitMethodDeclared() {
return initMethodDeclared;
}
public void setBeanName(String name) {
this.beanName = name;
}
public String getBeanName() {
return beanName;
}
public void setBeanFactory(BeanFactory beanFactory) {
this.owningFactory = beanFactory;
}
public void postProcessBeforeInit() {
if (this.inited || this.initedViaDeclaredInitMethod) {
throw new RuntimeException("Factory called postProcessBeforeInit after afterPropertiesSet");
}
if (this.postProcessedBeforeInit) {
throw new RuntimeException("Factory called postProcessBeforeInit twice");
}
this.postProcessedBeforeInit = true;
}
public void afterPropertiesSet() {
if (this.owningFactory == null) {
throw new RuntimeException("Factory didn't call setBeanFactory before afterPropertiesSet on lifecycle bean");
}
if (!this.postProcessedBeforeInit) {
throw new RuntimeException("Factory didn't call postProcessBeforeInit before afterPropertiesSet on lifecycle bean");
}
if (this.initedViaDeclaredInitMethod) {
throw new RuntimeException("Factory initialized via declared init method before initializing via afterPropertiesSet");
}
if (this.inited) {
throw new RuntimeException("Factory called afterPropertiesSet twice");
}
this.inited = true;
}
public void declaredInitMethod() {
if (!this.inited) {
throw new RuntimeException("Factory didn't call afterPropertiesSet before declared init method");
}
if (this.initedViaDeclaredInitMethod) {
throw new RuntimeException("Factory called declared init method twice");
}
this.initedViaDeclaredInitMethod = true;
}
public void postProcessAfterInit() {
if (!this.inited) {
throw new RuntimeException("Factory called postProcessAfterInit before afterPropertiesSet");
}
if (this.initMethodDeclared && !this.initedViaDeclaredInitMethod) {
throw new RuntimeException("Factory called postProcessAfterInit before calling declared init method");
}
if (this.postProcessedAfterInit) {
throw new RuntimeException("Factory called postProcessAfterInit twice");
}
this.postProcessedAfterInit = true;
}
/**
* Dummy business method that will fail unless the factory
* managed the bean's lifecycle correctly
*/
public void businessMethod() {
if (!this.inited || (this.initMethodDeclared && !this.initedViaDeclaredInitMethod) ||
!this.postProcessedAfterInit) {
throw new RuntimeException("Factory didn't initialize lifecycle object correctly");
}
}
public void destroy() {
if (this.destroyed) {
throw new IllegalStateException("Already destroyed");
}
this.destroyed = true;
}
public boolean isDestroyed() {
return destroyed;
}
public static class PostProcessor implements BeanPostProcessor {
public Object postProcessBeforeInitialization(Object bean, String name) throws BeansException {
if (bean instanceof ProtectedLifecycleBean) {
((ProtectedLifecycleBean) bean).postProcessBeforeInit();
}
return bean;
}
public Object postProcessAfterInitialization(Object bean, String name) throws BeansException {
if (bean instanceof ProtectedLifecycleBean) {
((ProtectedLifecycleBean) bean).postProcessAfterInit();
}
return bean;
}
}
}

View File

@ -21,6 +21,8 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import junit.framework.Assert;
import org.springframework.beans.BeansException;
import org.springframework.beans.ITestBean;
import org.springframework.beans.MutablePropertyValues;
@ -99,7 +101,7 @@ public class XmlListableBeanFactoryTests extends AbstractListableBeanFactoryTest
public void testDescriptionButNoProperties() throws Exception {
TestBean validEmpty = (TestBean) getBeanFactory().getBean("validEmptyWithDescription");
assertEquals(0, validEmpty.getAge());
Assert.assertEquals(0, validEmpty.getAge());
}
/**
@ -110,94 +112,94 @@ public class XmlListableBeanFactoryTests extends AbstractListableBeanFactoryTest
TestBean tb1 = (TestBean) getBeanFactory().getBean("aliased");
TestBean alias1 = (TestBean) getBeanFactory().getBean("myalias");
assertTrue(tb1 == alias1);
Assert.assertTrue(tb1 == alias1);
List tb1Aliases = Arrays.asList(getBeanFactory().getAliases("aliased"));
assertEquals(2, tb1Aliases.size());
assertTrue(tb1Aliases.contains("myalias"));
assertTrue(tb1Aliases.contains("youralias"));
assertTrue(beanNames.contains("aliased"));
assertFalse(beanNames.contains("myalias"));
assertFalse(beanNames.contains("youralias"));
Assert.assertEquals(2, tb1Aliases.size());
Assert.assertTrue(tb1Aliases.contains("myalias"));
Assert.assertTrue(tb1Aliases.contains("youralias"));
Assert.assertTrue(beanNames.contains("aliased"));
Assert.assertFalse(beanNames.contains("myalias"));
Assert.assertFalse(beanNames.contains("youralias"));
TestBean tb2 = (TestBean) getBeanFactory().getBean("multiAliased");
TestBean alias2 = (TestBean) getBeanFactory().getBean("alias1");
TestBean alias3 = (TestBean) getBeanFactory().getBean("alias2");
TestBean alias3a = (TestBean) getBeanFactory().getBean("alias3");
TestBean alias3b = (TestBean) getBeanFactory().getBean("alias4");
assertTrue(tb2 == alias2);
assertTrue(tb2 == alias3);
assertTrue(tb2 == alias3a);
assertTrue(tb2 == alias3b);
Assert.assertTrue(tb2 == alias2);
Assert.assertTrue(tb2 == alias3);
Assert.assertTrue(tb2 == alias3a);
Assert.assertTrue(tb2 == alias3b);
List tb2Aliases = Arrays.asList(getBeanFactory().getAliases("multiAliased"));
assertEquals(4, tb2Aliases.size());
assertTrue(tb2Aliases.contains("alias1"));
assertTrue(tb2Aliases.contains("alias2"));
assertTrue(tb2Aliases.contains("alias3"));
assertTrue(tb2Aliases.contains("alias4"));
assertTrue(beanNames.contains("multiAliased"));
assertFalse(beanNames.contains("alias1"));
assertFalse(beanNames.contains("alias2"));
assertFalse(beanNames.contains("alias3"));
assertFalse(beanNames.contains("alias4"));
Assert.assertEquals(4, tb2Aliases.size());
Assert.assertTrue(tb2Aliases.contains("alias1"));
Assert.assertTrue(tb2Aliases.contains("alias2"));
Assert.assertTrue(tb2Aliases.contains("alias3"));
Assert.assertTrue(tb2Aliases.contains("alias4"));
Assert.assertTrue(beanNames.contains("multiAliased"));
Assert.assertFalse(beanNames.contains("alias1"));
Assert.assertFalse(beanNames.contains("alias2"));
Assert.assertFalse(beanNames.contains("alias3"));
Assert.assertFalse(beanNames.contains("alias4"));
TestBean tb3 = (TestBean) getBeanFactory().getBean("aliasWithoutId1");
TestBean alias4 = (TestBean) getBeanFactory().getBean("aliasWithoutId2");
TestBean alias5 = (TestBean) getBeanFactory().getBean("aliasWithoutId3");
assertTrue(tb3 == alias4);
assertTrue(tb3 == alias5);
Assert.assertTrue(tb3 == alias4);
Assert.assertTrue(tb3 == alias5);
List tb3Aliases = Arrays.asList(getBeanFactory().getAliases("aliasWithoutId1"));
assertEquals(2, tb3Aliases.size());
assertTrue(tb3Aliases.contains("aliasWithoutId2"));
assertTrue(tb3Aliases.contains("aliasWithoutId3"));
assertTrue(beanNames.contains("aliasWithoutId1"));
assertFalse(beanNames.contains("aliasWithoutId2"));
assertFalse(beanNames.contains("aliasWithoutId3"));
Assert.assertEquals(2, tb3Aliases.size());
Assert.assertTrue(tb3Aliases.contains("aliasWithoutId2"));
Assert.assertTrue(tb3Aliases.contains("aliasWithoutId3"));
Assert.assertTrue(beanNames.contains("aliasWithoutId1"));
Assert.assertFalse(beanNames.contains("aliasWithoutId2"));
Assert.assertFalse(beanNames.contains("aliasWithoutId3"));
TestBean tb4 = (TestBean) getBeanFactory().getBean(TestBean.class.getName() + "#0");
assertEquals(null, tb4.getName());
Assert.assertEquals(null, tb4.getName());
Map drs = getListableBeanFactory().getBeansOfType(DummyReferencer.class, false, false);
assertEquals(5, drs.size());
assertTrue(drs.containsKey(DummyReferencer.class.getName() + "#0"));
assertTrue(drs.containsKey(DummyReferencer.class.getName() + "#1"));
assertTrue(drs.containsKey(DummyReferencer.class.getName() + "#2"));
Assert.assertEquals(5, drs.size());
Assert.assertTrue(drs.containsKey(DummyReferencer.class.getName() + "#0"));
Assert.assertTrue(drs.containsKey(DummyReferencer.class.getName() + "#1"));
Assert.assertTrue(drs.containsKey(DummyReferencer.class.getName() + "#2"));
}
public void testFactoryNesting() {
ITestBean father = (ITestBean) getBeanFactory().getBean("father");
assertTrue("Bean from root context", father != null);
Assert.assertTrue("Bean from root context", father != null);
TestBean rod = (TestBean) getBeanFactory().getBean("rod");
assertTrue("Bean from child context", "Rod".equals(rod.getName()));
assertTrue("Bean has external reference", rod.getSpouse() == father);
Assert.assertTrue("Bean from child context", "Rod".equals(rod.getName()));
Assert.assertTrue("Bean has external reference", rod.getSpouse() == father);
rod = (TestBean) parent.getBean("rod");
assertTrue("Bean from root context", "Roderick".equals(rod.getName()));
Assert.assertTrue("Bean from root context", "Roderick".equals(rod.getName()));
}
public void testFactoryReferences() {
DummyFactory factory = (DummyFactory) getBeanFactory().getBean("&singletonFactory");
DummyReferencer ref = (DummyReferencer) getBeanFactory().getBean("factoryReferencer");
assertTrue(ref.getTestBean1() == ref.getTestBean2());
assertTrue(ref.getDummyFactory() == factory);
Assert.assertTrue(ref.getTestBean1() == ref.getTestBean2());
Assert.assertTrue(ref.getDummyFactory() == factory);
DummyReferencer ref2 = (DummyReferencer) getBeanFactory().getBean("factoryReferencerWithConstructor");
assertTrue(ref2.getTestBean1() == ref2.getTestBean2());
assertTrue(ref2.getDummyFactory() == factory);
Assert.assertTrue(ref2.getTestBean1() == ref2.getTestBean2());
Assert.assertTrue(ref2.getDummyFactory() == factory);
}
public void testPrototypeReferences() {
// check that not broken by circular reference resolution mechanism
DummyReferencer ref1 = (DummyReferencer) getBeanFactory().getBean("prototypeReferencer");
assertTrue("Not referencing same bean twice", ref1.getTestBean1() != ref1.getTestBean2());
Assert.assertTrue("Not referencing same bean twice", ref1.getTestBean1() != ref1.getTestBean2());
DummyReferencer ref2 = (DummyReferencer) getBeanFactory().getBean("prototypeReferencer");
assertTrue("Not the same referencer", ref1 != ref2);
assertTrue("Not referencing same bean twice", ref2.getTestBean1() != ref2.getTestBean2());
assertTrue("Not referencing same bean twice", ref1.getTestBean1() != ref2.getTestBean1());
assertTrue("Not referencing same bean twice", ref1.getTestBean2() != ref2.getTestBean2());
assertTrue("Not referencing same bean twice", ref1.getTestBean1() != ref2.getTestBean2());
Assert.assertTrue("Not the same referencer", ref1 != ref2);
Assert.assertTrue("Not referencing same bean twice", ref2.getTestBean1() != ref2.getTestBean2());
Assert.assertTrue("Not referencing same bean twice", ref1.getTestBean1() != ref2.getTestBean1());
Assert.assertTrue("Not referencing same bean twice", ref1.getTestBean2() != ref2.getTestBean2());
Assert.assertTrue("Not referencing same bean twice", ref1.getTestBean1() != ref2.getTestBean2());
}
public void testBeanPostProcessor() throws Exception {
@ -205,22 +207,22 @@ public class XmlListableBeanFactoryTests extends AbstractListableBeanFactoryTest
TestBean kathy = (TestBean) getBeanFactory().getBean("kathy");
DummyFactory factory = (DummyFactory) getBeanFactory().getBean("&singletonFactory");
TestBean factoryCreated = (TestBean) getBeanFactory().getBean("singletonFactory");
assertTrue(kerry.isPostProcessed());
assertTrue(kathy.isPostProcessed());
assertTrue(factory.isPostProcessed());
assertTrue(factoryCreated.isPostProcessed());
Assert.assertTrue(kerry.isPostProcessed());
Assert.assertTrue(kathy.isPostProcessed());
Assert.assertTrue(factory.isPostProcessed());
Assert.assertTrue(factoryCreated.isPostProcessed());
}
public void testEmptyValues() {
TestBean rod = (TestBean) getBeanFactory().getBean("rod");
TestBean kerry = (TestBean) getBeanFactory().getBean("kerry");
assertTrue("Touchy is empty", "".equals(rod.getTouchy()));
assertTrue("Touchy is empty", "".equals(kerry.getTouchy()));
Assert.assertTrue("Touchy is empty", "".equals(rod.getTouchy()));
Assert.assertTrue("Touchy is empty", "".equals(kerry.getTouchy()));
}
public void testCommentsAndCdataInValue() {
TestBean bean = (TestBean) getBeanFactory().getBean("commentsInValue");
assertEquals("Failed to handle comments and CDATA properly", "this is a <!--comment-->", bean.getName());
Assert.assertEquals("Failed to handle comments and CDATA properly", "this is a <!--comment-->", bean.getName());
}
}

View File

@ -0,0 +1,127 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
<beans>
<bean id="validEmptyWithDescription" class="org.springframework.beans.TestBean">
<description>
I have no properties and I'm happy without them.
</description>
</bean>
<!--
Check automatic creation of alias, to allow for names that are illegal as XML ids.
-->
<bean id="aliased" class=" org.springframework.beans.TestBean " name="myalias">
<property name="name"><value>aliased</value></property>
</bean>
<alias name="aliased" alias="youralias"/>
<alias name="multiAliased" alias="alias3"/>
<bean id="multiAliased" class="org.springframework.beans.TestBean" name="alias1,alias2">
<property name="name"><value>aliased</value></property>
</bean>
<alias name="multiAliased" alias="alias4"/>
<bean class="org.springframework.beans.TestBean" name="aliasWithoutId1,aliasWithoutId2,aliasWithoutId3">
<property name="name"><value>aliased</value></property>
</bean>
<bean class="org.springframework.beans.TestBean">
<property name="name"><null/></property>
</bean>
<bean class="org.springframework.beans.factory.xml.DummyReferencer"/>
<bean class="org.springframework.beans.factory.xml.DummyReferencer"/>
<bean class="org.springframework.beans.factory.xml.DummyReferencer"/>
<bean id="rod" class="org.springframework.beans.TestBean">
<property name="name"><value><!-- a comment -->Rod</value></property>
<property name="age"><value>31</value></property>
<property name="spouse"><ref bean="father"/></property>
<property name="touchy"><value/></property>
</bean>
<bean id="roderick" parent="rod">
<property name="name"><value>Roderick<!-- a comment --></value></property>
<!-- Should inherit age -->
</bean>
<bean id="kerry" class="org.springframework.beans.TestBean">
<property name="name"><value>Ker<!-- a comment -->ry</value></property>
<property name="age"><value>34</value></property>
<property name="spouse"><ref local="rod"/></property>
<property name="touchy"><value></value></property>
</bean>
<bean id="kathy" class="org.springframework.beans.TestBean" scope="prototype">
<property name="name"><value>Kathy</value></property>
<property name="age"><value>28</value></property>
<property name="spouse"><ref bean="father"/></property>
</bean>
<bean id="typeMismatch" class="org.springframework.beans.TestBean" scope="prototype">
<property name="name"><value>typeMismatch</value></property>
<property name="age"><value>34x</value></property>
<property name="spouse"><ref local="rod"/></property>
</bean>
<!-- Test of lifecycle callbacks -->
<bean id="mustBeInitialized" class="org.springframework.beans.factory.MustBeInitialized"/>
<bean id="lifecycle" class="org.springframework.beans.factory.LifecycleBean"
init-method="declaredInitMethod">
<property name="initMethodDeclared"><value>true</value></property>
</bean>
<bean id="protectedLifecycle" class="org.springframework.beans.factory.xml.ProtectedLifecycleBean"
init-method="declaredInitMethod">
<property name="initMethodDeclared"><value>true</value></property>
</bean>
<!-- Factory beans are automatically treated differently -->
<bean id="singletonFactory" class="org.springframework.beans.factory.DummyFactory">
</bean>
<bean id="prototypeFactory" class="org.springframework.beans.factory.DummyFactory">
<property name="singleton"><value>false</value></property>
</bean>
<!-- Check that the circular reference resolution mechanism doesn't break
repeated references to the same FactoryBean -->
<bean id="factoryReferencer" class="org.springframework.beans.factory.xml.DummyReferencer">
<property name="testBean1"><ref bean="singletonFactory"/></property>
<property name="testBean2"><ref local="singletonFactory"/></property>
<property name="dummyFactory"><ref bean="&amp;singletonFactory"/></property>
</bean>
<bean id="factoryReferencerWithConstructor" class="org.springframework.beans.factory.xml.DummyReferencer">
<constructor-arg><ref bean="&amp;singletonFactory"/></constructor-arg>
<property name="testBean1"><ref bean="singletonFactory"/></property>
<property name="testBean2"><ref local="singletonFactory"/></property>
</bean>
<!-- Check that the circular reference resolution mechanism doesn't break
prototype instantiation -->
<bean id="prototypeReferencer" class="org.springframework.beans.factory.xml.DummyReferencer" scope="prototype">
<property name="testBean1"><ref local="kathy"/></property>
<property name="testBean2"><ref bean="kathy"/></property>
</bean>
<bean id="listenerVeto" class="org.springframework.beans.TestBean">
<property name="name"><value>listenerVeto</value></property>
<property name="age"><value>66</value></property>
</bean>
<bean id="validEmpty" class="org.springframework.beans.TestBean"/>
<bean id="commentsInValue" class="org.springframework.beans.TestBean">
<property name="name"><value>this is<!-- don't mind me --> a <![CDATA[<!--comment-->]]></value></property>
</bean>
</beans>

View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
This is a top level block comment
-->
<!-- here is a line comment -->
<!-- trying --> <!-- to trick --> <!--
the parser now --> <!-- <beans>
-->
<!-- more trickery--> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd"><!-- some nasty stuff -->
<beans>
<bean id="testBean" class="org.springframework.beans.TestBean"/>
</beans>

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
This is a top level block comment
-->
<!-- here is a line comment -->
<!-- trying --> <!-- to trick --> <!--
the parser now --> <!-- <beans>
-->
<!-- more trickery--><beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"><!-- end -->
<bean id="testBean" class="org.springframework.beans.TestBean"/>
</beans>