在Spring Boot中使用@Bean将@Value加载到BeanFactory对象中

时间:2014-01-27 15:03:31

标签: spring

任何人都可以帮我解决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

有什么方法吗?

由于

2 个答案:

答案 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

Spring Boot Actuator

中有新的注释@EnableConfigurationProperties
  

Spring Environment是一组名称 - 值对,取自(按优先级递减的顺序)

     

1)命令行,

     

2)外部配置文件

     

3)系统属性,

     

4)OS环境。

还可以用YAML格式定义应用程序属性(外部配置)。