我想通过自定义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
注释,一切都按预期工作。
答案 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) {};
}
}