提交 70fec479 编写于 作者: J Juergen Hoeller

Provider declaration for @Value method argument works again

Issue: SPR-12297
上级 9d832816
/* /*
* Copyright 2002-2013 the original author or authors. * Copyright 2002-2014 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
...@@ -16,24 +16,29 @@ ...@@ -16,24 +16,29 @@
package org.springframework.context.annotation.configuration; package org.springframework.context.annotation.configuration;
import static org.hamcrest.CoreMatchers.*; import javax.inject.Provider;
import static org.junit.Assert.*;
import org.junit.Test; import org.junit.Test;
import org.springframework.tests.sample.beans.Colour;
import org.springframework.tests.sample.beans.TestBean;
import org.springframework.beans.factory.BeanCreationException; import org.springframework.beans.factory.BeanCreationException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.support.DefaultListableBeanFactory; import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.support.RootBeanDefinition; import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader; import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope; import org.springframework.context.annotation.Scope;
import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.context.support.GenericApplicationContext; import org.springframework.context.support.GenericApplicationContext;
import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.ClassPathResource;
import org.springframework.tests.sample.beans.Colour;
import org.springframework.tests.sample.beans.TestBean;
import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;
/** /**
* System tests covering use of {@link Autowired} and {@link Value} within * System tests covering use of {@link Autowired} and {@link Value} within
...@@ -53,32 +58,11 @@ public class AutowiredConfigurationTests { ...@@ -53,32 +58,11 @@ public class AutowiredConfigurationTests {
assertThat(factory.getBean("testBean", TestBean.class).getName(), equalTo(Colour.RED.toString())); assertThat(factory.getBean("testBean", TestBean.class).getName(), equalTo(Colour.RED.toString()));
} }
@Configuration
static class AutowiredConfig {
@Autowired
private Colour colour;
@Bean
public TestBean testBean() {
return new TestBean(colour.toString());
}
}
@Configuration
static class ColorConfig {
@Bean
public Colour colour() {
return Colour.RED;
}
}
/** /**
* {@link Autowired} constructors are not supported on {@link Configuration} classes * {@link Autowired} constructors are not supported on {@link Configuration} classes
* due to CGLIB constraints * due to CGLIB constraints
*/ */
@Test(expected=BeanCreationException.class) @Test(expected = BeanCreationException.class)
public void testAutowiredConfigurationConstructorsAreNotSupported() { public void testAutowiredConfigurationConstructorsAreNotSupported() {
DefaultListableBeanFactory factory = new DefaultListableBeanFactory(); DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
new XmlBeanDefinitionReader(factory).loadBeanDefinitions( new XmlBeanDefinitionReader(factory).loadBeanDefinitions(
...@@ -89,22 +73,35 @@ public class AutowiredConfigurationTests { ...@@ -89,22 +73,35 @@ public class AutowiredConfigurationTests {
ctx.refresh(); // should throw ctx.refresh(); // should throw
} }
@Configuration @Test
static class AutowiredConstructorConfig { public void testValueInjection() {
Colour colour; ClassPathXmlApplicationContext factory = new ClassPathXmlApplicationContext(
"ValueInjectionTests.xml", AutowiredConfigurationTests.class);
doTestValueInjection(factory);
}
@Autowired @Test
AutowiredConstructorConfig(Colour colour) { public void testValueInjectionWithProviderFields() {
this.colour = colour; AnnotationConfigApplicationContext factory =
} new AnnotationConfigApplicationContext(ValueConfigWithProviderFields.class);
doTestValueInjection(factory);
} }
@Test
public void testValueInjectionWithProviderConstructorArguments() {
AnnotationConfigApplicationContext factory =
new AnnotationConfigApplicationContext(ValueConfigWithProviderConstructorArguments.class);
doTestValueInjection(factory);
}
@Test @Test
public void testValueInjection() { public void testValueInjectionWithProviderMethodArguments() {
ClassPathXmlApplicationContext factory = new ClassPathXmlApplicationContext( AnnotationConfigApplicationContext factory =
"ValueInjectionTests.xml", AutowiredConfigurationTests.class); new AnnotationConfigApplicationContext(ValueConfigWithProviderMethodArguments.class);
doTestValueInjection(factory);
}
private void doTestValueInjection(BeanFactory factory) {
System.clearProperty("myProp"); System.clearProperty("myProp");
TestBean testBean = factory.getBean("testBean", TestBean.class); TestBean testBean = factory.getBean("testBean", TestBean.class);
...@@ -130,6 +127,51 @@ public class AutowiredConfigurationTests { ...@@ -130,6 +127,51 @@ public class AutowiredConfigurationTests {
assertNull(testBean.getName()); assertNull(testBean.getName());
} }
@Test
public void testCustomProperties() {
ClassPathXmlApplicationContext factory = new ClassPathXmlApplicationContext(
"AutowiredConfigurationTests-custom.xml", AutowiredConfigurationTests.class);
TestBean testBean = factory.getBean("testBean", TestBean.class);
assertThat(testBean.getName(), equalTo("localhost"));
}
@Configuration
static class AutowiredConfig {
@Autowired
private Colour colour;
@Bean
public TestBean testBean() {
return new TestBean(colour.toString());
}
}
@Configuration
static class ColorConfig {
@Bean
public Colour colour() {
return Colour.RED;
}
}
@Configuration
static class AutowiredConstructorConfig {
Colour colour;
@Autowired
AutowiredConstructorConfig(Colour colour) {
this.colour = colour;
}
}
@Configuration @Configuration
static class ValueConfig { static class ValueConfig {
...@@ -155,15 +197,71 @@ public class AutowiredConfigurationTests { ...@@ -155,15 +197,71 @@ public class AutowiredConfigurationTests {
} }
@Test @Configuration
public void testCustomProperties() { static class ValueConfigWithProviderFields {
ClassPathXmlApplicationContext factory = new ClassPathXmlApplicationContext(
"AutowiredConfigurationTests-custom.xml", AutowiredConfigurationTests.class);
TestBean testBean = factory.getBean("testBean", TestBean.class); @Value("#{systemProperties[myProp]}")
assertThat(testBean.getName(), equalTo("localhost")); private Provider<String> name;
private Provider<String> name2;
@Value("#{systemProperties[myProp]}")
public void setName2(Provider<String> name) {
this.name2 = name;
}
@Bean @Scope("prototype")
public TestBean testBean() {
return new TestBean(name.get());
}
@Bean @Scope("prototype")
public TestBean testBean2() {
return new TestBean(name2.get());
}
} }
static class ValueConfigWithProviderConstructorArguments {
private final Provider<String> name;
private final Provider<String> name2;
@Autowired
public ValueConfigWithProviderConstructorArguments(@Value("#{systemProperties[myProp]}") Provider<String> name,
@Value("#{systemProperties[myProp]}") Provider<String> name2) {
this.name = name;
this.name2 = name2;
}
@Bean @Scope("prototype")
public TestBean testBean() {
return new TestBean(name.get());
}
@Bean @Scope("prototype")
public TestBean testBean2() {
return new TestBean(name2.get());
}
}
@Configuration
static class ValueConfigWithProviderMethodArguments {
@Bean @Scope("prototype")
public TestBean testBean(@Value("#{systemProperties[myProp]}") Provider<String> name) {
return new TestBean(name.get());
}
@Bean @Scope("prototype")
public TestBean testBean2(@Value("#{systemProperties[myProp]}") Provider<String> name2) {
return new TestBean(name2.get());
}
}
@Configuration @Configuration
static class PropertiesConfig { static class PropertiesConfig {
......
/* /*
* Copyright 2002-2013 the original author or authors. * Copyright 2002-2014 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
...@@ -153,6 +153,7 @@ public class ApplicationContextExpressionTests { ...@@ -153,6 +153,7 @@ public class ApplicationContextExpressionTests {
ValueTestBean tb3 = ac.getBean("tb3", ValueTestBean.class); ValueTestBean tb3 = ac.getBean("tb3", ValueTestBean.class);
assertEquals("XXXmyNameYYY42ZZZ", tb3.name); assertEquals("XXXmyNameYYY42ZZZ", tb3.name);
assertEquals(42, tb3.age); assertEquals(42, tb3.age);
assertEquals(42, tb3.ageFactory.getObject().intValue());
assertEquals("123 UK", tb3.country); assertEquals("123 UK", tb3.country);
assertEquals("123 UK", tb3.countryFactory.getObject()); assertEquals("123 UK", tb3.countryFactory.getObject());
System.getProperties().put("country", "US"); System.getProperties().put("country", "US");
...@@ -321,6 +322,9 @@ public class ApplicationContextExpressionTests { ...@@ -321,6 +322,9 @@ public class ApplicationContextExpressionTests {
@Autowired @Value("#{mySpecialAttr}") @Autowired @Value("#{mySpecialAttr}")
public int age; public int age;
@Value("#{mySpecialAttr}")
public ObjectFactory<Integer> ageFactory;
@Value("${code} #{systemProperties.country}") @Value("${code} #{systemProperties.country}")
public String country; public String country;
......
...@@ -74,9 +74,6 @@ public class TypeDescriptor implements Serializable { ...@@ -74,9 +74,6 @@ public class TypeDescriptor implements Serializable {
*/ */
public TypeDescriptor(MethodParameter methodParameter) { public TypeDescriptor(MethodParameter methodParameter) {
Assert.notNull(methodParameter, "MethodParameter must not be null"); Assert.notNull(methodParameter, "MethodParameter must not be null");
if (methodParameter.getNestingLevel() != 1) {
throw new IllegalArgumentException("MethodParameter argument must have its nestingLevel set to 1");
}
this.resolvableType = ResolvableType.forMethodParameter(methodParameter); this.resolvableType = ResolvableType.forMethodParameter(methodParameter);
this.type = this.resolvableType.resolve(methodParameter.getParameterType()); this.type = this.resolvableType.resolve(methodParameter.getParameterType());
this.annotations = (methodParameter.getParameterIndex() == -1 ? this.annotations = (methodParameter.getParameterIndex() == -1 ?
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册