如何在春季通过通用变量注入bean

时间:2018-07-12 16:25:31

标签: java spring dependency-injection autowired

我在注入具有通用类型的bean时遇到问题。看例子。我将向服务注入类型从App类获取的存储库。现在我有例外:

没有可用的'asd.IRepository'类型的合格bean:预期为单个匹配bean,但找到了2:a,b

这里的asd是软件包,仅用于测试。

在这种情况下我该怎么办?有办法做到吗?

public interface IRepository<T, V> {
    void print();
}


@Component
public class A implements IRepository<String,String> {

    @Override
    public void print() {
        System.out.println("A");
    }
}

@Component
public class B implements IRepository<Double,String> {

    @Override
    public void print() {
        System.out.println("A");
    }
}

@Service
public class ServiceABC<V, T> {

    @Autowired
    private IRepository<V,T> repo;

    public void print(){
        repo.print();
    }
}

@Controller
public class App {

    @Autowired
    private ServiceABC<String, String> serviceABC;

    public static void main(String[] args) {
        ApplicationContext ctx =
                new AnnotationConfigApplicationContext("asd");

        App app = ctx.getBean(App.class);
        app.serviceABC.print();
    }

3 个答案:

答案 0 :(得分:0)

您必须命名组件并按名称自动接线:

sudo pip install opencv-python

答案 1 :(得分:0)

似乎您不预先知道需要哪种IRepository接口实现。您将在运行时知道这一点。在这种情况下,这是Factory模式的典型情况,其中您将拥有一个IRepositoryFactory,该方法将具有一种按类型检索特定实现的方法(例如IRepositoryFactory.getInstance(String type);,因此在您的ServiceABC中,您可以使用IRepository在运行时获取特定的bean。因此,Factory模式可能是您问题的答案。我还写了一篇文章,探讨了此类问题,并提出了自我填充Factory的想法(使用开源)提供此类实用程序的库)。这是文章的链接:Non-intrusive access to "Orphaned" Beans in Spring framework

答案 2 :(得分:0)

类似的东西吗?

@Controller
public class RepositoryFactory {

    @Autowired
    private IRepository<String, String> a;

    @Autowired
    private IRepository<Double, String> b;

    public IRepository getRepository(String className) {

        if(className.equalsIgnoreCase("a")) {
            return a;
        } else if(className.equalsIgnoreCase("b")) {
            return b;
        }

        return null;
    }
}

@Service
public class ServiceABC {

    @Autowired
    private RepositoryFactory repositoryFactory;

    public void print(String className){
        repositoryFactory.getRepository(className).print();
    }
}


@Controller
public class App {

    @Autowired
    private ServiceABC serviceABC;

    public static void main(String[] args) {
        ApplicationContext ctx =
                new AnnotationConfigApplicationContext("asd");

        App app = ctx.getBean(App.class);
        app.serviceABC.print(A.class.getSimpleName());
    }
}s