簡體   English   中英

如何在春季通過泛型變量注入bean

[英]How to inject bean via generic variable in spring

我在用泛型類型注入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();
    }

您必須命名組件並按名稱自動接線:

@Component("A")
public class A implements IRepository<String,String> {...}

@Component("B")
public class B implements IRepository<Double,String> {...}

[...]

@Autowired
@Qualifier("B")
private IRepository repo;

看來您事先並不知道將需要IRepository接口的哪種實現。 您將在運行時知道這一點。 在這種情況下,這是Factory模式的典型情況,在這種情況下,您將擁有一個IRepositoryFactory ,該方法將具有按類型檢索特定實現的方法(例如IRepositoryFactory.getInstance(String type);因此,在ServiceABC您可以使用IRepository來獲取運行時使用特定的bean。因此,Factory模式可能是您問題的答案。我還寫了一篇文章來處理此類問題,並提出了自我填充Factory的想法(使用提供此類實用程序的開源庫)。文章鏈接: 在Spring框架中非侵入式訪問“孤立” Bean

這樣的東西?

@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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM