У меня была похожая проблема, но я хотел использовать одну фабрику для создания макетных реализаций моих автопроводных зависимостей с использованием JMockit (инфраструктуры тестирования, которую я должен использовать).
После того, как я не нашел удовлетворительного решения для сетей, я собрал простое решение, которое очень хорошо работает для меня.
Мое решение также использует Spring FactoryBean
, но оно использует только один фабричный bean-компонент для создания всех моих bean-компонентов (что, как кажется, хотел сделать первоначальный запросчик).
Мое решение состояло в том, чтобы реализовать мета-фабрику фабрики, которая обслуживает FactoryBean
упаковщиков вокруг реальной единственной фабрики.
Вот Java для моей фабрики JMockit:
public class MockBeanFactory<C> implements FactoryBean<C> {
private Class<C> mockBeanType;
protected MockBeanFactory(){}
protected <C> C create(Class<C> mockClass) {
return Mockit.newEmptyProxy(mockClass);
}
@Override
public C getObject() throws Exception {
return create(mockBeanType);
}
@Override
public Class<C> getObjectType() {
return mockBeanType;
}
@Override
public boolean isSingleton() {
return true;
}
public static class MetaFactory {
public <C> MockBeanFactory<C> createFactory(Class<C> mockBeanType) {
MockBeanFactory<C> factory = new MockBeanFactory<C>();
factory.mockBeanType = mockBeanType;
return factory;
}
}
}
А затем в XML-файле контекста Spring вы можете просто создать мета-фабрику, которая создает конкретные фабрики типа бина:
<bean id="metaFactory" class="com.stackoverflow.MockBeanFactory$MetaFactory"/>
<bean factory-bean="metaFactory" factory-method="createFactory">
<constructor-arg name="mockBeanType" value="com.stackoverflow.YourService"/>
</bean>
Чтобы это работало в ситуации оригинального аскера, его можно настроить, чтобы сделать FactoryBeans
оберткой / адаптером для serviceFactoryBean
:
public class FancyFactoryAdapter<C> implements FactoryBean<C> {
private Class<C> clientClass;
private FancyFactory serviceFactoryBean;
protected FancyFactoryAdapter(){}
@Override
public C getObject() throws Exception {
return serviceFactoryBean.buildService(clientClass);
}
@Override
public Class<C> getObjectType() {
return clientClass;
}
@Override
public boolean isSingleton() {
return true;
}
public static class MetaFactory {
@Autowired FancyFactory serviceFactoryBean;
public <C> FancyFactoryAdapter<C> createFactory(Class<C> clientClass) {
FancyFactoryAdapter<C> factory = new FancyFactoryAdapter<C>();
factory.clientClass = clientClass;
factory.serviceFactoryBean = serviceFactoryBean;
return factory;
}
}
}
Затем в XML (обратите внимание, что идентификатор userServiceFactory
и идентификатор компонента userService
необходимы только для работы с аннотацией @Qualifier
):
<bean id="metaFactory" class="com.stackoverflow.FancyFactoryAdapter$MetaFactory"/>
<bean id="userServiceFactory" factory-bean="metaFactory" factory-method="createFactory">
<constructor-arg name="clientClass" value="com.captain.services.UserServiceInterface"/>
</bean>
<bean id="userService" factory-bean="userServiceFactory"/>
<bean id="scoreServiceFactory" factory-bean="metaFactory" factory-method="createFactory">
<constructor-arg name="clientClass" value="com.captain.services.ScoreServiceInterface"/>
</bean>
<bean id="scoreService" factory-bean="scoreServiceFactory"/>
И это все, только один маленький Java-класс и небольшая часть конфигурации рабочей панели и ваша фабрика пользовательских компонентов могут создать все ваши компоненты и заставить Spring успешно их разрешить.