如何在Spring中按条件提供默认bean?

mem*_*und 5 java spring autowired

我想通过自定义 jar 提供默认 bean。仅当用户实现特定abstract类时,才应跳过默认 bean 注入。

以下设置已经可以正常工作,除了一件事:default有线类中的任何注入类都是null!我可能会缺少什么?

@Configration
public class AppConfig {
    //use the default service if the user does not provide an own implementation
    @Bean
    @Conditional(MissingServiceBean.class)
    public MyService myService() {
        return new MyService() {};
    }
}


@Component
public abstract class MyService {
    @Autowired
    private SomeOtherService other;

    //default impl of the method, that may be overridden
    public void run() {
        System.out.println(other); //null! Why?
    }
}

public class MissingServiceBean implements Condition {
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        return context.getBeanFactory().getBeansOfType(MyService.class).isEmpty();
    }
}
Run Code Online (Sandbox Code Playgroud)

beanMyService已创建并且也可以被注入。但包含的类为空。

如果我删除@Conditioanl注释,一切都会按预期进行。

Mar*_*rey 4

最简单的可能性是使用注释@Primary。您定义接口/抽象类并构建默认实现。到这里为止,这就是基本的弹簧自动装配。

现在,您可以创建另一个实现@Primary并使其在应用程序上下文中可用。Spring 现在将选择自动装配的主要实现。


Spring 4.1+ 中的另一种可能性是自动装配有序的List<Intf>,并通过调用询问接口supports(...)来获取您输入的任何参数的当前实现supports。您给予默认实现 alow priority以及更详细的实现更高的优先级。像这样,您甚至可以构建更详细的默认行为。我将这种方法用于多种配置,以处理具有默认和特定实现的不同类。

一个例子是在权限评估期间,我们有一个针对基类的默认配置,另一个针对域类的更高配置,以及针对特定域实体的甚至更高的可能配置。权限评估器遍历列表并检查每个实现是否支持该类,并在这种情况下委托给实现。

我这里没有代码,但如果需要的话我可以稍后分享以使其更清楚。