Java 具有运行时构造函数参数的Springbean

Java 具有运行时构造函数参数的Springbean,java,spring,spring-bean,Java,Spring,Spring Bean,我想在springjava配置中创建一个springbean,并在运行时传递一些构造函数参数。我创建了以下Java配置,其中有一个beanfixedLengthReport,它需要构造函数中的一些参数 @Configuration public class AppConfig { @Autowrire Dao dao; @Bean @Scope(value = "prototype") **//SourceSystem can change at ru

我想在springjava配置中创建一个springbean,并在运行时传递一些构造函数参数。我创建了以下Java配置,其中有一个beanfixedLengthReport,它需要构造函数中的一些参数

@Configuration
public class AppConfig {

    @Autowrire
    Dao dao;

    @Bean
    @Scope(value = "prototype")
    **//SourceSystem can change at runtime**
    public FixedLengthReport fixedLengthReport(String sourceSystem) {
         return new TdctFixedLengthReport(sourceSystem, dao);
    }
}
但是我得到一个错误,sourceSystem无法连接,因为找不到bean。如何使用运行时构造函数参数创建bean


我使用的是Spring4.2,您的代码看起来不错,要获得带有参数的原型,请使用BeanFactory#getBean(字符串名称、对象…args)方法

看看BeanFactory,getBean(字符串名、对象…args)就是您要找的

我猜您的想法(在我的例子中是IntelliJ IDEA版本15)会给您带来错误,而不是运行时/编译时错误。

在IntelliJ中,您可以更改弹簧检查的设置

  • 转到文件->设置
  • 在搜索框中键入检查
  • 转到SpringCore->Code->Autowire获取Bean类
  • 从“错误”更改为“弱警告”

您可以将原型bean与
BeanFactory一起使用

@Configuration
public class AppConfig {

   @Autowired
   Dao dao;

   @Bean
   @Scope(value = "prototype")
   public FixedLengthReport fixedLengthReport(String sourceSystem) {
       return new TdctFixedLengthReport(sourceSystem, dao);
   }
}
@Scope(value=“prototype”)
意味着Spring不会在一开始就实例化bean,而是在以后需要时进行实例化。现在,要定制原型bean的实例,您必须执行以下操作

@Controller
public class ExampleController{

   @Autowired
   private BeanFactory beanFactory;

   @RequestMapping("/")
   public String exampleMethod(){
      TdctFixedLengthReport report = 
         beanFactory.getBean(TdctFixedLengthReport.class, "sourceSystem");
   }
}
注意,因为bean不能在启动时实例化,所以不能直接自动连接bean;否则Spring将尝试实例化bean本身。此用法将导致错误

@Controller
public class ExampleController{

   //next declaration will cause ERROR
   @Autowired
   private TdctFixedLengthReport report;

}

这可以通过Spring在Spring 4.3中引入的
ObjectProvider
类来实现。有关更多详细信息,请参见Spring的

要点是为要提供的对象定义bean工厂方法,将
ObjectProvider
注入消费者,并创建要提供的对象的新实例

public class Pair
{
    private String left;
    private String right;

    public Pair(String left, String right)
    {
        this.left = left;
        this.right = right;
    }

    public String getLeft()
    {
        return left;
    }

    public String getRight()
    {
        return right;
    }
}

@Configuration
public class MyConfig
{
    @Bean
    @Scope(BeanDefinition.SCOPE_PROTOTYPE)
    public Pair pair(String left, String right)
    {
        return new Pair(left, right);
    }
}

@Component
public class MyConsumer
{
    private ObjectProvider<Pair> pairProvider;

    @Autowired
    public MyConsumer(ObjectProvider<Pair> pairProvider)
    {
        this.pairProvider = pairProvider;
    }

    public void doSomethingWithPairs()
    {
        Pair pairOne = pairProvider.getObject("a", "b");
        Pair pairTwo = pairProvider.getObject("z", "x");
    }
}
公共类对
{
私有字符串左;
私有字符串权;
公共对(左字符串、右字符串)
{
this.left=左;
这个。右=右;
}
公共字符串getLeft()
{
左转;
}
公共字符串getRight()
{
返还权;
}
}
@配置
公共类MyConfig
{
@豆子
@范围(BeanDefinition.Scope\u原型)
公共对(左字符串、右字符串)
{
返回新的一对(左、右);
}
}
@组成部分
公共类消费者
{
私有对象提供者对提供者;
@自动连线
公共用户(对象提供者对提供者)
{
this.pairProvider=pairProvider;
}
public void doSomethingWithPairs()
{
pairRone=pairProvider.getObject(“a”、“b”);
pairTwo=pairProvider.getObject(“z”,“x”);
}
}

注意:您实际上没有实现
ObjectProvider
接口;Spring会自动为您实现这一点。您只需要定义bean工厂方法。

您在哪里定义了
SourceSystem
的bean?SourceSystem不是spring bean。假设它只是一个字符串,其值在运行时确定。我已经更新了我的问题,你能提供
TdctFixedLengthReport
的实现吗?你有什么想法using@surajbahl:此错误可能是因为spring不知道TdctFixedLengthReport的实例。这里,TdctFixedLengthReport的实例是由程序而不是spring创建的。自动连线它,因此TdctFixedLengthReport的实例是由spring自己创建的。请更改
@Autowire
注释中的打字错误。(是的,这让我很烦!;)@Dominik thanx很多。下次,如果你发现同样的打字错误,请随意编辑我的帖子。)似乎编辑必须编辑至少6个字符,至少这是我在编辑问题(1个字符)和你的帖子(3个字符编辑)时遇到的情况:-@KenBekov它是alreday原型范围,调用时将启动,为什么我们需要lazy?Thx@Spring你说得对<代码>原型
将在调用时启动。因此,
Prototype
bean不需要
Lasy
。这只是为了演示概念,但实际上,这里有一种冗余。没错,我使用的是idea版本15,所以可能就是因为这个。我将更改设置以删除它。谢谢你的帮助,哈伊姆。