如何按条件在Spring中提供默认bean? [英] How to provide a default bean in Spring by condition?

查看:350
本文介绍了如何按条件在Spring中提供默认bean?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'd like to provide a default bean by a custom jar. Only if the user implements a specific abstract class the default bean injection should be skipped.

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

The following setup already works fine, except one thing: any injected classes within the default wired class are null! What might I be missing?

@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已创建,也可以注入.但是包含的类为空.

The MyService bean is created and can also be injected. But contained classes are null.

如果我删除了@Conditioanl批注,那么一切都会按预期进行.

If I remove the @Conditioanl annotation everything works as expected.

推荐答案

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

Your simplest possibility is the usage of the @Primary annotation. You define your interface/abstract class and build a default implementation. Until here thats the basic spring autowiring.

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

Now you create another implementation with @Primary and make it available in the application context. Spring will now pick up the primary implementation for the autowiring.

Spring 4.1+中的另一种可能性是自动连接有序的List<Intf>,并通过supports(...)调用询问接口以获取当前实现的参数,无论您为supports输入什么参数.您为默认实现指定了low priority,而更详细的实现则具有更高的优先级.这样,您甚至可以构建更详细的默认行为.我将这种方法用于几种配置,以使用默认的和特定的实现来处理不同的类.

Another possibilty in Spring 4.1+ would be to autowire an ordered List<Intf> and ask the interface with a supports(...) call to fetch the current implementation for whatever parameter you give into supports. You give the default implementation a low priority and the more detailed ones a higher priority. Like this you can even build a more detailed default behavior. I'm using this approach for several configurations to handle different classes with default and specific implementations.

一个示例是权限评估期间的示例,在该示例中,我们为基类提供了默认配置,为域类提供了另一个更高的配置,对于特定域实体有一个更高的可能配置.权限评估者将遍历列表,并检查每个实现是否支持该类,并在这种情况下委托给实现.

One example would be during permission evaluation where we have a default config for the base classes, another higher one for domain classes, and a even higher possible one for specific domain entities. The permission evaluator goes through the list and checks each implementation if it supports that class and delegates to the implementation in that case.

我这里没有代码,但是如果需要更清楚些,我可以稍后共享.

I dont have the code here but i could share it later if desired to make that more clear.

这篇关于如何按条件在Spring中提供默认bean?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆