我有一个应用程序,它具有一个非常简单的插件体系结构,通过使用spring类路径扫描注册其他行为("安装"插件通过将plugin.jar放在类路径上)。
这适用于注册其他bean,它也适用于注册这样的钩子:
// core.jar:
@Component
class CoreClass {
public void addListener(Listener listener) { /* ... */ }
}
// plugin.jar
@Component
class Plugin {
public Plugin(CoreClass coreClass) {
coreClass.addListener(new PluginListener());
}
}
然而,有时更换整个bean更合适。这可能如下所示:
// core.jar:
@Component("someBean")
class CoreClass implements CoreInterface {
@Override
public void doStuff();
}
// plugin.jar
@Component("someBean")
@Order(HIGHEST_PRECEDENCE)
class Plugin implements CoreInterface {
@Override
public void doStuff();
}
在这种情况下,我希望在启动期间通过类路径扫描发现Plugin
和CoreClass
,但是应忽略CoreClass
,因为bean someBean
具有另一个具有更高优先权的定义。
我知道我可以使用XML(<import resource="classpath*:plugin-spring.xml" />
)来做到这一点,因为XML允许覆盖定义。但这也可以使用注释吗?
编辑:请注意,我有时会有多个相同类型的bean实例(具有不同的属性),我注入了基于名称的实例。因此,我实际上需要用某个名称覆盖bean。
答案 0 :(得分:0)
可能使用的解决方案:
<强> @Primary 强>
表示当多个候选者有资格自动装配单值依赖项时,应优先考虑bean。如果只是一个主要的&#39; bean存在于候选者之间,它将是自动装配的值。
此注释在语义上等同于Spring XML中元素的主要属性。
可以在任何直接或间接使用@Component注释的类或使用@Bean注释的方法上使用。
@Configuration
@ImportResource( { "classpath*:core-spring.xml", "classpath*:plugin-spring.xml" } )
public class ConfigClass { }
或者您可以使用:
ConflictingBeanDefinitionException
我怀疑注释问题不清楚要覆盖哪个顺序,如果你定义了符号相同的名称,你最终会使用@Component
spring将不允许你拥有@Bean
或{{ 1}}同名。在xml中,您可以管理覆盖顺序,这就是您可以在xml上执行此操作的原因。在注释中你不能这样做。
任何给定的 Spring上下文只能有一个bean用于任何给定的id或名称。对于XML id属性,这由架构验证强制执行。在name属性的情况下,这由Spring的逻辑强制执行。
但是,如果上下文是由两个不同的XML描述符文件构造的,并且两个文件都使用了一个id,那么将会覆盖&#34;覆盖&#34;另一个。确切的行为取决于文件在上下文加载时的顺序。
尽管可能,但不建议这样做。它容易出错且容易出错,如果你更改了一个而不是另一个的ID,你将无法从Spring获得帮助。
但是,如果上下文是由两个不同的XML描述符文件构造的,并且两个文件都使用了一个id,那么将会覆盖&#34;覆盖&#34;另一个。确切的行为取决于文件在上下文加载时的顺序。