Spring bean与运行时构造函数参数

sur*_*ahl 26 java spring spring-bean

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

@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);
    }
}
Run Code Online (Sandbox Code Playgroud)

但我收到的错误是sourceSystem无法连接,因为没有找到bean.如何使用运行时构造函数参数创建bean?

我使用的是Spring 4.2

Ken*_*kov 43

您可以使用原型bean和a BeanFactory.

@Configuration
public class AppConfig {

   @Autowired
   Dao dao;

   @Bean
   @Scope(value = "prototype")
   public FixedLengthReport fixedLengthReport(String sourceSystem) {
       return new TdctFixedLengthReport(sourceSystem, dao);
   }
}
Run Code Online (Sandbox Code Playgroud)

@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");
   }
}
Run Code Online (Sandbox Code Playgroud)

注意,因为你的bean在启动时无法实例化,你不能直接自动装配你的bean; 否则Spring会尝试实例化bean本身.此用法将导致错误.

@Controller
public class ExampleController{

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

}
Run Code Online (Sandbox Code Playgroud)

  • 请更改`@Autowire`注释中的拼写错误.(是的,这给我带来了很多!;)) (3认同)
  • @Dominik thanx很多.下次可以随意编辑我的帖子,如果你发现同样的错别字.) (2认同)
  • @Spring你吧."原型"将在通话时启动.因此`Prototype` bean不需要'Lasy`.它只是为了演示概念,但实际上"懒惰"在这里是一种冗余. (2认同)

Hai*_*Dog 7

这可以通过ObjectProvider<>Spring 4.3 中引入的 Spring 类来实现。有关其他详细信息,请参阅 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");
    }
}
Run Code Online (Sandbox Code Playgroud)

注意:您实际上并未实现该ObjectProvider<>接口;Spring 会自动为您执行此操作。您只需要定义 bean 工厂方法。


Hai*_*man 5

您的代码看起来不错,要获取带有参数的原型,请使用 BeanFactory#getBean(String name, Object... args) 方法。

\n\n

看看Spring Java Config:如何使用运行时参数创建原型范围的 @Bean?BeanFactory#getBean(String name, Object... args) 将是您正在寻找的。

\n\n

我猜你的 IDEA(在我的例子中是 IntelliJ IDEA 版本 15)给了你错误,并且 it\xe2\x80\x99s 不是运行时/编译时错误。

\n\n

在 IntelliJ 中,您可以更改 Spring 检查的设置。

\n\n
    \n
  • 转到文件 -> 设置。
  • \n
  • 在搜索框中键入检查。
  • \n
  • 转到 Spring Core->Code->Autowire for Bean Classes。
  • \n
  • 从“错误”更改为 \xe2\x80\x9cweak warning\xe2\x80\x9d
  • \n
\n


归档时间:

查看次数:

31648 次

最近记录:

6 年,10 月 前