+ Moving .config.java module -> .context
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright 2002-2009 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.context.annotation.configuration;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.springframework.beans.factory.support.BeanDefinitionBuilder.*;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.aop.support.AopUtils;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.support.ConfigurationClassPostProcessor;
|
||||
|
||||
|
||||
/**
|
||||
* Covers the somewhat unlilely case of a {@link Configuration} class being declared
|
||||
* as an abstract {@link BeanDefinition}.
|
||||
*
|
||||
* @author Chris Beams
|
||||
* @see BeanDefinition#isAbstract()
|
||||
*/
|
||||
public class AbstractBeanDefinitionConfigurationClassTests {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@Test
|
||||
public void abstractConfigurationClassBeanDefinitionsAreIgnored() {
|
||||
@Configuration class Abstract { @Bean Object foo1() { return null; } }
|
||||
@Configuration class Concrete { @Bean Object foo2() { return null; } }
|
||||
|
||||
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
|
||||
factory.registerBeanDefinition("abstract",
|
||||
rootBeanDefinition(Abstract.class).setAbstract(true).getBeanDefinition());
|
||||
factory.registerBeanDefinition("concrete",
|
||||
rootBeanDefinition(Concrete.class).setAbstract(false).getBeanDefinition());
|
||||
new ConfigurationClassPostProcessor().postProcessBeanFactory(factory);
|
||||
|
||||
assertTrue("abstract configuration should be CGLIB-enhanced",
|
||||
AopUtils.isCglibProxyClassName(factory.getBeanDefinition("abstract").getBeanClassName()));
|
||||
assertTrue("concrete configuration should be CGLIB-enhanced",
|
||||
AopUtils.isCglibProxyClassName(factory.getBeanDefinition("concrete").getBeanClassName()));
|
||||
|
||||
assertFalse("abstract configuration's @Bean method should not be registered",
|
||||
factory.containsBeanDefinition("foo1"));
|
||||
assertTrue("concrete configuration's @Bean method should be registered",
|
||||
factory.containsBeanDefinition("foo2"));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package org.springframework.context.annotation.configuration;
|
||||
|
||||
import org.junit.Before;
|
||||
|
||||
|
||||
public abstract class AbstractJavaConfigTests {
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
|
||||
}
|
||||
|
||||
// protected
|
||||
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
package org.springframework.context.annotation.configuration;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.aspectj.lang.annotation.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||
import org.springframework.beans.factory.xml.XmlBeanFactory;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.support.ConfigurationClassPostProcessor;
|
||||
import org.springframework.context.support.GenericApplicationContext;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
|
||||
import test.beans.TestBean;
|
||||
|
||||
|
||||
public class AspectTests {
|
||||
private void assertAdviceWasApplied(Class<?> configClass) {
|
||||
GenericApplicationContext ctx = new GenericApplicationContext(
|
||||
new XmlBeanFactory(new ClassPathResource("aspectj-autoproxy-config.xml", AspectTests.class)));
|
||||
ctx.addBeanFactoryPostProcessor(new ConfigurationClassPostProcessor());
|
||||
ctx.registerBeanDefinition("config", new RootBeanDefinition(configClass));
|
||||
ctx.refresh();
|
||||
|
||||
TestBean testBean = ctx.getBean("testBean", TestBean.class);
|
||||
assertThat(testBean.getName(), equalTo("name"));
|
||||
testBean.absquatulate();
|
||||
assertThat(testBean.getName(), equalTo("advisedName"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void aspectAnnotatedConfiguration() {
|
||||
assertAdviceWasApplied(AspectConfig.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void configurationIncludesAspect() {
|
||||
assertAdviceWasApplied(ConfigurationWithAspect.class);
|
||||
}
|
||||
|
||||
|
||||
@Aspect
|
||||
@Configuration
|
||||
static class AspectConfig {
|
||||
@Bean
|
||||
public TestBean testBean() {
|
||||
return new TestBean("name");
|
||||
}
|
||||
|
||||
@Before("execution(* test.beans.TestBean.absquatulate(..)) && target(testBean)")
|
||||
public void touchBean(TestBean testBean) {
|
||||
testBean.setName("advisedName");
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class ConfigurationWithAspect {
|
||||
@Bean
|
||||
public TestBean testBean() {
|
||||
return new TestBean("name");
|
||||
}
|
||||
|
||||
@Bean
|
||||
public NameChangingAspect nameChangingAspect() {
|
||||
return new NameChangingAspect();
|
||||
}
|
||||
}
|
||||
|
||||
@Aspect
|
||||
static class NameChangingAspect {
|
||||
@Before("execution(* test.beans.TestBean.absquatulate(..)) && target(testBean)")
|
||||
public void touchBean(TestBean testBean) {
|
||||
testBean.setName("advisedName");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
package org.springframework.context.annotation.configuration;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
|
||||
import test.beans.Colour;
|
||||
import test.beans.TestBean;
|
||||
|
||||
|
||||
public class AutowiredConfigurationTests {
|
||||
public @Test
|
||||
void test() {
|
||||
ClassPathXmlApplicationContext factory = new ClassPathXmlApplicationContext(
|
||||
AutowiredConfigurationTests.class.getSimpleName() + ".xml", AutowiredConfigurationTests.class);
|
||||
|
||||
assertThat(factory.getBean("colour", Colour.class), equalTo(Colour.RED));
|
||||
assertThat(factory.getBean("testBean", TestBean.class).getName(), equalTo(Colour.RED.toString()));
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class AutowiredConfig {
|
||||
private @Autowired
|
||||
Colour colour;
|
||||
|
||||
public @Bean
|
||||
TestBean testBean() {
|
||||
return new TestBean(colour.toString());
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class ColorConfig {
|
||||
public @Bean
|
||||
Colour colour() {
|
||||
return Colour.RED;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public @Test
|
||||
void testValueInjection() {
|
||||
System.setProperty("myProp", "foo");
|
||||
|
||||
ClassPathXmlApplicationContext factory = new ClassPathXmlApplicationContext(
|
||||
"ValueInjectionTests.xml", AutowiredConfigurationTests.class);
|
||||
|
||||
TestBean testBean = factory.getBean("testBean", TestBean.class);
|
||||
assertThat(testBean.getName(), equalTo("foo"));
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class ValueConfig {
|
||||
|
||||
@Value("#{systemProperties.myProp}")
|
||||
private String name = "default";
|
||||
|
||||
public @Bean
|
||||
TestBean testBean() {
|
||||
return new TestBean(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<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.xsd
|
||||
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"
|
||||
xmlns:context="http://www.springframework.org/schema/context">
|
||||
|
||||
<context:annotation-config/>
|
||||
|
||||
<bean class="org.springframework.context.annotation.support.ConfigurationClassPostProcessor"/>
|
||||
|
||||
<bean class="org.springframework.context.annotation.configuration.AutowiredConfigurationTests$AutowiredConfig"/>
|
||||
<bean class="org.springframework.context.annotation.configuration.AutowiredConfigurationTests$ColorConfig"/>
|
||||
|
||||
</beans>
|
||||
@@ -0,0 +1,159 @@
|
||||
package org.springframework.context.annotation.configuration;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.springframework.beans.factory.support.BeanDefinitionBuilder.*;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
import org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.parsing.BeanDefinitionParsingException;
|
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.context.annotation.StandardScopes;
|
||||
import org.springframework.context.annotation.support.ConfigurationClassPostProcessor;
|
||||
|
||||
import test.beans.ITestBean;
|
||||
import test.beans.TestBean;
|
||||
|
||||
|
||||
public class BasicTests {
|
||||
|
||||
/**
|
||||
* Creates a new {@link BeanFactory}, populates it with a {@link BeanDefinition} for
|
||||
* each of the given {@link Configuration} <var>configClasses</var>, and then
|
||||
* post-processes the factory using JavaConfig's {@link ConfigurationClassPostProcessor}.
|
||||
* When complete, the factory is ready to service requests for any {@link Bean} methods
|
||||
* declared by <var>configClasses</var>.
|
||||
*
|
||||
* @param configClasses the {@link Configuration} classes under test. may be an empty
|
||||
* list.
|
||||
*
|
||||
* @return fully initialized and post-processed {@link BeanFactory}
|
||||
*/
|
||||
private static BeanFactory initBeanFactory(Class<?>... configClasses) {
|
||||
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
|
||||
|
||||
for (Class<?> configClass : configClasses) {
|
||||
String configBeanName = configClass.getName();
|
||||
factory.registerBeanDefinition(configBeanName, rootBeanDefinition(configClass).getBeanDefinition());
|
||||
}
|
||||
|
||||
new ConfigurationClassPostProcessor().postProcessBeanFactory(factory);
|
||||
|
||||
factory.addBeanPostProcessor(new AutowiredAnnotationBeanPostProcessor());
|
||||
|
||||
return factory;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void customBeanNameIsRespected() {
|
||||
BeanFactory factory = initBeanFactory(ConfigWithBeanWithCustomName.class);
|
||||
assertSame(factory.getBean("customName"), ConfigWithBeanWithCustomName.testBean);
|
||||
|
||||
// method name should not be registered
|
||||
try {
|
||||
factory.getBean("methodName");
|
||||
fail("bean should not have been registered with 'methodName'");
|
||||
} catch (NoSuchBeanDefinitionException ex) { /* expected */ }
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class ConfigWithBeanWithCustomName {
|
||||
static TestBean testBean = new TestBean();
|
||||
@Bean(name="customName")
|
||||
public TestBean methodName() {
|
||||
return testBean;
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void aliasesAreRespected() {
|
||||
BeanFactory factory = initBeanFactory(ConfigWithBeanWithAliases.class);
|
||||
assertSame(factory.getBean("name1"), ConfigWithBeanWithAliases.testBean);
|
||||
String[] aliases = factory.getAliases("name1");
|
||||
for(String alias : aliases)
|
||||
assertSame(factory.getBean(alias), ConfigWithBeanWithAliases.testBean);
|
||||
|
||||
// method name should not be registered
|
||||
try {
|
||||
factory.getBean("methodName");
|
||||
fail("bean should not have been registered with 'methodName'");
|
||||
} catch (NoSuchBeanDefinitionException ex) { /* expected */ }
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class ConfigWithBeanWithAliases {
|
||||
static TestBean testBean = new TestBean();
|
||||
@Bean(name={"name1", "alias1", "alias2", "alias3"})
|
||||
public TestBean methodName() {
|
||||
return testBean;
|
||||
}
|
||||
}
|
||||
|
||||
@Test(expected=BeanDefinitionParsingException.class)
|
||||
public void testFinalBeanMethod() {
|
||||
initBeanFactory(ConfigWithFinalBean.class);
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class ConfigWithFinalBean {
|
||||
public final @Bean TestBean testBean() {
|
||||
return new TestBean();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void simplestPossibleConfiguration() {
|
||||
BeanFactory factory = initBeanFactory(SimplestPossibleConfig.class);
|
||||
|
||||
String stringBean = factory.getBean("stringBean", String.class);
|
||||
|
||||
assertThat(stringBean, equalTo("foo"));
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class SimplestPossibleConfig {
|
||||
public @Bean String stringBean() {
|
||||
return "foo";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void configurationWithPrototypeScopedBeans() {
|
||||
BeanFactory factory = initBeanFactory(ConfigWithPrototypeBean.class);
|
||||
|
||||
TestBean foo = factory.getBean("foo", TestBean.class);
|
||||
ITestBean bar = factory.getBean("bar", ITestBean.class);
|
||||
ITestBean baz = factory.getBean("baz", ITestBean.class);
|
||||
|
||||
assertThat(foo.getSpouse(), sameInstance(bar));
|
||||
assertThat(bar.getSpouse(), not(sameInstance(baz)));
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class ConfigWithPrototypeBean {
|
||||
public @Bean TestBean foo() {
|
||||
TestBean foo = new TestBean("foo");
|
||||
foo.setSpouse(bar());
|
||||
return foo;
|
||||
}
|
||||
|
||||
public @Bean TestBean bar() {
|
||||
TestBean bar = new TestBean("bar");
|
||||
bar.setSpouse(baz());
|
||||
return bar;
|
||||
}
|
||||
|
||||
@Bean @Scope(StandardScopes.PROTOTYPE)
|
||||
public TestBean baz() {
|
||||
return new TestBean("bar");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,275 @@
|
||||
/*
|
||||
* 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.context.annotation.configuration;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.factory.parsing.BeanDefinitionParsingException;
|
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.context.annotation.support.ConfigurationClassPostProcessor;
|
||||
|
||||
import test.beans.ITestBean;
|
||||
import test.beans.TestBean;
|
||||
|
||||
|
||||
/**
|
||||
* System tests for {@link Import} annotation support.
|
||||
*
|
||||
* @author Chris Beams
|
||||
*/
|
||||
public class ImportTests {
|
||||
|
||||
private DefaultListableBeanFactory processConfigurationClasses(Class<?>... classes) {
|
||||
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
|
||||
for (Class<?> clazz : classes)
|
||||
beanFactory.registerBeanDefinition(clazz.getSimpleName(), new RootBeanDefinition(clazz));
|
||||
new ConfigurationClassPostProcessor().postProcessBeanFactory(beanFactory);
|
||||
return beanFactory;
|
||||
}
|
||||
|
||||
private void assertBeanDefinitionCount(int expectedCount, Class<?>... classes) {
|
||||
DefaultListableBeanFactory beanFactory = processConfigurationClasses(classes);
|
||||
assertThat(beanFactory.getBeanDefinitionCount(), equalTo(expectedCount));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProcessImports() {
|
||||
int configClasses = 2;
|
||||
int beansInClasses = 2;
|
||||
|
||||
assertBeanDefinitionCount((configClasses + beansInClasses), ConfigurationWithImportAnnotation.class);
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@Import(OtherConfiguration.class)
|
||||
static class ConfigurationWithImportAnnotation {
|
||||
@Bean
|
||||
public ITestBean one() {
|
||||
return new TestBean();
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class OtherConfiguration {
|
||||
@Bean
|
||||
public ITestBean two() {
|
||||
return new TestBean();
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
@Test
|
||||
public void testImportAnnotationWithTwoLevelRecursion() {
|
||||
int configClasses = 2;
|
||||
int beansInClasses = 3;
|
||||
|
||||
assertBeanDefinitionCount((configClasses + beansInClasses), AppConfig.class);
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@Import(DataSourceConfig.class)
|
||||
static class AppConfig {
|
||||
|
||||
@Bean
|
||||
public ITestBean transferService() {
|
||||
return new TestBean(accountRepository());
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ITestBean accountRepository() {
|
||||
return new TestBean();
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class DataSourceConfig {
|
||||
@Bean
|
||||
public ITestBean dataSourceA() {
|
||||
return new TestBean();
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
@Test
|
||||
public void testImportAnnotationWithThreeLevelRecursion() {
|
||||
int configClasses = 3;
|
||||
int beansInClasses = 5;
|
||||
|
||||
assertBeanDefinitionCount((configClasses + beansInClasses), FirstLevel.class);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
@Test
|
||||
public void testImportAnnotationWithMultipleArguments() {
|
||||
int configClasses = 3;
|
||||
int beansInClasses = 3;
|
||||
|
||||
assertBeanDefinitionCount((configClasses + beansInClasses),
|
||||
WithMultipleArgumentsToImportAnnotation.class);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testImportAnnotationWithMultipleArgumentsResultingInOverriddenBeanDefinition() {
|
||||
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
|
||||
beanFactory.registerBeanDefinition("config", new RootBeanDefinition(
|
||||
WithMultipleArgumentsThatWillCauseDuplication.class));
|
||||
new ConfigurationClassPostProcessor().postProcessBeanFactory(beanFactory);
|
||||
assertThat(beanFactory.getBeanDefinitionCount(), equalTo(4));
|
||||
assertThat(beanFactory.getBean("foo", ITestBean.class).getName(), equalTo("foo2"));
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@Import( { Foo1.class, Foo2.class })
|
||||
static class WithMultipleArgumentsThatWillCauseDuplication {
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class Foo1 {
|
||||
@Bean
|
||||
public ITestBean foo() {
|
||||
return new TestBean("foo1");
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class Foo2 {
|
||||
@Bean
|
||||
public ITestBean foo() {
|
||||
return new TestBean("foo2");
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
@Test
|
||||
public void testImportAnnotationOnInnerClasses() {
|
||||
int configClasses = 2;
|
||||
int beansInClasses = 2;
|
||||
|
||||
assertBeanDefinitionCount((configClasses + beansInClasses), OuterConfig.InnerConfig.class);
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class OuterConfig {
|
||||
@Bean
|
||||
String whatev() {
|
||||
return "whatev";
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@Import(ExternalConfig.class)
|
||||
static class InnerConfig {
|
||||
@Bean
|
||||
public ITestBean innerBean() {
|
||||
return new TestBean();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class ExternalConfig {
|
||||
@Bean
|
||||
public ITestBean extBean() {
|
||||
return new TestBean();
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
@Configuration
|
||||
@Import(SecondLevel.class)
|
||||
static class FirstLevel {
|
||||
@Bean
|
||||
public TestBean m() {
|
||||
return new TestBean();
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@Import(ThirdLevel.class)
|
||||
static class SecondLevel {
|
||||
@Bean
|
||||
public TestBean n() {
|
||||
return new TestBean();
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class ThirdLevel {
|
||||
@Bean
|
||||
public ITestBean thirdLevelA() {
|
||||
return new TestBean();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ITestBean thirdLevelB() {
|
||||
return new TestBean();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ITestBean thirdLevelC() {
|
||||
return new TestBean();
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@Import( { LeftConfig.class, RightConfig.class })
|
||||
static class WithMultipleArgumentsToImportAnnotation {
|
||||
@Bean
|
||||
public TestBean m() {
|
||||
return new TestBean();
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class LeftConfig {
|
||||
@Bean
|
||||
public ITestBean left() {
|
||||
return new TestBean();
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class RightConfig {
|
||||
@Bean
|
||||
public ITestBean right() {
|
||||
return new TestBean();
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
@Test(expected=BeanDefinitionParsingException.class)
|
||||
public void testImportNonConfigurationAnnotationClassCausesError() {
|
||||
processConfigurationClasses(ConfigAnnotated.class);
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@Import(NonConfigAnnotated.class)
|
||||
static class ConfigAnnotated { }
|
||||
|
||||
static class NonConfigAnnotated { }
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright 2002-2009 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.context.annotation.configuration;
|
||||
|
||||
import java.lang.annotation.Inherited;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.support.ConfigurationClassPostProcessor;
|
||||
|
||||
import test.beans.TestBean;
|
||||
|
||||
/**
|
||||
* Tests that polymorphic Configuration classes need not explicitly redeclare the
|
||||
* {@link Configuration} annotation. This respects the {@link Inherited} nature
|
||||
* of the Configuration annotation, even though it's being detected via ASM.
|
||||
*
|
||||
* @author Chris Beams
|
||||
*/
|
||||
public class PolymorphicConfigurationTests {
|
||||
|
||||
@Test
|
||||
public void subclassNeedNotDeclareConfigurationAnnotation() {
|
||||
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
|
||||
beanFactory.registerBeanDefinition("config", new RootBeanDefinition(Config.class));
|
||||
new ConfigurationClassPostProcessor().postProcessBeanFactory(beanFactory);
|
||||
|
||||
beanFactory.getBean("testBean", TestBean.class);
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class SuperConfig {
|
||||
@Bean
|
||||
public TestBean testBean() {
|
||||
return new TestBean();
|
||||
}
|
||||
}
|
||||
|
||||
static class Config extends SuperConfig { }
|
||||
}
|
||||
@@ -0,0 +1,438 @@
|
||||
/*
|
||||
* Copyright 2002-2009 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.context.annotation.configuration;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.springframework.beans.factory.support.BeanDefinitionBuilder.*;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.aop.scope.ScopedObject;
|
||||
import org.springframework.beans.factory.ObjectFactory;
|
||||
import org.springframework.beans.factory.parsing.BeanDefinitionParsingException;
|
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.context.annotation.ScopedProxyMode;
|
||||
import org.springframework.context.annotation.StandardScopes;
|
||||
import org.springframework.context.annotation.support.ConfigurationClassPostProcessor;
|
||||
import org.springframework.context.support.GenericApplicationContext;
|
||||
|
||||
import test.beans.ITestBean;
|
||||
import test.beans.TestBean;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Tests that scopes are properly supported by using a custom Scope implementations
|
||||
* and scoped proxy {@link Bean} declarations.
|
||||
*
|
||||
* @author Costin Leau
|
||||
* @author Chris Beams
|
||||
*/
|
||||
public class ScopingTests {
|
||||
|
||||
public static String flag = "1";
|
||||
|
||||
private static final String SCOPE = "my scope";
|
||||
private CustomScope customScope;
|
||||
private GenericApplicationContext ctx;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
customScope = new CustomScope();
|
||||
ctx = createContext(customScope, ScopedConfigurationClass.class);
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
ctx.close();
|
||||
ctx = null;
|
||||
customScope = null;
|
||||
}
|
||||
|
||||
private GenericApplicationContext createContext(org.springframework.beans.factory.config.Scope customScope, Class<?> configClass) {
|
||||
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
|
||||
if(customScope != null)
|
||||
beanFactory.registerScope(SCOPE, customScope);
|
||||
beanFactory.registerBeanDefinition("config",
|
||||
rootBeanDefinition(configClass).getBeanDefinition());
|
||||
GenericApplicationContext ctx = new GenericApplicationContext(beanFactory);
|
||||
ctx.addBeanFactoryPostProcessor(new ConfigurationClassPostProcessor());
|
||||
ctx.refresh();
|
||||
return ctx;
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testScopeOnClasses() throws Exception {
|
||||
genericTestScope("scopedClass");
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testScopeOnInterfaces() throws Exception {
|
||||
genericTestScope("scopedInterface");
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testSameScopeOnDifferentBeans() throws Exception {
|
||||
Object beanAInScope = ctx.getBean("scopedClass");
|
||||
Object beanBInScope = ctx.getBean("scopedInterface");
|
||||
|
||||
assertNotSame(beanAInScope, beanBInScope);
|
||||
|
||||
customScope.createNewScope = true;
|
||||
|
||||
Object newBeanAInScope = ctx.getBean("scopedClass");
|
||||
Object newBeanBInScope = ctx.getBean("scopedInterface");
|
||||
|
||||
assertNotSame(newBeanAInScope, newBeanBInScope);
|
||||
assertNotSame(newBeanAInScope, beanAInScope);
|
||||
assertNotSame(newBeanBInScope, beanBInScope);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testScopedProxyOnSingletonBeanMethod() throws Exception {
|
||||
// should throw - scoped proxies should not be applied on singleton/prototype beans
|
||||
try {
|
||||
createContext(null, InvalidProxyOnPredefinedScopesConfiguration.class);
|
||||
fail("exception expected");
|
||||
} catch (BeanDefinitionParsingException ex) {
|
||||
assertTrue(ex.getMessage().contains("scoped proxies cannot be created for singleton/prototype beans"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testRawScopes() throws Exception {
|
||||
|
||||
String beanName = "scopedProxyInterface";
|
||||
|
||||
// get hidden bean
|
||||
Object bean = ctx.getBean("scopedTarget." + beanName);
|
||||
|
||||
assertFalse(bean instanceof ScopedObject);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testScopedProxyConfiguration() throws Exception {
|
||||
|
||||
TestBean singleton = (TestBean) ctx.getBean("singletonWithScopedInterfaceDep");
|
||||
ITestBean spouse = singleton.getSpouse();
|
||||
assertTrue("scoped bean is not wrapped by the scoped-proxy", spouse instanceof ScopedObject);
|
||||
|
||||
String beanName = "scopedProxyInterface";
|
||||
|
||||
String scopedBeanName = "scopedTarget." + beanName;
|
||||
|
||||
// get hidden bean
|
||||
assertEquals(flag, spouse.getName());
|
||||
|
||||
ITestBean spouseFromBF = (ITestBean) ctx.getBean(scopedBeanName);
|
||||
assertEquals(spouse.getName(), spouseFromBF.getName());
|
||||
// the scope proxy has kicked in
|
||||
assertNotSame(spouse, spouseFromBF);
|
||||
|
||||
// create a new bean
|
||||
customScope.createNewScope = true;
|
||||
|
||||
// get the bean again from the BF
|
||||
spouseFromBF = (ITestBean) ctx.getBean(scopedBeanName);
|
||||
// make sure the name has been updated
|
||||
assertSame(spouse.getName(), spouseFromBF.getName());
|
||||
assertNotSame(spouse, spouseFromBF);
|
||||
|
||||
// get the bean again
|
||||
spouseFromBF = (ITestBean) ctx.getBean(scopedBeanName);
|
||||
assertSame(spouse.getName(), spouseFromBF.getName());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testScopedProxyConfigurationWithClasses() throws Exception {
|
||||
|
||||
TestBean singleton = (TestBean) ctx.getBean("singletonWithScopedClassDep");
|
||||
ITestBean spouse = singleton.getSpouse();
|
||||
assertTrue("scoped bean is not wrapped by the scoped-proxy", spouse instanceof ScopedObject);
|
||||
|
||||
String beanName = "scopedProxyClass";
|
||||
|
||||
String scopedBeanName = "scopedTarget." + beanName;
|
||||
|
||||
// get hidden bean
|
||||
assertEquals(flag, spouse.getName());
|
||||
|
||||
TestBean spouseFromBF = (TestBean) ctx.getBean(scopedBeanName);
|
||||
assertEquals(spouse.getName(), spouseFromBF.getName());
|
||||
// the scope proxy has kicked in
|
||||
assertNotSame(spouse, spouseFromBF);
|
||||
|
||||
// create a new bean
|
||||
customScope.createNewScope = true;
|
||||
flag = "boo";
|
||||
|
||||
// get the bean again from the BF
|
||||
spouseFromBF = (TestBean) ctx.getBean(scopedBeanName);
|
||||
// make sure the name has been updated
|
||||
assertSame(spouse.getName(), spouseFromBF.getName());
|
||||
assertNotSame(spouse, spouseFromBF);
|
||||
|
||||
// get the bean again
|
||||
spouseFromBF = (TestBean) ctx.getBean(scopedBeanName);
|
||||
assertSame(spouse.getName(), spouseFromBF.getName());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testScopedConfigurationBeanDefinitionCount() throws Exception {
|
||||
|
||||
// count the beans
|
||||
// 6 @Beans + 1 Configuration + 2 scoped proxy
|
||||
assertThat(ctx.getBeanDefinitionCount(), equalTo(9));
|
||||
}
|
||||
|
||||
// /**
|
||||
// * SJC-254 caught a regression in handling scoped proxies starting in 1.0 m4.
|
||||
// * The ScopedProxyFactoryBean object was having its scope set to that of its delegate
|
||||
// * whereas it should have remained singleton.
|
||||
// */
|
||||
// @Test
|
||||
// public void sjc254() {
|
||||
// JavaConfigWebApplicationContext ctx = new JavaConfigWebApplicationContext();
|
||||
// ctx.setConfigLocations(new String[] { ScopeTestConfiguration.class.getName() });
|
||||
// ctx.refresh();
|
||||
//
|
||||
// // should be fine
|
||||
// ctx.getBean(Bar.class);
|
||||
//
|
||||
// boolean threw = false;
|
||||
// try {
|
||||
// ctx.getBean(Foo.class);
|
||||
// } catch (BeanCreationException ex) {
|
||||
// if(ex.getCause() instanceof IllegalStateException) {
|
||||
// threw = true;
|
||||
// }
|
||||
// }
|
||||
// assertTrue(threw);
|
||||
// }
|
||||
|
||||
@Configuration
|
||||
static class ScopeTestConfiguration {
|
||||
|
||||
@Bean
|
||||
@Scope(value=StandardScopes.SESSION, proxyMode=ScopedProxyMode.INTERFACES)
|
||||
public Foo foo() {
|
||||
return new Foo();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Bar bar() {
|
||||
return new Bar(foo());
|
||||
}
|
||||
}
|
||||
|
||||
static class Foo {
|
||||
public Foo() {
|
||||
//System.out.println("created foo: " + this.getClass().getName());
|
||||
}
|
||||
|
||||
public void doSomething() {
|
||||
//System.out.println("interesting: " + this);
|
||||
}
|
||||
}
|
||||
|
||||
static class Bar {
|
||||
|
||||
private final Foo foo;
|
||||
|
||||
public Bar(Foo foo) {
|
||||
this.foo = foo;
|
||||
//System.out.println("created bar: " + this);
|
||||
}
|
||||
|
||||
public Foo getFoo() {
|
||||
return foo;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void genericTestScope(String beanName) throws Exception {
|
||||
String message = "scope is ignored";
|
||||
Object bean1 = ctx.getBean(beanName);
|
||||
Object bean2 = ctx.getBean(beanName);
|
||||
|
||||
assertSame(message, bean1, bean2);
|
||||
|
||||
Object bean3 = ctx.getBean(beanName);
|
||||
|
||||
assertSame(message, bean1, bean3);
|
||||
|
||||
// make the scope create a new object
|
||||
customScope.createNewScope = true;
|
||||
|
||||
Object newBean1 = ctx.getBean(beanName);
|
||||
assertNotSame(message, bean1, newBean1);
|
||||
|
||||
Object sameBean1 = ctx.getBean(beanName);
|
||||
|
||||
assertSame(message, newBean1, sameBean1);
|
||||
|
||||
// make the scope create a new object
|
||||
customScope.createNewScope = true;
|
||||
|
||||
Object newBean2 = ctx.getBean(beanName);
|
||||
assertNotSame(message, newBean1, newBean2);
|
||||
|
||||
// make the scope create a new object .. again
|
||||
customScope.createNewScope = true;
|
||||
|
||||
Object newBean3 = ctx.getBean(beanName);
|
||||
assertNotSame(message, newBean2, newBean3);
|
||||
}
|
||||
|
||||
@Configuration
|
||||
public static class InvalidProxyOnPredefinedScopesConfiguration {
|
||||
@Bean @Scope(proxyMode=ScopedProxyMode.INTERFACES)
|
||||
public Object invalidProxyOnPredefinedScopes() { return new Object(); }
|
||||
}
|
||||
|
||||
@Configuration
|
||||
public static class ScopedConfigurationClass {
|
||||
@Bean
|
||||
@Scope(SCOPE)
|
||||
public TestBean scopedClass() {
|
||||
TestBean tb = new TestBean();
|
||||
tb.setName(flag);
|
||||
return tb;
|
||||
}
|
||||
|
||||
@Bean
|
||||
@Scope(SCOPE)
|
||||
public ITestBean scopedInterface() {
|
||||
TestBean tb = new TestBean();
|
||||
tb.setName(flag);
|
||||
return tb;
|
||||
}
|
||||
|
||||
@Bean
|
||||
@Scope(value=SCOPE, proxyMode=ScopedProxyMode.TARGET_CLASS)
|
||||
public ITestBean scopedProxyInterface() {
|
||||
TestBean tb = new TestBean();
|
||||
tb.setName(flag);
|
||||
return tb;
|
||||
}
|
||||
|
||||
@Bean
|
||||
@Scope(value=SCOPE, proxyMode=ScopedProxyMode.TARGET_CLASS)
|
||||
public TestBean scopedProxyClass() {
|
||||
TestBean tb = new TestBean();
|
||||
tb.setName(flag);
|
||||
return tb;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public TestBean singletonWithScopedClassDep() {
|
||||
TestBean singleton = new TestBean();
|
||||
singleton.setSpouse(scopedProxyClass());
|
||||
return singleton;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public TestBean singletonWithScopedInterfaceDep() {
|
||||
TestBean singleton = new TestBean();
|
||||
singleton.setSpouse(scopedProxyInterface());
|
||||
return singleton;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Simple scope implementation which creates object based on a flag.
|
||||
*
|
||||
* @author Costin Leau
|
||||
* @author Chris Beams
|
||||
*/
|
||||
class CustomScope implements org.springframework.beans.factory.config.Scope {
|
||||
|
||||
public boolean createNewScope = true;
|
||||
|
||||
private Map<String, Object> beans = new HashMap<String, Object>();
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.beans.factory.config.Scope#get(java.lang.String,
|
||||
* org.springframework.beans.factory.ObjectFactory)
|
||||
*/
|
||||
public Object get(String name, ObjectFactory<?> objectFactory) {
|
||||
if (createNewScope) {
|
||||
beans.clear();
|
||||
// reset the flag back
|
||||
createNewScope = false;
|
||||
}
|
||||
|
||||
Object bean = beans.get(name);
|
||||
// if a new object is requested or none exists under the current
|
||||
// name, create one
|
||||
if (bean == null) {
|
||||
beans.put(name, objectFactory.getObject());
|
||||
}
|
||||
|
||||
return beans.get(name);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.beans.factory.config.Scope#getConversationId()
|
||||
*/
|
||||
public String getConversationId() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.beans.factory.config.Scope#registerDestructionCallback(java.lang.String,
|
||||
* java.lang.Runnable)
|
||||
*/
|
||||
public void registerDestructionCallback(String name, Runnable callback) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.beans.factory.config.Scope#remove(java.lang.String)
|
||||
*/
|
||||
public Object remove(String name) {
|
||||
return beans.remove(name);
|
||||
}
|
||||
|
||||
public Object resolveContextualObject(String key) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<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.xsd
|
||||
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"
|
||||
xmlns:context="http://www.springframework.org/schema/context">
|
||||
|
||||
<context:annotation-config/>
|
||||
|
||||
<bean class="org.springframework.context.annotation.support.ConfigurationClassPostProcessor"/>
|
||||
|
||||
<bean class="org.springframework.context.annotation.configuration.AutowiredConfigurationTests$ValueConfig"/>
|
||||
|
||||
<!--
|
||||
<context:component-scan base-package="test.basic.value"/>
|
||||
-->
|
||||
</beans>
|
||||
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:aop="http://www.springframework.org/schema/aop"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
|
||||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"
|
||||
xmlns:context="http://www.springframework.org/schema/context">
|
||||
|
||||
<aop:aspectj-autoproxy proxy-target-class="true"/>
|
||||
</beans>
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright 2002-2009 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Integration tests for {@link org.springframework.context.annotation.Configuration}
|
||||
* class processing.
|
||||
*
|
||||
* @author Chris Beams
|
||||
* @see org.springframework.context.annotation.Configuration
|
||||
* @see org.springframework.context.annotation.Bean
|
||||
* @see org.springframework.context.annotation.support.ConfigurationClassPostProcessor
|
||||
*/
|
||||
package org.springframework.context.annotation.configuration;
|
||||
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
* Copyright 2002-2009 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.context.annotation.support;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.factory.parsing.BeanDefinitionParsingException;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.context.annotation.support.ConfigurationParser;
|
||||
|
||||
import test.beans.TestBean;
|
||||
|
||||
|
||||
/**
|
||||
* TCK-style unit tests for handling circular use of the {@link Import} annotation. Explore
|
||||
* subclass hierarchy for specific concrete implementations.
|
||||
*
|
||||
* @author Chris Beams
|
||||
*/
|
||||
public abstract class AbstractCircularImportDetectionTests {
|
||||
|
||||
protected abstract ConfigurationParser newParser();
|
||||
|
||||
protected abstract String loadAsConfigurationSource(Class<?> clazz) throws Exception;
|
||||
|
||||
@Test
|
||||
public void simpleCircularImportIsDetected() throws Exception {
|
||||
boolean threw = false;
|
||||
try {
|
||||
newParser().parse(loadAsConfigurationSource(A.class), null);
|
||||
} catch (BeanDefinitionParsingException ex) {
|
||||
assertTrue("Wrong message. Got: " + ex.getMessage(),
|
||||
ex.getMessage().contains(
|
||||
"Illegal attempt by @Configuration class 'AbstractCircularImportDetectionTests.B' " +
|
||||
"to import class 'AbstractCircularImportDetectionTests.A'"));
|
||||
threw = true;
|
||||
}
|
||||
|
||||
assertTrue(threw);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void complexCircularImportIsDetected() throws Exception {
|
||||
boolean threw = false;
|
||||
try {
|
||||
newParser().parse(loadAsConfigurationSource(X.class), null);
|
||||
} catch (BeanDefinitionParsingException ex) {
|
||||
assertTrue("Wrong message. Got: " + ex.getMessage(),
|
||||
ex.getMessage().contains(
|
||||
"Illegal attempt by @Configuration class 'AbstractCircularImportDetectionTests.Z2' " +
|
||||
"to import class 'AbstractCircularImportDetectionTests.Z'"));
|
||||
threw = true;
|
||||
}
|
||||
|
||||
assertTrue(threw);
|
||||
}
|
||||
|
||||
@Import(B.class)
|
||||
static class A {
|
||||
@Bean
|
||||
TestBean b1() {
|
||||
return new TestBean();
|
||||
}
|
||||
}
|
||||
|
||||
@Import(A.class)
|
||||
static class B {
|
||||
@Bean
|
||||
TestBean b2() {
|
||||
return new TestBean();
|
||||
}
|
||||
}
|
||||
|
||||
@Import( { Y.class, Z.class })
|
||||
class X {
|
||||
@Bean
|
||||
TestBean x() {
|
||||
return new TestBean();
|
||||
}
|
||||
}
|
||||
|
||||
class Y {
|
||||
@Bean
|
||||
TestBean y() {
|
||||
return new TestBean();
|
||||
}
|
||||
}
|
||||
|
||||
@Import( { Z1.class, Z2.class })
|
||||
class Z {
|
||||
@Bean
|
||||
TestBean z() {
|
||||
return new TestBean();
|
||||
}
|
||||
}
|
||||
|
||||
class Z1 {
|
||||
@Bean
|
||||
TestBean z1() {
|
||||
return new TestBean();
|
||||
}
|
||||
}
|
||||
|
||||
@Import(Z.class)
|
||||
class Z2 {
|
||||
@Bean
|
||||
TestBean z2() {
|
||||
return new TestBean();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright 2002-2009 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.context.annotation.support;
|
||||
|
||||
import org.springframework.beans.factory.parsing.FailFastProblemReporter;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.context.annotation.support.ConfigurationParser;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
|
||||
/**
|
||||
* Unit test proving that ASM-based {@link ConfigurationParser} correctly detects circular use of
|
||||
* the {@link Import @Import} annotation.
|
||||
*
|
||||
* <p>While this test is the only subclass of {@link AbstractCircularImportDetectionTests}, the
|
||||
* hierarchy remains in place in case a JDT-based ConfigurationParser implementation needs to be
|
||||
* developed.
|
||||
*
|
||||
* @author Chris Beams
|
||||
*/
|
||||
public class AsmCircularImportDetectionTests extends AbstractCircularImportDetectionTests {
|
||||
@Override
|
||||
protected ConfigurationParser newParser() {
|
||||
return new ConfigurationParser(new FailFastProblemReporter(), ClassUtils.getDefaultClassLoader());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String loadAsConfigurationSource(Class<?> clazz) throws Exception {
|
||||
return clazz.getName();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,182 @@
|
||||
/*
|
||||
* Copyright 2002-2009 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.context.annotation.support;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.springframework.context.annotation.ScopedProxyMode.*;
|
||||
import static org.springframework.context.annotation.StandardScopes.*;
|
||||
import static org.springframework.context.annotation.support.MutableAnnotationUtils.*;
|
||||
|
||||
import java.lang.reflect.Modifier;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.factory.parsing.BeanDefinitionParsingException;
|
||||
import org.springframework.beans.factory.parsing.FailFastProblemReporter;
|
||||
import org.springframework.beans.factory.parsing.Location;
|
||||
import org.springframework.beans.factory.parsing.ProblemReporter;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.context.annotation.support.BeanMethod;
|
||||
import org.springframework.context.annotation.support.ConfigurationClass;
|
||||
import org.springframework.context.annotation.support.ModelClass;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
|
||||
|
||||
/**
|
||||
* Unit tests for {@link BeanMethod}.
|
||||
*
|
||||
* @author Chris Beams
|
||||
*/
|
||||
public class BeanMethodTests {
|
||||
|
||||
private ProblemReporter problemReporter = new FailFastProblemReporter();
|
||||
private String beanName = "foo";
|
||||
private Bean beanAnno = createMutableAnnotation(Bean.class);
|
||||
private ModelClass returnType = new ModelClass("FooType");
|
||||
private ConfigurationClass declaringClass = new ConfigurationClass();
|
||||
{ declaringClass.setName("test.Config"); }
|
||||
|
||||
@Test
|
||||
public void testWellFormedMethod() {
|
||||
BeanMethod beanMethod = new BeanMethod(beanName, 0, returnType, beanAnno);
|
||||
|
||||
assertThat(beanMethod.getName(), sameInstance(beanName));
|
||||
assertThat(beanMethod.getModifiers(), equalTo(0));
|
||||
assertThat(beanMethod.getReturnType(), sameInstance(returnType));
|
||||
assertThat(beanMethod.getAnnotation(Bean.class), sameInstance(beanAnno));
|
||||
assertThat(beanMethod.getAnnotation(Override.class), nullValue());
|
||||
assertThat(beanMethod.getRequiredAnnotation(Bean.class), sameInstance(beanAnno));
|
||||
try {
|
||||
beanMethod.getRequiredAnnotation(Override.class);
|
||||
fail("expected IllegalArgumentException ex");
|
||||
} catch (IllegalArgumentException ex) { /* expected */ }
|
||||
|
||||
// must call setDeclaringClass() before calling getLocation()
|
||||
try {
|
||||
beanMethod.getLocation();
|
||||
fail("expected IllegalStateException ex");
|
||||
} catch (IllegalStateException ex) { /* expected */ }
|
||||
|
||||
|
||||
beanMethod.setDeclaringClass(declaringClass);
|
||||
assertThat(beanMethod.getDeclaringClass(), sameInstance(declaringClass));
|
||||
|
||||
beanMethod.setSource(12); // indicating a line number
|
||||
assertEquals(beanMethod.getSource(), 12);
|
||||
|
||||
Location location = beanMethod.getLocation();
|
||||
assertEquals(location.getResource(), new ClassPathResource("test/Config"));
|
||||
assertEquals(location.getSource(), 12);
|
||||
|
||||
// should validate without throwing as this is a well-formed method
|
||||
beanMethod.validate(problemReporter);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void finalMethodsAreIllegal() {
|
||||
BeanMethod beanMethod = new BeanMethod(beanName, Modifier.FINAL, returnType, beanAnno);
|
||||
beanMethod.setDeclaringClass(declaringClass);
|
||||
try {
|
||||
beanMethod.validate(problemReporter);
|
||||
fail("should have failed due to final bean method");
|
||||
} catch (BeanDefinitionParsingException ex) {
|
||||
assertTrue(ex.getMessage().contains("remove the final modifier"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void privateMethodsAreIllegal() {
|
||||
BeanMethod beanMethod = new BeanMethod(beanName, Modifier.PRIVATE, returnType, beanAnno);
|
||||
beanMethod.setDeclaringClass(declaringClass);
|
||||
try {
|
||||
beanMethod.validate(problemReporter);
|
||||
fail("should have failed due to private bean method");
|
||||
} catch (BeanDefinitionParsingException ex) {
|
||||
assertTrue(ex.getMessage().contains("increase the method's visibility"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void singletonInterfaceScopedProxiesAreIllegal() {
|
||||
Scope scope = SingletonInterfaceProxy.class.getAnnotation(Scope.class);
|
||||
BeanMethod beanMethod = new BeanMethod(beanName, 0, returnType, beanAnno, scope);
|
||||
beanMethod.setDeclaringClass(declaringClass);
|
||||
try {
|
||||
beanMethod.validate(problemReporter);
|
||||
fail("should have failed due to singleton with scoped proxy");
|
||||
} catch (Exception ex) {
|
||||
assertTrue(ex.getMessage().contains("cannot be created for singleton/prototype beans"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void singletonTargetClassScopedProxiesAreIllegal() {
|
||||
Scope scope = SingletonTargetClassProxy.class.getAnnotation(Scope.class);
|
||||
BeanMethod beanMethod = new BeanMethod(beanName, 0, returnType, beanAnno, scope);
|
||||
beanMethod.setDeclaringClass(declaringClass);
|
||||
try {
|
||||
beanMethod.validate(problemReporter);
|
||||
fail("should have failed due to singleton with scoped proxy");
|
||||
} catch (Exception ex) {
|
||||
assertTrue(ex.getMessage().contains("cannot be created for singleton/prototype beans"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void singletonsSansProxyAreLegal() {
|
||||
Scope scope = SingletonNoProxy.class.getAnnotation(Scope.class);
|
||||
BeanMethod beanMethod = new BeanMethod(beanName, 0, returnType, beanAnno, scope);
|
||||
beanMethod.setDeclaringClass(declaringClass);
|
||||
beanMethod.validate(problemReporter); // should validate without problems - it's legal
|
||||
}
|
||||
|
||||
@Test
|
||||
public void prototypeInterfaceScopedProxiesAreIllegal() {
|
||||
Scope scope = PrototypeInterfaceProxy.class.getAnnotation(Scope.class);
|
||||
BeanMethod beanMethod = new BeanMethod(beanName, 0, returnType, beanAnno, scope);
|
||||
beanMethod.setDeclaringClass(declaringClass);
|
||||
try {
|
||||
beanMethod.validate(problemReporter);
|
||||
fail("should have failed due to prototype with scoped proxy");
|
||||
} catch (Exception ex) {
|
||||
assertTrue(ex.getMessage().contains("cannot be created for singleton/prototype beans"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sessionInterfaceScopedProxiesAreLegal() {
|
||||
Scope scope = SessionInterfaceProxy.class.getAnnotation(Scope.class);
|
||||
BeanMethod beanMethod = new BeanMethod(beanName, 0, returnType, beanAnno, scope);
|
||||
beanMethod.setDeclaringClass(declaringClass);
|
||||
beanMethod.validate(problemReporter); // should validate without problems - it's legal
|
||||
}
|
||||
|
||||
@Scope(value=SINGLETON, proxyMode=INTERFACES)
|
||||
private class SingletonInterfaceProxy { }
|
||||
|
||||
@Scope(value=SINGLETON, proxyMode=TARGET_CLASS)
|
||||
private class SingletonTargetClassProxy { }
|
||||
|
||||
@Scope(value=SINGLETON, proxyMode=NO)
|
||||
private class SingletonNoProxy { }
|
||||
|
||||
@Scope(value=PROTOTYPE, proxyMode=INTERFACES)
|
||||
private class PrototypeInterfaceProxy { }
|
||||
|
||||
@Scope(value=SESSION, proxyMode=INTERFACES)
|
||||
private class SessionInterfaceProxy { }
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright 2002-2009 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.context.annotation.support;
|
||||
|
||||
import static java.lang.String.*;
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.context.annotation.support.ConfigurationClass;
|
||||
import org.springframework.context.annotation.support.ConfigurationModel;
|
||||
|
||||
|
||||
/**
|
||||
* Unit tests for {@link ConfigurationModel}.
|
||||
*
|
||||
* @author Chris Beams
|
||||
*/
|
||||
public class ConfigurationModelTests {
|
||||
|
||||
@Test
|
||||
public void testToString() {
|
||||
ConfigurationModel model = new ConfigurationModel();
|
||||
assertThat(model.toString(), equalTo(
|
||||
"ConfigurationModel containing @Configuration classes: []"));
|
||||
|
||||
ConfigurationClass config1 = new ConfigurationClass();
|
||||
config1.setName("test.Config1");
|
||||
model.add(config1);
|
||||
|
||||
assertThat(model.toString(), equalTo(format(
|
||||
"ConfigurationModel containing @Configuration classes: [%s]", config1)));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
/*
|
||||
* Copyright 2002-2009 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.context.annotation.support;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.springframework.beans.factory.support.BeanDefinitionBuilder.*;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Vector;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.support.ConfigurationClassPostProcessor;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
|
||||
/**
|
||||
* Unit tests for {@link ConfigurationClassPostProcessor}.
|
||||
*
|
||||
* @author Chris Beams
|
||||
*/
|
||||
public class ConfigurationPostProcessorTests {
|
||||
|
||||
private static final String ORIG_CGLIB_TEST_CLASS = ConfigurationClassPostProcessor.CGLIB_TEST_CLASS;
|
||||
private static final String BOGUS_CGLIB_TEST_CLASS = "a.bogus.class";
|
||||
|
||||
/**
|
||||
* CGLIB is an optional dependency for Spring. If users attempt
|
||||
* to use {@link Configuration} classes, they'll need it on the classpath;
|
||||
* if Configuration classes are present in the bean factory and CGLIB
|
||||
* is not present, an instructive exception should be thrown.
|
||||
*/
|
||||
@Test
|
||||
public void testFailFastIfCglibNotPresent() {
|
||||
@Configuration class Config { }
|
||||
|
||||
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
|
||||
factory.registerBeanDefinition("config", rootBeanDefinition(Config.class).getBeanDefinition());
|
||||
ConfigurationClassPostProcessor cpp = new ConfigurationClassPostProcessor();
|
||||
|
||||
// temporarily set the cglib test class to something bogus
|
||||
ConfigurationClassPostProcessor.CGLIB_TEST_CLASS = BOGUS_CGLIB_TEST_CLASS;
|
||||
|
||||
try {
|
||||
cpp.postProcessBeanFactory(factory);
|
||||
} catch (RuntimeException ex) {
|
||||
assertTrue(ex.getMessage().contains("CGLIB is required to process @Configuration classes"));
|
||||
} finally {
|
||||
ConfigurationClassPostProcessor.CGLIB_TEST_CLASS = ORIG_CGLIB_TEST_CLASS;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* In order to keep Spring's footprint as small as possible, CGLIB must
|
||||
* not be required on the classpath unless the user is taking advantage
|
||||
* of {@link Configuration} classes.
|
||||
*
|
||||
* This test will fail if any CGLIB classes are classloaded before the call
|
||||
* to {@link ConfigurationClassPostProcessor#enhanceConfigurationClasses}
|
||||
*/
|
||||
@Test
|
||||
public void testCglibClassesAreLoadedJustInTimeForEnhancement() throws Exception {
|
||||
ClassLoader classLoader = ClassUtils.getDefaultClassLoader();
|
||||
Field classesField = ClassLoader.class.getDeclaredField("classes");
|
||||
classesField.setAccessible(true);
|
||||
|
||||
// first, remove any CGLIB classes that may have been loaded by other tests
|
||||
@SuppressWarnings("unchecked")
|
||||
Vector<Class<?>> classes = (Vector<Class<?>>) classesField.get(classLoader);
|
||||
|
||||
Vector<Class<?>> cglibClassesAlreadyLoaded = new Vector<Class<?>>();
|
||||
for(Class<?> loadedClass : classes)
|
||||
if(loadedClass.getName().startsWith("net.sf.cglib"))
|
||||
cglibClassesAlreadyLoaded.add(loadedClass);
|
||||
|
||||
for(Class<?> cglibClass : cglibClassesAlreadyLoaded)
|
||||
classes.remove(cglibClass);
|
||||
|
||||
// now, execute a scenario where everything except enhancement occurs
|
||||
// -- no CGLIB classes should get loaded!
|
||||
testFailFastIfCglibNotPresent();
|
||||
|
||||
// test to ensure that indeed no CGLIB classes have been loaded
|
||||
for(Class<?> loadedClass : classes)
|
||||
if(loadedClass.getName().startsWith("net.sf.cglib"))
|
||||
fail("CGLIB class should not have been eagerly loaded: " + loadedClass.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Enhanced {@link Configuration} classes are only necessary for respecting
|
||||
* certain bean semantics, like singleton-scoping, scoped proxies, etc.
|
||||
*
|
||||
* Technically, {@link ConfigurationClassPostProcessor} could fail to enhance the
|
||||
* registered Configuration classes and many use cases would still work.
|
||||
* Certain cases, however, like inter-bean singleton references would not.
|
||||
* We test for such a case below, and in doing so prove that enhancement is
|
||||
* working.
|
||||
*/
|
||||
@Test
|
||||
public void testEnhancementIsPresentBecauseSingletonSemanticsAreRespected() {
|
||||
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
|
||||
beanFactory.registerBeanDefinition("config",
|
||||
rootBeanDefinition(SingletonBeanConfig.class).getBeanDefinition());
|
||||
new ConfigurationClassPostProcessor().postProcessBeanFactory(beanFactory);
|
||||
Foo foo = (Foo) beanFactory.getBean("foo");
|
||||
Bar bar = (Bar) beanFactory.getBean("bar");
|
||||
assertThat(foo, sameInstance(bar.foo));
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class SingletonBeanConfig {
|
||||
public @Bean Foo foo() {
|
||||
return new Foo();
|
||||
}
|
||||
|
||||
public @Bean Bar bar() {
|
||||
return new Bar(foo());
|
||||
}
|
||||
}
|
||||
|
||||
static class Foo { }
|
||||
static class Bar {
|
||||
final Foo foo;
|
||||
public Bar(Foo foo) { this.foo = foo; }
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright 2002-2009 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.context.annotation.support;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.springframework.beans.factory.support.BeanDefinitionBuilder.*;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.parsing.BeanDefinitionParsingException;
|
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.support.ConfigurationClassPostProcessor;
|
||||
|
||||
|
||||
/**
|
||||
* Unit tests covering cases where a user defines an invalid Configuration
|
||||
* class, e.g.: forgets to annotate with {@link Configuration} or declares
|
||||
* a Configuration class as final.
|
||||
*
|
||||
* @author Chris Beams
|
||||
*/
|
||||
public class InvalidConfigurationClassDefinitionTests {
|
||||
|
||||
@Test
|
||||
public void configurationClassesMayNotBeFinal() {
|
||||
@Configuration
|
||||
final class Config { }
|
||||
|
||||
BeanDefinition configBeanDef = rootBeanDefinition(Config.class).getBeanDefinition();
|
||||
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
|
||||
beanFactory.registerBeanDefinition("config", configBeanDef);
|
||||
|
||||
try {
|
||||
new ConfigurationClassPostProcessor().postProcessBeanFactory(beanFactory);
|
||||
fail("expected exception");
|
||||
} catch (BeanDefinitionParsingException ex) {
|
||||
assertTrue(ex.getMessage(), ex.getMessage().contains("Remove the final modifier"));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright 2002-2009 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Unit tests for support classes related to
|
||||
* {@link org.springframework.context.annotation.Configuration} class processing.
|
||||
*
|
||||
* @author Chris Beams
|
||||
*/
|
||||
package org.springframework.context.annotation.support;
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
* Copyright 2002-2009 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.
|
||||
@@ -49,7 +49,7 @@ import org.springframework.util.ObjectUtils;
|
||||
* @author Chris Beams
|
||||
*/
|
||||
public final class ClassPathXmlApplicationContextTests {
|
||||
|
||||
|
||||
private static final String PATH = "/org/springframework/context/support/";
|
||||
private static final String RESOURCE_CONTEXT = PATH + "ClassPathXmlApplicationContextTests-resource.xml";
|
||||
private static final String CONTEXT_WILDCARD = PATH + "test/context*.xml";
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* 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 test.beans;
|
||||
|
||||
import org.springframework.core.enums.ShortCodedLabeledEnum;
|
||||
|
||||
|
||||
/**
|
||||
* TODO: JAVADOC
|
||||
*
|
||||
* @author Rob Harrop
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public class Colour extends ShortCodedLabeledEnum {
|
||||
|
||||
public static final Colour RED = new Colour(0, "RED");
|
||||
|
||||
public static final Colour BLUE = new Colour(1, "BLUE");
|
||||
|
||||
public static final Colour GREEN = new Colour(2, "GREEN");
|
||||
|
||||
public static final Colour PURPLE = new Colour(3, "PURPLE");
|
||||
|
||||
private Colour(int code, String label) {
|
||||
super(code, label);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* 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 test.beans;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.beans.factory.ObjectFactory;
|
||||
import org.springframework.beans.factory.config.Scope;
|
||||
|
||||
|
||||
/**
|
||||
* Simple scope implementation which creates object based on a flag.
|
||||
*
|
||||
* @author Costin Leau
|
||||
* @author Chris Beams
|
||||
*/
|
||||
public class CustomScope implements Scope {
|
||||
|
||||
public boolean createNewScope = true;
|
||||
|
||||
private Map<String, Object> beans = new HashMap<String, Object>();
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.beans.factory.config.Scope#get(java.lang.String,
|
||||
* org.springframework.beans.factory.ObjectFactory)
|
||||
*/
|
||||
public Object get(String name, ObjectFactory<?> objectFactory) {
|
||||
if (createNewScope) {
|
||||
beans.clear();
|
||||
// reset the flag back
|
||||
createNewScope = false;
|
||||
}
|
||||
|
||||
Object bean = beans.get(name);
|
||||
// if a new object is requested or none exists under the current
|
||||
// name, create one
|
||||
if (bean == null) {
|
||||
beans.put(name, objectFactory.getObject());
|
||||
}
|
||||
|
||||
return beans.get(name);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.beans.factory.config.Scope#getConversationId()
|
||||
*/
|
||||
public String getConversationId() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.beans.factory.config.Scope#registerDestructionCallback(java.lang.String,
|
||||
* java.lang.Runnable)
|
||||
*/
|
||||
public void registerDestructionCallback(String name, Runnable callback) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.beans.factory.config.Scope#remove(java.lang.String)
|
||||
*/
|
||||
public Object remove(String name) {
|
||||
return beans.remove(name);
|
||||
}
|
||||
|
||||
public Object resolveContextualObject(String key) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* 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 test.beans;
|
||||
|
||||
|
||||
/** TODO: JAVADOC */
|
||||
public class DependsOnTestBean {
|
||||
public TestBean tb;
|
||||
|
||||
private int state;
|
||||
|
||||
public void setTestBean(TestBean tb) {
|
||||
this.tb = tb;
|
||||
}
|
||||
|
||||
public int getState() {
|
||||
return state;
|
||||
}
|
||||
|
||||
public TestBean getTestBean() {
|
||||
return tb;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* 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 test.beans;
|
||||
|
||||
|
||||
/** TODO: JAVADOC */
|
||||
public interface INestedTestBean {
|
||||
|
||||
String getCompany();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* 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 test.beans;
|
||||
|
||||
|
||||
/** TODO: JAVADOC */
|
||||
public interface IOther {
|
||||
|
||||
void absquatulate();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* 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 test.beans;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
|
||||
/**
|
||||
* Interface used for test beans. Two methods are the same as on Person, but if this extends
|
||||
* person it breaks quite a few tests
|
||||
*
|
||||
* @author Rod Johnson
|
||||
*/
|
||||
public interface ITestBean {
|
||||
|
||||
int getAge();
|
||||
|
||||
void setAge(int age);
|
||||
|
||||
String getName();
|
||||
|
||||
void setName(String name);
|
||||
|
||||
ITestBean getSpouse();
|
||||
|
||||
void setSpouse(ITestBean spouse);
|
||||
|
||||
/**
|
||||
* t null no error.
|
||||
*/
|
||||
void exceptional(Throwable t) throws Throwable;
|
||||
|
||||
Object returnsThis();
|
||||
|
||||
INestedTestBean getDoctor();
|
||||
|
||||
INestedTestBean getLawyer();
|
||||
|
||||
IndexedTestBean getNestedIndexedBean();
|
||||
|
||||
/**
|
||||
* Increment the age by one.
|
||||
*
|
||||
* @return the previous age
|
||||
*/
|
||||
int haveBirthday();
|
||||
|
||||
void unreliableFileOperation() throws IOException;
|
||||
}
|
||||
@@ -0,0 +1,145 @@
|
||||
/*
|
||||
* 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 test.beans;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.SortedMap;
|
||||
import java.util.SortedSet;
|
||||
import java.util.TreeSet;
|
||||
|
||||
|
||||
/**
|
||||
* TODO: JAVADOC
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 11.11.2003
|
||||
*/
|
||||
public class IndexedTestBean {
|
||||
|
||||
private TestBean[] array;
|
||||
|
||||
private Collection<TestBean> collection;
|
||||
|
||||
private List<TestBean> list;
|
||||
|
||||
private Set<TestBean> set;
|
||||
|
||||
private SortedSet<TestBean> sortedSet;
|
||||
|
||||
private Map<String, Object> map;
|
||||
|
||||
private SortedMap<String, TestBean> sortedMap;
|
||||
|
||||
public IndexedTestBean() {
|
||||
this(true);
|
||||
}
|
||||
|
||||
public IndexedTestBean(boolean populate) {
|
||||
if (populate) {
|
||||
populate();
|
||||
}
|
||||
}
|
||||
|
||||
public void populate() {
|
||||
TestBean tb0 = new TestBean("name0", 0);
|
||||
TestBean tb1 = new TestBean("name1", 0);
|
||||
TestBean tb2 = new TestBean("name2", 0);
|
||||
TestBean tb3 = new TestBean("name3", 0);
|
||||
TestBean tb4 = new TestBean("name4", 0);
|
||||
TestBean tb5 = new TestBean("name5", 0);
|
||||
TestBean tb6 = new TestBean("name6", 0);
|
||||
TestBean tb7 = new TestBean("name7", 0);
|
||||
TestBean tbX = new TestBean("nameX", 0);
|
||||
TestBean tbY = new TestBean("nameY", 0);
|
||||
this.array = new TestBean[] { tb0, tb1 };
|
||||
this.list = new ArrayList<TestBean>();
|
||||
this.list.add(tb2);
|
||||
this.list.add(tb3);
|
||||
this.set = new TreeSet<TestBean>();
|
||||
this.set.add(tb6);
|
||||
this.set.add(tb7);
|
||||
this.map = new HashMap<String, Object>();
|
||||
this.map.put("key1", tb4);
|
||||
this.map.put("key2", tb5);
|
||||
this.map.put("key.3", tb5);
|
||||
List<TestBean> list = new ArrayList<TestBean>();
|
||||
list.add(tbX);
|
||||
list.add(tbY);
|
||||
this.map.put("key4", list);
|
||||
}
|
||||
|
||||
public TestBean[] getArray() {
|
||||
return array;
|
||||
}
|
||||
|
||||
public void setArray(TestBean[] array) {
|
||||
this.array = array;
|
||||
}
|
||||
|
||||
public Collection<?> getCollection() {
|
||||
return collection;
|
||||
}
|
||||
|
||||
public void setCollection(Collection<TestBean> collection) {
|
||||
this.collection = collection;
|
||||
}
|
||||
|
||||
public List<TestBean> getList() {
|
||||
return list;
|
||||
}
|
||||
|
||||
public void setList(List<TestBean> list) {
|
||||
this.list = list;
|
||||
}
|
||||
|
||||
public Set<TestBean> getSet() {
|
||||
return set;
|
||||
}
|
||||
|
||||
public void setSet(Set<TestBean> set) {
|
||||
this.set = set;
|
||||
}
|
||||
|
||||
public SortedSet<TestBean> getSortedSet() {
|
||||
return sortedSet;
|
||||
}
|
||||
|
||||
public void setSortedSet(SortedSet<TestBean> sortedSet) {
|
||||
this.sortedSet = sortedSet;
|
||||
}
|
||||
|
||||
public Map<String, Object> getMap() {
|
||||
return map;
|
||||
}
|
||||
|
||||
public void setMap(Map<String, Object> map) {
|
||||
this.map = map;
|
||||
}
|
||||
|
||||
public SortedMap<String, TestBean> getSortedMap() {
|
||||
return sortedMap;
|
||||
}
|
||||
|
||||
public void setSortedMap(SortedMap<String, TestBean> sortedMap) {
|
||||
this.sortedMap = sortedMap;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* 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 test.beans;
|
||||
|
||||
/**
|
||||
* Simple nested test bean used for testing bean factories, AOP framework etc.
|
||||
*
|
||||
* @author Trevor D. Cook
|
||||
* @since 30.09.2003
|
||||
*/
|
||||
public class NestedTestBean implements INestedTestBean {
|
||||
|
||||
private String company = "";
|
||||
|
||||
public NestedTestBean() {
|
||||
}
|
||||
|
||||
public NestedTestBean(String company) {
|
||||
setCompany(company);
|
||||
}
|
||||
|
||||
public void setCompany(String company) {
|
||||
this.company = ((company != null) ? company : "");
|
||||
}
|
||||
|
||||
public String getCompany() {
|
||||
return company;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (!(obj instanceof NestedTestBean)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
NestedTestBean ntb = (NestedTestBean) obj;
|
||||
return this.company.equals(ntb.company);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return this.company.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "NestedTestBean: " + this.company;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,419 @@
|
||||
/*
|
||||
* 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 test.beans;
|
||||
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.BeanFactoryAware;
|
||||
import org.springframework.beans.factory.BeanNameAware;
|
||||
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
|
||||
|
||||
/**
|
||||
* Simple test bean used for testing bean factories, AOP framework etc.
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @since 15 April 2001
|
||||
*/
|
||||
public class TestBean implements BeanNameAware, BeanFactoryAware, ITestBean, IOther, Comparable<Object> {
|
||||
|
||||
private String beanName;
|
||||
|
||||
private String country;
|
||||
|
||||
private BeanFactory beanFactory;
|
||||
|
||||
private boolean postProcessed;
|
||||
|
||||
private String name;
|
||||
|
||||
private String sex;
|
||||
|
||||
private int age;
|
||||
|
||||
private boolean jedi;
|
||||
|
||||
private ITestBean spouse;
|
||||
|
||||
private String touchy;
|
||||
|
||||
private String[] stringArray;
|
||||
|
||||
private Integer[] someIntegerArray;
|
||||
|
||||
private Date date = new Date();
|
||||
|
||||
private Float myFloat = new Float(0.0);
|
||||
|
||||
private Collection<?> friends = new LinkedList<Object>();
|
||||
|
||||
private Set<?> someSet = new HashSet<Object>();
|
||||
|
||||
private Map<?, ?> someMap = new HashMap<Object, Object>();
|
||||
|
||||
private List<?> someList = new ArrayList<Object>();
|
||||
|
||||
private Properties someProperties = new Properties();
|
||||
|
||||
private INestedTestBean doctor = new NestedTestBean();
|
||||
|
||||
private INestedTestBean lawyer = new NestedTestBean();
|
||||
|
||||
private IndexedTestBean nestedIndexedBean;
|
||||
|
||||
private boolean destroyed;
|
||||
|
||||
private Number someNumber;
|
||||
|
||||
private Colour favouriteColour;
|
||||
|
||||
private Boolean someBoolean;
|
||||
|
||||
private List<?> otherColours;
|
||||
|
||||
private List<?> pets;
|
||||
|
||||
public TestBean() {
|
||||
}
|
||||
|
||||
public TestBean(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public TestBean(ITestBean spouse) {
|
||||
this.spouse = spouse;
|
||||
}
|
||||
|
||||
public TestBean(String name, int age) {
|
||||
this.name = name;
|
||||
this.age = age;
|
||||
}
|
||||
|
||||
public TestBean(ITestBean spouse, Properties someProperties) {
|
||||
this.spouse = spouse;
|
||||
this.someProperties = someProperties;
|
||||
}
|
||||
|
||||
public void setBeanName(String beanName) {
|
||||
this.beanName = beanName;
|
||||
}
|
||||
|
||||
public String getBeanName() {
|
||||
return beanName;
|
||||
}
|
||||
|
||||
public void setBeanFactory(BeanFactory beanFactory) {
|
||||
this.beanFactory = beanFactory;
|
||||
}
|
||||
|
||||
public BeanFactory getBeanFactory() {
|
||||
return beanFactory;
|
||||
}
|
||||
|
||||
public void setPostProcessed(boolean postProcessed) {
|
||||
this.postProcessed = postProcessed;
|
||||
}
|
||||
|
||||
public boolean isPostProcessed() {
|
||||
return postProcessed;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getSex() {
|
||||
return sex;
|
||||
}
|
||||
|
||||
public void setSex(String sex) {
|
||||
this.sex = sex;
|
||||
}
|
||||
|
||||
public int getAge() {
|
||||
return age;
|
||||
}
|
||||
|
||||
public void setAge(int age) {
|
||||
this.age = age;
|
||||
}
|
||||
|
||||
public boolean isJedi() {
|
||||
return jedi;
|
||||
}
|
||||
|
||||
public void setJedi(boolean jedi) {
|
||||
this.jedi = jedi;
|
||||
}
|
||||
|
||||
public ITestBean getSpouse() {
|
||||
return spouse;
|
||||
}
|
||||
|
||||
public void setSpouse(ITestBean spouse) {
|
||||
this.spouse = spouse;
|
||||
}
|
||||
|
||||
public String getTouchy() {
|
||||
return touchy;
|
||||
}
|
||||
|
||||
public void setTouchy(String touchy) throws Exception {
|
||||
if (touchy.indexOf('.') != -1) {
|
||||
throw new Exception("Can't contain a .");
|
||||
}
|
||||
|
||||
if (touchy.indexOf(',') != -1) {
|
||||
throw new NumberFormatException("Number format exception: contains a ,");
|
||||
}
|
||||
|
||||
this.touchy = touchy;
|
||||
}
|
||||
|
||||
public String getCountry() {
|
||||
return country;
|
||||
}
|
||||
|
||||
public void setCountry(String country) {
|
||||
this.country = country;
|
||||
}
|
||||
|
||||
public String[] getStringArray() {
|
||||
return stringArray;
|
||||
}
|
||||
|
||||
public void setStringArray(String[] stringArray) {
|
||||
this.stringArray = stringArray;
|
||||
}
|
||||
|
||||
public Integer[] getSomeIntegerArray() {
|
||||
return someIntegerArray;
|
||||
}
|
||||
|
||||
public void setSomeIntegerArray(Integer[] someIntegerArray) {
|
||||
this.someIntegerArray = someIntegerArray;
|
||||
}
|
||||
|
||||
public Date getDate() {
|
||||
return date;
|
||||
}
|
||||
|
||||
public void setDate(Date date) {
|
||||
this.date = date;
|
||||
}
|
||||
|
||||
public Float getMyFloat() {
|
||||
return myFloat;
|
||||
}
|
||||
|
||||
public void setMyFloat(Float myFloat) {
|
||||
this.myFloat = myFloat;
|
||||
}
|
||||
|
||||
public Collection<?> getFriends() {
|
||||
return friends;
|
||||
}
|
||||
|
||||
public void setFriends(Collection<?> friends) {
|
||||
this.friends = friends;
|
||||
}
|
||||
|
||||
public Set<?> getSomeSet() {
|
||||
return someSet;
|
||||
}
|
||||
|
||||
public void setSomeSet(Set<?> someSet) {
|
||||
this.someSet = someSet;
|
||||
}
|
||||
|
||||
public Map<?, ?> getSomeMap() {
|
||||
return someMap;
|
||||
}
|
||||
|
||||
public void setSomeMap(Map<?, ?> someMap) {
|
||||
this.someMap = someMap;
|
||||
}
|
||||
|
||||
public List<?> getSomeList() {
|
||||
return someList;
|
||||
}
|
||||
|
||||
public void setSomeList(List<?> someList) {
|
||||
this.someList = someList;
|
||||
}
|
||||
|
||||
public Properties getSomeProperties() {
|
||||
return someProperties;
|
||||
}
|
||||
|
||||
public void setSomeProperties(Properties someProperties) {
|
||||
this.someProperties = someProperties;
|
||||
}
|
||||
|
||||
public INestedTestBean getDoctor() {
|
||||
return doctor;
|
||||
}
|
||||
|
||||
public INestedTestBean getLawyer() {
|
||||
return lawyer;
|
||||
}
|
||||
|
||||
public void setDoctor(INestedTestBean bean) {
|
||||
doctor = bean;
|
||||
}
|
||||
|
||||
public void setLawyer(INestedTestBean bean) {
|
||||
lawyer = bean;
|
||||
}
|
||||
|
||||
public Number getSomeNumber() {
|
||||
return someNumber;
|
||||
}
|
||||
|
||||
public void setSomeNumber(Number someNumber) {
|
||||
this.someNumber = someNumber;
|
||||
}
|
||||
|
||||
public Colour getFavouriteColour() {
|
||||
return favouriteColour;
|
||||
}
|
||||
|
||||
public void setFavouriteColour(Colour favouriteColour) {
|
||||
this.favouriteColour = favouriteColour;
|
||||
}
|
||||
|
||||
public Boolean getSomeBoolean() {
|
||||
return someBoolean;
|
||||
}
|
||||
|
||||
public void setSomeBoolean(Boolean someBoolean) {
|
||||
this.someBoolean = someBoolean;
|
||||
}
|
||||
|
||||
public IndexedTestBean getNestedIndexedBean() {
|
||||
return nestedIndexedBean;
|
||||
}
|
||||
|
||||
public void setNestedIndexedBean(IndexedTestBean nestedIndexedBean) {
|
||||
this.nestedIndexedBean = nestedIndexedBean;
|
||||
}
|
||||
|
||||
public List<?> getOtherColours() {
|
||||
return otherColours;
|
||||
}
|
||||
|
||||
public void setOtherColours(List<?> otherColours) {
|
||||
this.otherColours = otherColours;
|
||||
}
|
||||
|
||||
public List<?> getPets() {
|
||||
return pets;
|
||||
}
|
||||
|
||||
public void setPets(List<?> pets) {
|
||||
this.pets = pets;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ITestBean#exceptional(Throwable)
|
||||
*/
|
||||
public void exceptional(Throwable t) throws Throwable {
|
||||
if (t != null) {
|
||||
throw t;
|
||||
}
|
||||
}
|
||||
|
||||
public void unreliableFileOperation() throws IOException {
|
||||
throw new IOException();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ITestBean#returnsThis()
|
||||
*/
|
||||
public Object returnsThis() {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see IOther#absquatulate()
|
||||
*/
|
||||
public void absquatulate() {
|
||||
}
|
||||
|
||||
public int haveBirthday() {
|
||||
return age++;
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
this.destroyed = true;
|
||||
}
|
||||
|
||||
public boolean wasDestroyed() {
|
||||
return destroyed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
if (this == other) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((other == null) || !(other instanceof TestBean)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
TestBean tb2 = (TestBean) other;
|
||||
return (ObjectUtils.nullSafeEquals(this.name, tb2.name) && (this.age == tb2.age));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return this.age;
|
||||
}
|
||||
|
||||
public int compareTo(Object other) {
|
||||
if ((this.name != null) && (other instanceof TestBean)) {
|
||||
return this.name.compareTo(((TestBean) other).getName());
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String s = "name=" + name + "; age=" + age + "; touchy=" + touchy;
|
||||
s += "; spouse={" + ((spouse != null) ? spouse.getName() : null) + "}";
|
||||
return s;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user