Java 我可以重写使用类路径扫描定义的Springbean定义吗?

Java 我可以重写使用类路径扫描定义的Springbean定义吗?,java,spring,plugins,Java,Spring,Plugins,我有一个应用程序,它有一个非常简单的插件架构,通过使用spring类路径扫描注册其他行为(“安装”插件是通过将plugin.jar放在类路径上实现的) 这对于注册其他bean非常有效,对于注册这样的钩子也非常有效: //core.jar: @组成部分 类核心类{ public void addListener(侦听器侦听器){/*…*/} } //plugin.jar @组成部分 类插件{ 公共插件(CoreClass CoreClass){ addListener(新的PluginListen

我有一个应用程序,它有一个非常简单的插件架构,通过使用spring类路径扫描注册其他行为(“安装”插件是通过将plugin.jar放在类路径上实现的)

这对于注册其他bean非常有效,对于注册这样的钩子也非常有效:

//core.jar:
@组成部分
类核心类{
public void addListener(侦听器侦听器){/*…*/}
}
//plugin.jar
@组成部分
类插件{
公共插件(CoreClass CoreClass){
addListener(新的PluginListener());
}
}
然而,有时替换整个bean更合适。这可能是这样的:

//core.jar:
@组件(“someBean”)
类CoreClass实现CoreInterface{
@凌驾
公共无效doStuff();
}
//plugin.jar
@组件(“someBean”)
@顺序(最高优先级)
类插件实现CoreInterface{
@凌驾
公共无效doStuff();
}
在这种情况下,我希望在启动期间通过类路径扫描发现
Plugin
CoreClass
,但是应该忽略
CoreClass
,因为bean
someBean
有另一个具有更高优先级的定义

我知道我可以使用XML(
)来实现这一点,因为XML允许覆盖定义。但是使用注释也可以吗


编辑:注意,有时我会有多个相同类型的bean实例(具有不同的属性),我会基于名称注入这些实例。因此,我实际上需要用特定的名称覆盖bean。

可能使用的解决方案:

@Primary

指示当多个候选项有资格自动关联单值依赖项时,应优先考虑bean。如果候选对象中只存在一个“主”bean,那么它将是自动连接的值

该注释在语义上等同于SpringXML中元素的主属性

可用于直接或间接用@Component注释的任何类或用@Bean注释的方法

// core.jar:
@Component
class CoreClass implements CoreInterface {
  @Override
  public void doStuff();
}

// plugin.jar
@Component
@Primary
class Plugin implements CoreInterface {
  @Override
  public void doStuff();
}

或者您可以使用:

@Configuration  
@ImportResource( { "classpath*:core-spring.xml", "classpath*:plugin-spring.xml" } )  
public class ConfigClass { } 
我怀疑注释的问题不清楚要覆盖哪个顺序,如果您在相同名称的注释上定义,您将最终得到
冲突BeanDefinitionException
spring将不允许您使用相同名称的
@Component
@Bean
。在xml中,您可以管理覆盖顺序,这就是为什么您可以在xml上这样做。在注释中,您不能这样做

任何给定的Spring上下文对于任何给定的id或名称只能有一个bean。对于XMLID属性,这是由模式验证强制执行的。对于name属性,这是由Spring的逻辑实现的

但是,如果上下文是由两个不同的XML描述符文件构造的,并且两个文件都使用了一个id,那么其中一个将“覆盖”另一个。确切的行为取决于上下文加载文件时文件的顺序

因此,虽然这是可能的,但不建议这样做。它容易出错且脆弱,如果您更改其中一个的ID而不是另一个的ID,您将无法从Spring获得帮助


但是,如果上下文是由两个不同的XML描述符文件构造的,并且两个文件都使用了一个id,那么其中一个将“覆盖”另一个。确切的行为取决于上下文加载文件时文件的顺序。

True,在上面显示的情况下,主要工作(基于类型的注入)。然而,在我的例子中,我经常有一个特定类型的多个实例,我注入基于名称的实例。但是@Primary仍然不允许用相同的名称定义两个bean。我怀疑您正在尝试做一些spring注定不会做的事情。我的建议是使用
@Primary
并在需要另一个bean的地方使用
@Qualifier