Spring中无法修改依赖类时,优先装配子类Bean实现方法覆写
要让ABC.m2()调用XYZExtended.m1(),核心是让Spring把XYZExtended实例作为XYZ类型的Bean注入到ABC中,以下是几种不需要修改ABC.java的实现方式:
方法一:使用@Primary注解
在XYZExtended上添加@Primary注解,当Spring容器中有多个XYZ类型的Bean时,会优先选择标记了@Primary的实例注入到ABC中。
修改后的XYZExtended代码:
@Service @Primary class XYZExtended extends XYZ{ @Override public void m1(){ // 重写后的业务逻辑 } }
注意:如果原XYZ类保留@Service注解,Spring会同时创建两个Bean,但@Primary会确保ABC注入的是XYZExtended。若不需要原XYZ实例,可直接移除其@Service注解。
方法二:覆盖原Bean的名称
Spring中同名称的Bean会被后注册的覆盖。默认@Service会以类名首字母小写作为Bean名称(比如XYZ的Bean名为xyz),给XYZExtended指定相同名称即可覆盖原Bean。
修改后的XYZExtended代码:
@Service("xyz") class XYZExtended extends XYZ{ @Override public void m1(){ // 重写后的业务逻辑 } }
此时Spring只会创建XYZExtended的实例,ABC中注入的自然是该实例。若原XYZ保留@Service,需确保XYZExtended的注册顺序在其之后,或直接移除原XYZ的@Service注解。
方法三:使用@Conditional排除原Bean
若需保留原XYZ的@Service注解,但只让XYZExtended生效,可给XYZ添加@Conditional注解,让它在XYZExtended存在时不被注册。
修改原XYZ类:
@Service @Conditional(NoXYZExtendedCondition.class) class XYZ { public void m1(){ } }
实现条件判断类:
public class NoXYZExtendedCondition implements Condition { @Override public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { // 检查容器中是否存在XYZExtended的Bean定义 return !context.getBeanFactory().containsBeanDefinition("xyzExtended"); } }
XYZExtended保持原注解即可:
@Service class XYZExtended extends XYZ{ @Override public void m1(){ // 重写后的业务逻辑 } }
这种方式可灵活控制Bean的注册逻辑,适合需要根据环境切换的场景。
内容的提问来源于stack exchange,提问作者Avinash kumar

