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

jucafojl  于 2021-07-09  发布在  Java
关注(0)|答案(1)|浏览(349)

我有一个应用程序,它有一个非常简单的插件架构,通过使用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 应该忽略,因为 someBean 具有更高优先级的另一个定义。
我知道我可以使用xml来实现这一点( <import resource="classpath*:plugin-spring.xml" /> ),因为xml允许重写定义。但这是否也可以使用注解?
edit:请注意,我有时会有多个相同类型(具有不同属性)的bean示例,这些示例是我基于名称注入的。因此,我实际上需要用一个特定的名称覆盖bean。

wz1wpwve

wz1wpwve1#

可能使用的解决方案:
@初级
指示当多个候选对象有资格自动关联一个单值依赖项时,应优先考虑bean。如果候选对象中正好存在一个“primary”bean,那么它将是autowired值。
这个注解在语义上等同于springxml中元素的primary属性。
可用于直接或间接用@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();
}

http://memorynotfound.com/handling-multiple-autowire-candidates-with-spring-primary/
或者你可以使用:

@Configuration  
@ImportResource( { "classpath*:core-spring.xml", "classpath*:plugin-spring.xml" } )  
public class ConfigClass { }

我怀疑注解的问题是不清楚要覆盖哪个顺序,如果您在注解上定义相同的名称,您将得到相同的结果 ConflictingBeanDefinitionException Spring不会让你拥有 @Component 或者 @Bean 同名的。在xml中,您可以管理覆盖顺序,这就是为什么您可以在xml上这样做。在注解中你不能这样做。
对于任何给定的id或名称,任何给定的spring上下文只能有一个bean。对于xmlid属性,这是通过模式验证来实现的。对于name属性,这是由spring的逻辑实现的。
但是,如果上下文是由两个不同的xml描述符文件构造的,并且两个文件都使用了一个id,那么其中一个将“覆盖”另一个。确切的行为取决于上下文加载文件时文件的顺序。
因此,虽然这是可能的,但不建议这样做。它容易出错而且脆弱,如果您更改其中一个的id而不是另一个的id,那么您将得不到spring的帮助。
但是,如果上下文是由两个不同的xml描述符文件构造的,并且两个文件都使用了一个id,那么其中一个将“覆盖”另一个。确切的行为取决于上下文加载文件时文件的顺序。

相关问题