今天debug代码时,遇到一个坑
public interface LoopService {void testLoop();void testInnerLoop();
}@Service
public class DefaultLoopService implements LoopService {private static final Logger log = LoggerFactory.getLogger(DefaultLoopService.class);@Overridepublic void testLoop() {log.info("DefaultLoopService");}@Overridepublic void testInnerLoop() {log.info("DefaultLoopService--testInnerLoop");}}@Service
@Primary
public class UsingLoopService implements LoopService {private static final Logger log = LoggerFactory.getLogger(UsingLoopService.class);@Autowiredprivate LoopService loopService;@Overridepublic void testLoop() {log.info("UsingLoopService");loopService.testInnerLoop();}@Overridepublic void testInnerLoop() {log.info("UsingLoopService--testInnerLoop");}
}@RestController
public class LoopController {@Autowiredprivate LoopService loopService;@GetMapping("/testLoop")public void testLoop() {loopService.testLoop();}
}
当我请求http://localhost:8080/testLoop时,
期望打印
UsingLoopService : UsingLoopService
UsingLoopService : UsingLoopService–testInnerLoop
但实际却打印
UsingLoopService : UsingLoopService
UsingLoopService : DefaultLoopService–testInnerLoop
我的解决方案
给UsingLoopService命名
@Service("usingLoopService")
@Primary
public class UsingLoopService implements LoopService {private static final Logger log = LoggerFactory.getLogger(UsingLoopService.class);@Autowired@Qualifier("usingLoopService")private LoopService loopService;@Overridepublic void testLoop() {log.info("UsingLoopService");loopService.testInnerLoop();}@Overridepublic void testInnerLoop() {log.info("UsingLoopService--testInnerLoop");}
}
这时打印符合预期
UsingLoopService : UsingLoopService
UsingLoopService : UsingLoopService–testInnerLoop
请教
哪位大神有更好的解决方案,不防写在下面评论区↓\downarrow↓
后续
今天收到了spring官方的回复
the logic locates in org.springframework.beans.factory.support.DefaultListableBeanFactory@L1533
protected Map<String, Object> findAutowireCandidates(&#64;Nullable String beanName, Class<?> requiredType, DependencyDescriptor descriptor) {String[] candidateNames &#61; BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this, requiredType, true, descriptor.isEager());Map<String, Object> result &#61; CollectionUtils.newLinkedHashMap(candidateNames.length);for (Map.Entry<Class<?>, Object> classObjectEntry : this.resolvableDependencies.entrySet()) {Class<?> autowiringType &#61; classObjectEntry.getKey();if (autowiringType.isAssignableFrom(requiredType)) {Object autowiringValue &#61; classObjectEntry.getValue();autowiringValue &#61; AutowireUtils.resolveAutowiringValue(autowiringValue, requiredType);if (requiredType.isInstance(autowiringValue)) {result.put(ObjectUtils.identityToString(autowiringValue), autowiringValue);break;}}}for (String candidate : candidateNames) {if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, descriptor)) {addCandidateEntry(result, candidate, descriptor, requiredType);}}if (result.isEmpty()) {boolean multiple &#61; indicatesMultipleBeans(requiredType);DependencyDescriptor fallbackDescriptor &#61; descriptor.forFallbackMatch();for (String candidate : candidateNames) {if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, fallbackDescriptor) &&(!multiple || getAutowireCandidateResolver().hasQualifier(descriptor))) {addCandidateEntry(result, candidate, descriptor, requiredType);}}if (result.isEmpty() && !multiple) {for (String candidate : candidateNames) {if (isSelfReference(beanName, candidate) &&(!(descriptor instanceof MultiElementDescriptor) || !beanName.equals(candidate)) &&isAutowireCandidate(candidate, fallbackDescriptor)) {addCandidateEntry(result, candidate, descriptor, requiredType);}}}}return result;}