【问题标题】:spring how to instantiate an @Autowired constructor without passing the parameterspring如何在不传递参数的情况下实例化@Autowired构造函数
【发布时间】:2019-03-27 19:10:55
【问题描述】:

假设我有这门课

class Foo implements IFoo { Foo() {} }
class Fooz implements IFoo { Fooz() {}}

class Foobar implement IFoobar {
  @Autowired
  Foobar (Foo foo) {}
}

class Foobarz implement IFoobar {
  @Autowired
  Foobarz (Bar bar) {}
}

在简单的情况下,我可以解决我的问题:

class Bar {
  @Autowired 
  Bar (IFoo foo) {
    this.foo = foo;
  }
}

但是,如果我希望能够根据我的配置文件选择我的 IFoo 和 IFoobar 实例,我需要这样做:

@Configuration
class Configuration {
  @Bean
  foo () {
    return this.isZ() ? new Fooz() : new Foo ();
  }
  @Bean
  foobar () {
    return this.isZ() ? new Foobarz(/* ??????? */) : new Foobar (/* ??????? */);
  }
}

如您所见,我无法实例化我的 Foobar,因为我需要另一个 bean。我知道有 ApplicationContext.getBean,但我不能确定当 foobar() 被调用时它是否会在我的 Configuration 类中被初始化。

而且我也不想调用this.foo(),因为那样会创建对象的另一个引用,而且我不确定执行和初始化的顺序

【问题讨论】:

标签: java spring


【解决方案1】:

在您的情况下,以下应该可以解决问题

@Configuration
class Configuration {
  @Bean
  IFoo foo() {
    return this.isZ() ? new Fooz() : new Foo ();
  }
  @Bean
  IFoobar foobar(IFoo foo) { // IFoo bean declared above will be injected here by Spring
    return this.isZ() ? new Foobarz(foo) : new Foobar(foo);
  }
}

更新

但更优雅的方法是在你的类上添加 @Service@Component 注释(@Bean 声明应该从配置中删除)...

package com.foobarpkg.maybeanotherpkg;

@Service 
class Foobar implement IFoobar {
  @Autowired
  Foobar (IFoo foo) { // not that interface should be used here instead of concrete class (Foo/Fooz)
  } 
}

...并让 Spring 知道它的包位于

@Configuration
@ComponentScan(basePackages = {"com.foobarpkg"})
class Configuration { 
 @Bean
  IFoo foo() {
    return this.isZ() ? new Fooz() : new Foo ();
  }
  // foobar bean is no longer declared here
}

【讨论】:

  • 这似乎是我一直在寻找的,尽管它不是最佳答案,无论如何,谢谢!
猜你喜欢
  • 1970-01-01
  • 2013-06-07
  • 1970-01-01
  • 1970-01-01
  • 2013-01-27
  • 1970-01-01
  • 1970-01-01
  • 2010-09-15
  • 1970-01-01
相关资源
最近更新 更多