Spring 4-Autowire通用接口

时间:2018-07-09 09:31:07

标签: java spring generics autowired

从Spring(v4.3.8)开始,当Spring尝试加载依赖项注入时遇到一个问题。

我想基于T(Debit1或Debit2)的类型调用ManagerImpl1.java或ManagerImpl2.java实现的“管理”方法。详细信息如下:

  

原因:   org.springframework.beans.factory.NoUniqueBeanDefinitionException:否   类型的合格豆   'com.xxx.xxx.datacollection.infoprod.Manager'   可用:预期的单个匹配bean,但发现2:   ManagerImpl1,ManagerImpl2

Business.java:

@Component
public class Business<T extends Debit> {

    @Autowired
    private Manager<T> manager;

    public void treatment(Context<T> context, FindServiceReturnMessage response) {

        manager.manage(response, context);
    }

Manager.java:

public interface Manager<T extends Debit> {

    void manage(final FindServiceReturnMessage response, Context<T> context);
}

ManagerImpl1.java:

@Component
public class ManagerImpl1 implements Manager<Debit1> {

    @Override
    public void manage(final FindServiceReturnMessage response, Context<Debit1> context) {

    }
}

ManagerImpl2.java:

@Component
public class ManagerImpl2 implements Manager<Debit2> {

    @Override
    public void manage(final FindServiceReturnMessage response, Context<Debit2> context) {

    }
}

此外,“借方1”和“借方2”实现了接口“借方”。

我尝试了几件事,但没有成功...

1 个答案:

答案 0 :(得分:0)

您需要在Bean上添加一个限定符,如下所示:

@Component
@Qualifier("managerImpl2")
public class ManagerImpl2 implements Manager<Debit2> {

    @Override
    public void manage(final FindServiceReturnMessage response, Context<Debit2> context) 
    {

    }
}

然后,当您要使用它时,请再次使用@Qualifier批注:

@Component
public class Business<T extends Debit> {

    @Autowired
    @Qualifier("managerImpl2")
    private Manager<T> manager;

    public void treatment(Context<T> context, FindServiceReturnMessage response) {

        manager.manage(response, context);
    }
}

但是,正如@dvorog在评论中所说,由于泛型不存在于编译中,因此您可能必须创建一个如下的Business接口:

public interface Business<T extends Debit> {

    public void treatment(Context<T> context, FindServiceReturnMessage response);
}

并实现BusinessImpl以在每次使用新型Debit时指定它:

@Component
public class ManagerImpl2Business<Debit2> {

    @Autowired
    @Qualifier("managerImpl2")
    private Manager<Debit2> manager;

    public void treatment(Context<Debit2> context, FindServiceReturnMessage response) {

        manager.manage(response, context);
    }
}

这将重复一遍,并且可能会以一些无法维护的代码或某些if (T instanceof Debit1)结尾,以使您的通用性正常工作。