Spring Test Framework e problema de autowiring baseado em anotação
-
12-09-2020 - |
Pergunta
Eu gostaria de usar duas implementações diferentes para um DAO com testframework do Spring.
src.main.java
.businessobjects
\-User.java
.dao
\-IUserDAO.java
.daojpa
\-UserDAO.java
.daohibernate
\-UserDAO.java
O caso de teste da primavera em:
src.test.java.base:
package base;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("/hibernate-beans.xml")
@Transactional
public abstract class SpringTestCase {}
E aqui está o erro:
Causado por:java.lang.IllegalStateException:Nome do bean especificado por anotação 'userDAO' para a classe de bean [jpadao. UserDAO] conflitos com os existentes, definição de feijão não compatível do mesmo Nome e classe [JPAADAO. UserDAO]
Já tentei substituir a ligação automática usando qualificadores, por exemplo:
<bean class="jpaadao.UserDAO">
<qualifier value="jpaa"/>
</bean>
<bean class="jpadao.UserDAO">
<qualifier value="jpa"/>
</bean>
E então na fiação do caso de teste com
@Autowired
@Qualifier("jpa")
private IUserDAO userDAO;
mas o erro persiste.
Duas questões:
- Como esse problema pode ser resolvido com configuração baseada em anotações?
- Como posso executar testes SEM fiação automática e anotações?
Solução
Você está usando beans sem nomes para que o Spring tente criar um nome, esse nome pode ser baseado na anotação @Component que você provavelmente tem em sua classe, mas também pode ser a versão camelcased de sua classe não qualificada nome do seu bean (em ambos os casos eles seriam iguais e isso faria com que o Spring se opusesse).
Além disso, parece que você está misturando verificação de componentes e configuração xml de uma forma que me parece um pouco estranha.
Há muitas maneiras de resolver isso, mas de maneira mais clara, você usaria apenas um único bean implementando o contrato que está tentando cumprir.Se você precisar de implementações diferentes, deverá dar-lhes nomes diferentes e mais descritivos:
<bean id="jpaUserRepository" class="..JpaUserRepository"/>
Isso fornecerá um registro mais útil, mesmo que os nomes dos beans nunca sejam usados porque você depende da fiação automática.
Outras dicas
- Faça o que Iwein sugeriu:nomeie melhor suas classes de implementação (por exemplo, HibernateUserDao e JpaUserDao);ou especifique um nome de bean exclusivo por meio da anotação @Component ou @Repository em suas classes de implementação UserDAO.
- Atualmente, você não pode executar testes sem ligação automática.Consulte este problema do JIRA para obter detalhes: https://jira.springsource.org/browse/SPR-6050
Cumprimentos,
Sam (autor do Spring TestContext Framework)
p.s.Não, o problema que você está enfrentando não está relacionado ao SPR-4524.
Você pode tentar injetar o nome da dependência usando o @Resource
anotação.Você terá que dar nomes (ids) aos beans ou usar o padrão, que é o nome da classe não qualificado e sem letras maiúsculas.
Eu tenho tudo instalado e funcionando agora!No entanto, não acredito que esta seja a melhor prática.Simplesmente excluí o caminho dos DAOs indesejados escrevendo em appContext.xml:
<context:component-scan base-package="test">
<context:exclude-filter type="regex" expression="test\.daohibernate.*"></context:exclude-filter>
</context:component-scan>
Alguma sugestão?Esse problema poderia estar relacionado http://jira.springframework.org/browse/SPR-4524 ?