@Configuration parsing fully relies on Spring's MetadataReader abstraction now

This commit is contained in:
Juergen Hoeller
2009-04-24 11:16:46 +00:00
parent 37e1333a41
commit b5d21108da
30 changed files with 819 additions and 1944 deletions

View File

@@ -1,137 +0,0 @@
/*
* 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;
import java.lang.reflect.Modifier;
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.parsing.FailFastProblemReporter;
import org.springframework.beans.factory.parsing.Location;
import org.springframework.beans.factory.parsing.ProblemReporter;
import static org.springframework.context.annotation.ConfigurationClassReaderUtils.*;
import static org.springframework.context.annotation.ScopedProxyMode.*;
import static org.springframework.context.annotation.StandardScopes.*;
import org.springframework.core.io.ClassPathResource;
import org.springframework.util.ClassUtils;
/**
* @author Chris Beams
*/
public class BeanMethodTests {
private ProblemReporter problemReporter = new FailFastProblemReporter();
private String beanName = "foo";
private Bean beanAnno = (Bean) createMutableAnnotation(Bean.class, ClassUtils.getDefaultClassLoader());
private ConfigurationClassMethod.ReturnType returnType = new ConfigurationClassMethod.ReturnType("FooType");
private ConfigurationClass declaringClass = new ConfigurationClass();
{ declaringClass.setName("test.Config"); }
@Test
public void testWellFormedMethod() {
ConfigurationClassMethod beanMethod = new ConfigurationClassMethod(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 IllegalStateException ex");
} catch (IllegalStateException 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() {
ConfigurationClassMethod beanMethod = new ConfigurationClassMethod(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() {
ConfigurationClassMethod beanMethod = new ConfigurationClassMethod(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 singletonsSansProxyAreLegal() {
Scope scope = SingletonNoProxy.class.getAnnotation(Scope.class);
ConfigurationClassMethod beanMethod = new ConfigurationClassMethod(beanName, 0, returnType, beanAnno, scope);
beanMethod.setDeclaringClass(declaringClass);
beanMethod.validate(problemReporter); // should validate without problems - it's legal
}
@Test
public void sessionInterfaceScopedProxiesAreLegal() {
Scope scope = SessionInterfaceProxy.class.getAnnotation(Scope.class);
ConfigurationClassMethod beanMethod = new ConfigurationClassMethod(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 { }
}

View File

@@ -34,12 +34,10 @@ import org.springframework.core.io.ClassPathResource;
import test.beans.Colour;
import test.beans.TestBean;
/**
* System tests covering use of {@link Autowired} and {@link Value} within
* {@link Configuration} classes.
*
*
* @author Chris Beams
*/
public class AutowiredConfigurationTests {
@@ -73,6 +71,7 @@ public class AutowiredConfigurationTests {
}
}
/**
* {@link Autowired} constructors are not supported on {@link Configuration} classes
* due to CGLIB constraints
@@ -96,6 +95,7 @@ public class AutowiredConfigurationTests {
}
}
@Test
public void testValueInjection() {
System.setProperty("myProp", "foo");
@@ -119,6 +119,7 @@ public class AutowiredConfigurationTests {
}
}
@Test
public void testCustomProperties() {
ClassPathXmlApplicationContext factory = new ClassPathXmlApplicationContext(
@@ -143,4 +144,5 @@ public class AutowiredConfigurationTests {
return new TestBean(hostname);
}
}
}

View File

@@ -74,15 +74,6 @@ public class ConfigurationClassProcessingTests {
} 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);
@@ -98,27 +89,11 @@ public class ConfigurationClassProcessingTests {
} 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);
@@ -139,6 +114,24 @@ public class ConfigurationClassProcessingTests {
}
@Configuration
static class ConfigWithBeanWithCustomName {
static TestBean testBean = new TestBean();
@Bean(name="customName")
public TestBean methodName() {
return testBean;
}
}
@Configuration
static class ConfigWithFinalBean {
public final @Bean TestBean testBean() {
return new TestBean();
}
}
@Configuration
static class SimplestPossibleConfig {
public @Bean String stringBean() {
@@ -147,6 +140,16 @@ public class ConfigurationClassProcessingTests {
}
@Configuration
static class ConfigWithBeanWithAliases {
static TestBean testBean = new TestBean();
@Bean(name={"name1", "alias1", "alias2", "alias3"})
public TestBean methodName() {
return testBean;
}
}
@Configuration
static class ConfigWithPrototypeBean {

View File

@@ -19,14 +19,14 @@ package org.springframework.context.annotation.configuration;
import java.lang.annotation.Inherited;
import org.junit.Test;
import test.beans.TestBean;
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.ConfigurationClassPostProcessor;
import test.beans.TestBean;
/**
* Tests that polymorphic Configuration classes need not explicitly redeclare the
* {@link Configuration} annotation. This respects the {@link Inherited} nature
@@ -37,7 +37,7 @@ import test.beans.TestBean;
public class PolymorphicConfigurationTests {
@Test
public void subclassNeedNotDeclareConfigurationAnnotation() {
public void beanMethodsDetectedOnSuperClass() {
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
beanFactory.registerBeanDefinition("config", new RootBeanDefinition(Config.class));
ConfigurationClassPostProcessor pp = new ConfigurationClassPostProcessor();
@@ -56,6 +56,7 @@ public class PolymorphicConfigurationTests {
}
@Configuration
static class Config extends SuperConfig {
}