gpt4 book ai didi

java - Spring 覆盖 bean 配置设置其 "Primary"一个

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:48:02 25 4
gpt4 key购买 nike

使用 Spring 3.X.X 我有 2 个用 @Primary 注释的服务,我创建了另一个配置类,我想在其中使用其中一个服务的“定制”版本。

出于某种原因,我在调试配置类时忽略了我看到它获得了正确的依赖项,但是当我想使用它时它设置了错误的依赖项。

我觉得用代码更容易解​​释,这里是一个例子:

接口(interface)富:

public interface Foo {
String getMessage();
}

硬编码默认消息的主要实现:

@Primary
@Service("FooImpl")
public class FooImpl implements Foo {

private String message = "fooDefaultMessage";

@Override
public String getMessage() {
return message;
}

public void setMessage(String message) {
this.message = message;
}
}

栏界面:

public interface Bar {

void doBar();
}

栏默认实现:

@Primary
@Service("BarImpl")
public class BarImpl implements Bar {

private Foo foo;

@Override
public void doBar() {
System.out.println(foo.getMessage());
}

public Foo getFoo() {
return foo;
}

@Autowired
public void setFoo(Foo foo) {
this.foo = foo;
}
}

到目前为止一切顺利,如果我想注入(inject)一个 Bar,我会得到预期的一切。事情是我有一个配置如下:

@Configuration
public class BeanConfiguration {

@Bean
@Qualifier("readOnlyFoo")
Foo readOnlyFoo() {
FooImpl foo = new FooImpl();
foo.setMessage("a read only message");
return foo;
}

@Bean
@Qualifier("readOnlyBar")
Bar readOnlyBar() {
BarImpl bar = new BarImpl();
bar.setFoo(readOnlyFoo());
return bar;
}
}

当我想注入(inject)一个 readOnlyBar 时,我得到的是默认的 Foo 而不是此处设置的 Foo。

private Bar readOnlyBar;

@Autowired
@Qualifier("readOnlyBar")
public void setReadOnlyBar(Bar readOnlyBar) {
this.readOnlyBar = readOnlyBar;
}

...
readOnlyBar.doBar();

拥有带有“fooDefaultMessage”的 Foo bean。这是为什么?我如何确保 Spring 使用我在 @Configuration 上设置的 Bean?

提前致谢

编辑:请注意,如果您没有调用 @Configuration 类中的 readOnly() 方法,而是传递了一个 @Qualified 参数,则会发生同样的情况。即:

@Configuration
public class BeanConfiguration {

@Bean
@Qualifier("readOnlyFoo")
Foo readOnlyFoo() {
FooImpl foo = new FooImpl();
foo.setMessage("a read only message");
return foo;
}

@Bean
@Qualifier("readOnlyBar")
Bar readOnlyBar(@Qualifier("readOnlyFoo") Foo readOnlyFoo) {
BarImpl bar = new BarImpl();
bar.setFoo(readOnlyFoo);
return bar;
}
}

如果我改为尝试使用 Constructor 依赖注入(inject),一切都会按我想要/预期的方式工作,但不幸的是我不能使用它。

最佳答案

正如@yaswanth 在他的回答中指出的那样,问题是 foo 属性被创建 bean 后发生的属性注入(inject)覆盖。

解决这个问题的一种方法是对 BarImpl 使用构造函数注入(inject)而不是属性注入(inject)。这将使您的代码看起来像...

@Primary @Service("BarImpl")
class BarImpl implements Bar
{
private Foo foo;

@Autowired
public BarImpl(Foo foo) {
this.foo = foo;
}
}

你的配置是...

@Configuration
class BeanConfiguration
{
@Bean @Qualifier("readOnlyFoo")
Foo readOnlyFoo() {
FooImpl foo = new FooImpl();
foo.setMessage("a read only message");
return foo;
}

@Bean @Qualifier("readOnlyBar")
Bar readOnlyBar(@Qualifier("readOnlyFoo") Foo readOnlyFoo) {
return new BarImpl(readOnlyFoo);
}
}

作为旁路;你还应该确保在你的工厂方法中使用依赖注入(inject)而不是显式调用工厂方法,否则你最终会得到你的 bean 的多个实例......

祝你 future 工作顺利!

关于java - Spring 覆盖 bean 配置设置其 "Primary"一个,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47098752/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com