仅在没有其他服务的情况下为接口加载服务

时间:2016-07-07 15:45:20

标签: spring spring-boot

在我的应用程序中,我有默认实现的接口,即服务:

public interface MessageGenerator {
    Message getMessage();
}

@Service
public class PropertiesMessageGenerator implements MessageGenerator {
    @Override
    public Message getMessage() {
        return doSmth();
    }
}

此服务由春季靴子#ComponentScan加载,一切正常,直到我添加@Profile的新实施

@Service
@Profile("p1")
public class ProfileMessageGenerator implements MessageGenerator {
    @Override
    public Message getMessage() {
        return doSmthWithProfile();
    }
}

PropertiesMessageGenerator处于上下文中时,如何停止加载到DI服务ProfileMessageGenerator

PS 我无法在@Profile("default")上使用MultipleMessages,因为我有更多配置文件,我一次加载。

2 个答案:

答案 0 :(得分:2)

如果您不使用组件扫描,则可以使用@Qualifier

定义并选择bean

如果要维护使用组件扫描,请使用@Conditional注释。

创建自己的'org.springframework.context.annotation.Condition.class'实现并将其传递给注释。

这可以读取一个属性来定义它何时返回true,可以在你想要的内容中设置它。

如果您不想实现自己的条件,可以使用

@ConditionalOnMissingBean(MessageGenerator.class)

或者只使用@Primary注释ProfileMessageGenerator。

答案 1 :(得分:0)

聚会有点晚,但可能对未来的访客有所帮助:

我通过像这样配置我的服务使其在 Spring Boot 2.5.1 中工作:

@Service
@ConditionalOnMissingBean(value = BaseService.class, ignored = DefaultService.class)
public class DefaultService implements BaseService {
    ...
}

如果注释中没有 ignored 字段,条件将匹配 DefaultService,因此不会实例化它。这种行为有点奇怪,但将自身排除在条件之外使其起作用。有了这个,我可以创建一个额外的 BaseService 实现,它只是用 @Service 注释,而不是实例化 DefaultService 而是另一个实现。