在用Spring框架写Service层服务的时候,我们一般都习惯定义一个service接口,再定义一个service实现类,在引用的时候我们就通过一个@Resource注解或者@Autowired注解,此时Spring会根据名称优先或类型优先注入Spring的Bean。
如果一个service实现类,实现了两个Service接口,Spring是怎么处理注入的呢?
一、代码示例我们就通过如下代码示例,看看一个Service实现类实现两个接口源码是怎么加载的:
public class AchievementController {
@Resource
private TestTwoApiService testTwoApiService;
@Service
@Slf4j
public class AchievementServiceImpl implements AchievementService, TestTwoApiService {
二、注入的源码
我们知道Bean的属性注入,会通过:
三、不同注解方式的处理 1、@Resource注解org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean
进入到:
org.springframework.context.annotation.CommonAnnotationBeanPostProcessor#autowireResource
通过name获取bean走的是这段代码:
if (this.fallbackToDefaultTypeMatch && element.isDefaultName && !factory.containsBean(name)) {
autowiredBeanNames = new linkedHashSet<>();
resource = beanFactory.resolveDependency(descriptor, requestingBeanName, autowiredBeanNames, null);
if (resource == null) {
throw new NoSuchBeanDefinitionException(element.getLookupType(), "No resolvable resource object");
}
}
else {
resource = beanFactory.resolveBeanByName(name, descriptor);
autowiredBeanNames = Collections.singleton(name);
}
我们知道BeanFactory存放Bean的beanName是什么?是Bean的类名的首字母小写,很遗憾,最后是通过遍历所有的bean,才匹配到:testTwoApiService。
private String[] doGetBeanNamesForType(ResolvableType type, boolean includeNonSingletons, boolean allowEagerInit) {
List result = new ArrayList<>();
// Check all bean definitions.
for (String beanName : this.beanDefinitionNames) {
这个流程和我们平时一个Bean的时候注入接口类是一致的,都要进行bean的遍历。
2、@Autowired注解上面的:
org.springframework.beans.factory.support.DefaultListableBeanFactory#doGetBeanNamesForType
方法走的也是@Autowired注解的方法
区别是在populateBean方法后,走的是这块方法:
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor#postProcessProperties四、总结
,所以就算一个Bean有多个接口,其注入的@Resource注解和@Autowired注解,源码的路径是不变的。



