【记录】spring中一个接口多个实现类

重构遇到个小问题,记录下:

错误信息:

***************************
APPLICATION FAILED TO START
***************************

Description:

Field xxxService in com.alibaba.xxx required a single bean, but 2 were found:

解决方法:

Action:

Consider marking one of the beans as @Primary, updating the consumer to accept multiple beans, or using @Qualifier to identify the bean that should be consumed

代码案例:

import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;

/**
 * 一个接口
 */
public interface DataTransferService {
    Long transferData() throws Exception;

}

/**
 * 实现类一
 * 重要:添加@Primary标记为默认初始化的类
 */
@Component("dataTransferService")
@Primary
class DataTransferServiceImpl implements DataTransferService {

    @Override
    public Long transferData() throws Exception {
        return 0L;
    }
}

/**
 *实现类二
 */
@Component("dataTransferServiceSync")
class DataTransferServiceSyncImpl implements DataTransferService {

    @Override
    public Long transferData() throws Exception {

        return 0L;
    }
}

使用方式:

/**
 * 两种使用方式,已测试
 */
public class ActivityDemo {
    /**方式一*/
    @Autowired
    @Qualifier("dataTransferService")
    protected DataTransferService dataTransferService;

    @Autowired
    @Qualifier("dataTransferServiceSync")
    protected DataTransferService dataTransferServiceSync;

    /**方式二*/

//    @Resource("dataTransferService")
//    protected DataTransferService dataTransferService;
//
//    @Resource("dataTransferServiceSync")
//    protected DataTransferService dataTransferServiceSync;
}

注意:添加@Primary告诉spring初始化时使用哪个主要的实现类。

补充:https://baijiahao.baidu.com/s?id=1608114169828948852&wfr=spider&for=pc

@Autowired与@Resource的区别

(1)@Autowired

@Autowired为Spring提供的注解,需要导入包org.springframework.beans.factory.annotation.Autowired;只按照byType注入。

@Autowired注解是按照类型(byType)装配依赖对象,默认情况下它要求依赖对象必须存在,如果允许null值,可以设置它的required属性为false。如果我们想使用按照名称(byName)来装配,可以结合@Qualifier注解一起使用。如下:

(2)@Resource

@Resource默认按照ByName自动注入,由J2EE提供,需要导入包javax.annotation.Resource。@Resource有两个重要的属性:name和type,而Spring将@Resource注解的name属性解析为bean的名字,而type属性则解析为bean的类型。

所以,如果使用name属性,则使用byName的自动注入策略,而使用type属性时则使用byType自动注入策略。如果既不制定name也不制定type属性,这时将通过反射机制使用byName自动注入策略。

猜你喜欢

转载自blog.csdn.net/the_fool_/article/details/84567778