任何人都可以帮我解决Spring Boot问题吗?
我想创建一个工厂bean作为我的应用程序上下文的一部分,但我希望能够使用注入的属性值来实例化它。但是,如今所示,Spring似乎会先装载FactoryBeans:
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.AbstractFactoryBean;
import org.springframework.beans.factory.config.ListFactoryBean;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.Bean;
@EnableAutoConfiguration
public class TestClass
{
@Value("${test.value}")
String value;
@Bean
public Object test1()
{
System.out.println("test.value=" + value );
List<String> list = new ArrayList<String>();
ListFactoryBean factory = new ListFactoryBean();
factory.setSourceList(list);
return factory;
}
public static void main(String[] args)
{
SpringApplication.run(TestClass.class, args);
}
}
使用
运行时java -Dtest.value=HELLO -jar myTest.jar
正确加载值:
test.value=HELLO
但是,当我指定要加载的bean实际上是一个工厂bean时,并以相同的方式运行它:
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.AbstractFactoryBean;
import org.springframework.beans.factory.config.ListFactoryBean;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.Bean;
@EnableAutoConfiguration
public class TestClass
{
@Value("${test.value}")
String value;
@Bean
public AbstractFactoryBean test1()
{
System.out.println("test.value=" + value );
List<String> list = new ArrayList<String>();
ListFactoryBean factory = new ListFactoryBean();
factory.setSourceList(list);
return factory;
}
public static void main(String[] args)
{
SpringApplication.run(TestClass.class, args);
}
}
该值为null,因为尚未注入。
test.value=null
有什么方法吗?
由于
答案 0 :(得分:3)
Spring通常必须查询bean定义以获取它们生成的对象类型。工厂bean总是有问题的,因为它们可能会导致依赖级联,无法尝试在请求类型之前解析所有可用的动态信息。
我认为ListFactoryBean
对其产品类型不够准确(getObjectType()
只能返回非通用List.class
)。您可以编写自己的工厂,使用正确的泛型类型进行参数化。或者,您可以宣布@Bean
返回FactoryBean<List<String>
。
另一个提示是将@Bean
定义移动到单独的类(例如嵌套的静态类),以便可以独立于应用程序上下文的其余部分实例化它。 E.g。
@EnableAutoConfiguration
public class TestClass
{
protected static class NestedConfiguration {
@Value("${test.value}")
String value;
@Bean
public FactoryBean<Properties> test1()
{
System.out.println("test.value=" + value );
// ...
return factory;
}
}
...
}
这不是一个Boot问题,所以你可以考虑更改标签。
答案 1 :(得分:0)
看看Empowering your apps with Spring Boot's property support
中有新的注释@EnableConfigurationProperties
Spring Environment是一组名称 - 值对,取自(按优先级递减的顺序)
1)命令行,
2)外部配置文件
3)系统属性,
4)OS环境。
还可以用YAML格式定义应用程序属性(外部配置)。