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