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

标签 java spring spring-bean

使用 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/

相关文章:

spring - FindByIndexNameSessionRepository “RedisConnectionFactory is required” 配置错误

java - 访问字段时出错(使用 Hibernate/JPA)

java - @PostInitialize 哪个包的一部分

java - Spring 4.2+ : How to reference a Spring bean instance from inside an @EventListener condition expression

java - 安卓设计: onDraw() not called after invalidate()

java - 在 nkzawa socket.iO-client 上添加自定义参数以进行握手

spring - 将全局变量传递给 Spring + Apache Tiles

java - Spring中如何提供参数化的组件?

java - 变量名未解析

java - 在 Eclipse 中开发期间在安全策略中使用 "codebases"