From 70fec47944abbc18601a532eaf07e032b9940d53 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Mon, 6 Oct 2014 18:08:19 +0200 Subject: [PATCH] Provider declaration for @Value method argument works again Issue: SPR-12297 --- .../AutowiredConfigurationTests.java | 184 ++++++++++++++---- .../ApplicationContextExpressionTests.java | 6 +- .../core/convert/TypeDescriptor.java | 3 - 3 files changed, 146 insertions(+), 47 deletions(-) diff --git a/spring-context/src/test/java/org/springframework/context/annotation/configuration/AutowiredConfigurationTests.java b/spring-context/src/test/java/org/springframework/context/annotation/configuration/AutowiredConfigurationTests.java index 45bea62180..91a9d488c2 100644 --- a/spring-context/src/test/java/org/springframework/context/annotation/configuration/AutowiredConfigurationTests.java +++ b/spring-context/src/test/java/org/springframework/context/annotation/configuration/AutowiredConfigurationTests.java @@ -1,5 +1,5 @@ /* - * 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"); * you may not use this file except in compliance with the License. @@ -16,24 +16,29 @@ package org.springframework.context.annotation.configuration; -import static org.hamcrest.CoreMatchers.*; -import static org.junit.Assert.*; +import javax.inject.Provider; + 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.BeanFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.support.DefaultListableBeanFactory; import org.springframework.beans.factory.support.RootBeanDefinition; import org.springframework.beans.factory.xml.XmlBeanDefinitionReader; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Scope; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.context.support.GenericApplicationContext; 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 @@ -53,32 +58,11 @@ public class AutowiredConfigurationTests { 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 * due to CGLIB constraints */ - @Test(expected=BeanCreationException.class) + @Test(expected = BeanCreationException.class) public void testAutowiredConfigurationConstructorsAreNotSupported() { DefaultListableBeanFactory factory = new DefaultListableBeanFactory(); new XmlBeanDefinitionReader(factory).loadBeanDefinitions( @@ -89,22 +73,35 @@ public class AutowiredConfigurationTests { ctx.refresh(); // should throw } - @Configuration - static class AutowiredConstructorConfig { - Colour colour; + @Test + public void testValueInjection() { + ClassPathXmlApplicationContext factory = new ClassPathXmlApplicationContext( + "ValueInjectionTests.xml", AutowiredConfigurationTests.class); + doTestValueInjection(factory); + } - @Autowired - AutowiredConstructorConfig(Colour colour) { - this.colour = colour; - } + @Test + public void testValueInjectionWithProviderFields() { + AnnotationConfigApplicationContext factory = + new AnnotationConfigApplicationContext(ValueConfigWithProviderFields.class); + doTestValueInjection(factory); } + @Test + public void testValueInjectionWithProviderConstructorArguments() { + AnnotationConfigApplicationContext factory = + new AnnotationConfigApplicationContext(ValueConfigWithProviderConstructorArguments.class); + doTestValueInjection(factory); + } @Test - public void testValueInjection() { - ClassPathXmlApplicationContext factory = new ClassPathXmlApplicationContext( - "ValueInjectionTests.xml", AutowiredConfigurationTests.class); + public void testValueInjectionWithProviderMethodArguments() { + AnnotationConfigApplicationContext factory = + new AnnotationConfigApplicationContext(ValueConfigWithProviderMethodArguments.class); + doTestValueInjection(factory); + } + private void doTestValueInjection(BeanFactory factory) { System.clearProperty("myProp"); TestBean testBean = factory.getBean("testBean", TestBean.class); @@ -130,6 +127,51 @@ public class AutowiredConfigurationTests { 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 static class ValueConfig { @@ -155,15 +197,71 @@ public class AutowiredConfigurationTests { } - @Test - public void testCustomProperties() { - ClassPathXmlApplicationContext factory = new ClassPathXmlApplicationContext( - "AutowiredConfigurationTests-custom.xml", AutowiredConfigurationTests.class); + @Configuration + static class ValueConfigWithProviderFields { - TestBean testBean = factory.getBean("testBean", TestBean.class); - assertThat(testBean.getName(), equalTo("localhost")); + @Value("#{systemProperties[myProp]}") + private Provider name; + + private Provider name2; + + @Value("#{systemProperties[myProp]}") + public void setName2(Provider 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 name; + + private final Provider name2; + + @Autowired + public ValueConfigWithProviderConstructorArguments(@Value("#{systemProperties[myProp]}") Provider name, + @Value("#{systemProperties[myProp]}") Provider 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 name) { + return new TestBean(name.get()); + } + + @Bean @Scope("prototype") + public TestBean testBean2(@Value("#{systemProperties[myProp]}") Provider name2) { + return new TestBean(name2.get()); + } + } + + @Configuration static class PropertiesConfig { diff --git a/spring-context/src/test/java/org/springframework/context/expression/ApplicationContextExpressionTests.java b/spring-context/src/test/java/org/springframework/context/expression/ApplicationContextExpressionTests.java index 010a31e5a4..e940b51c9e 100644 --- a/spring-context/src/test/java/org/springframework/context/expression/ApplicationContextExpressionTests.java +++ b/spring-context/src/test/java/org/springframework/context/expression/ApplicationContextExpressionTests.java @@ -1,5 +1,5 @@ /* - * 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"); * you may not use this file except in compliance with the License. @@ -153,6 +153,7 @@ public class ApplicationContextExpressionTests { ValueTestBean tb3 = ac.getBean("tb3", ValueTestBean.class); assertEquals("XXXmyNameYYY42ZZZ", tb3.name); assertEquals(42, tb3.age); + assertEquals(42, tb3.ageFactory.getObject().intValue()); assertEquals("123 UK", tb3.country); assertEquals("123 UK", tb3.countryFactory.getObject()); System.getProperties().put("country", "US"); @@ -321,6 +322,9 @@ public class ApplicationContextExpressionTests { @Autowired @Value("#{mySpecialAttr}") public int age; + @Value("#{mySpecialAttr}") + public ObjectFactory ageFactory; + @Value("${code} #{systemProperties.country}") public String country; diff --git a/spring-core/src/main/java/org/springframework/core/convert/TypeDescriptor.java b/spring-core/src/main/java/org/springframework/core/convert/TypeDescriptor.java index bfc2b22e96..1467ab614c 100644 --- a/spring-core/src/main/java/org/springframework/core/convert/TypeDescriptor.java +++ b/spring-core/src/main/java/org/springframework/core/convert/TypeDescriptor.java @@ -74,9 +74,6 @@ public class TypeDescriptor implements Serializable { */ public TypeDescriptor(MethodParameter methodParameter) { 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.type = this.resolvableType.resolve(methodParameter.getParameterType()); this.annotations = (methodParameter.getParameterIndex() == -1 ? -- GitLab