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

时间:2014-08-27 08:28:07

标签: 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();
    }
}

创建了MyService bean,也可以注入它。但是包含的类是null。

如果删除@Conditioanl注释,一切都按预期工作。

2 个答案:

答案 0 :(得分:3)

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

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


Spring 4.1+中的另一个可能性是自动装配一个有序的List<Intf>,并要求接口进行supports(...)调用,以获取您为supports提供的任何参数的当前实现。您为默认实现提供low priority,更详细的实现优先级更高。像这样,您甚至可以构建更详细的默认行为。我在几种配置中使用这种方法来处理具有默认和特定实现的不同类。

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

我这里没有代码,但如果希望更清楚,我可以稍后分享。

答案 1 :(得分:0)

将您的代码更改为以下内容:

public abstract class MyService {

    private final SomeOtherService other;

    public MyService(SomeOtherService other) {
       this.other = other;
    }

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

@Configration
public class AppConfig {

    @Autowired
    private SomeOtherService other;

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