如何解决Java Spring-强制不继承bean
首先,一些代码:
interface Foo {
void bar();
}
@Configuration
class FooConfig {
@Bean
public Foo foo() { return new MagicFoo(); }
class MagicFoo implements Foo { ... }
}
@Component
class FooImpl implements Foo {
public void bar() { }
}
@Component
class BarImpl {
final Foo foo;
public BarImpl(Foo foo) { this.foo = foo; }
}
如本例所示,当实例化BarImpl
时,Spring框架将查找与Foo
匹配的bean,并且更喜欢FooConfig
定义的bean(即MagicFoo
)上的实现类FooImpl
。
我的问题是:是否有任何方法可以配置此代码,以使仅Bean直接与接口匹配(例如Foo
),而不是任何实现类(例如FooImpl
)都可以接受接口依赖性?即以某种方式将Spring配置为以这种特殊方式处理Foo
依赖项。
在这样的配置中,如果删除了FooConfig
,则尝试实例化BarImpl
时会出错,因为找不到合适的bean,即使有FooImpl
的bean也可以找到。换句话说,有了所需的配置,开发人员被迫为标识的接口显式定义bean,而不是将实现类标记为bean。
解决方法
如果您有多个实现Foo
的bean,它们都是自动装配类型Foo
的参数的候选对象。
您无法区分@Bean
创建的bean和@Component
创建的bean。
不过,您可以使用@Qualifier
来隔离/分离它们。
@Configuration
class FooConfig {
@Bean
@Qualifier("ABC")
public Foo foo() { return new MagicFoo(); }
class MagicFoo implements Foo { ... }
}
@Component
@Qualifier("XYZ")
class FooImpl implements Foo {
public void bar() { }
}
@Component
class BarImpl {
final Foo foo;
public BarImpl(@Qualifier("ABC") Foo foo) { this.foo = foo; }
}
现在该参数只能由@Bean
创建的bean自动装配,因为那是唯一具有正确限定符的参数。
至此,我已经通过以下设置完成了期望的行为:
- 我为实现创建了注释,不应将其用作特殊接口的bean。 (例如
@ActvityImplementation
)- 特殊接口还具有用于标识它们的关联注释。 (例如
@ActivityInterface
)
- 特殊接口还具有用于标识它们的关联注释。 (例如
- 我有一个配置类,该类提取所有带有
@ActivityImplementation
注释的Bean。 - 配置类在每个实现Bean上进行反映,以提取带有
@ActivityInterface
批注的接口。 - 对于每个实现Bean,我在Spring应用程序上下文中查询与接口匹配的Bean,并检查返回的Bean的类型。
- 如果返回的bean与实现类型匹配(而不是预期的“魔术”类型),则会抛出错误。
此逻辑确保我(以及使用该框架的其他任何人)都不会忘记配置“魔术”界面实现。存在“魔术”实现时,它是为接口返回的bean。当“魔术”实现不存在时,Spring退回到实现Bean,然后触发错误。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。