Dúvida Autowiring no Spring

5 respostas
R

Caros,

estou tentando implementar um controller genérico mas estou apanhando na injeção dos beans:

public class GenericController<T extends BaseModel> {
	@Resource
	public GenericDAO<T, Long> dao;

ERRO:

No unique bean of type [dao.GenericDAO] is defined: expected single matching bean but found 2: [cadeiraDAOImp, periodoDAOImp]

Eu entendo a causa do erro,só não entendo como posso usar o @Qualifier nesse caso.

5 Respostas

WRYEL

Isso acontece porquê em tempo de execução o Spring não consegue resolver os tipos genéricos : <T, Long> … ele está procurando por alguem que resolva GenericDAO apenas, e como acha dois candidatos, estoura exceção. Com o @Qualifier você resolveria este problema colocando implicitamente o nome do bean, mas, isso quase sempre me cheira gambiarra hehe :smiley:

Você teria que fazer alguma interface de especializacao, algo como:

interface UsuarioDAO extends GenericDAO<Usuario, Long> { }

@Repository
public class UsuarioDAOImpl extends GenericDAOImpl<Usuario, Long> implements UsuarioDAO {

}

depois, no seu controller:

public abstract class GenericController<B extends Serializable, DAO extends GenericDAO<B, ?>> {
     @Autowired
     private DAO dao;
}

Mas, lembrando que quanto mais generics você usar, mas sujo as camadas generics abaixo podem ficar :?

Eu tenho uma app/arquitetura que to fazendo pra brincar, que tem Controller / Model / DAO generico, de uma aqui (https://github.com/wryel/springmvc-tiles-jpa/), quem sabe a gente não pode discutir algumas ideias.

edit:

dao generico: https://github.com/wryel/springmvc-tiles-jpa/blob/master/springmvc-tiles-jpa-core/src/main/java/br/com/wryel/dao/impl/GenericJPADAOImpl.java

model generic: (business generico): https://github.com/wryel/springmvc-tiles-jpa/blob/master/springmvc-tiles-jpa-core/src/main/java/br/com/wryel/model/impl/GenericModelImpl.java

exemplo de uso de controller generico: https://github.com/wryel/springmvc-tiles-jpa/blob/master/springmvc-tiles-jpa-web/src/main/java/br/com/wryel/controller/UsuarioController.java

Essa minha mania de passar alguns tipos no contrutor, é para não ter que ficar marcando aqueles chatos supresswarning :wink: (dava para recuperar os tipos pelo genericSuperClass(), mais ai vai a questão de gosto)

[]'s

R

Boa tarde meu caro,é mais ou menos desse jeito que to tentando:

public interface PeriodoDAO extends GenericDAO&lt;Periodo,Long&gt; {
 public List&lt;Periodo&gt; findByExample(Periodo filtro,Modo modo);
}

Impl:

@Qualifier("periodoDAO")
@Component
public class PeriodoDAOImp extends GenericDAOImp&lt;Periodo,Long&gt;
implements PeriodoDAO
{

}
WRYEL

@Qualifier você diz explicitamente qual bean o Spring você quer que injete, é usado em campo ou setter e não em nome de classe. Ex:

public class Controller {
     @Autowired
     @Qualifier("nomeDoBeanSpring")
     private Bean bean;
     //... getter/setter
}

Lembrando que os nomes defaults dos beans Spring, é o nome da classe em camelCase :slight_smile:

R

WRYEL:
@Qualifier você diz explicitamente qual bean o Spring você quer que injete, é usado em campo ou setter e não em nome de classe. Ex:

public class Controller {
     @Autowired
     @Qualifier("nomeDoBeanSpring")
     private Bean bean;
     //... getter/setter
}

Lembrando que os nomes defaults dos beans Spring, é o nome da classe em camelCase :slight_smile:

Entendi,então no meu caso eu creio que não rola o @Qualifier:

@Resource
public GenericDAO<T, Long> dao;

Preciso achar outra forma de injetar a implementação.

WRYEL

vou falar do jeito básico, ai você formula algo com suas ideias.

public abstract class GenericController<DAO extends GenericDAO<?, ?>> {
     
     @Autowired
     private DAO dao;

     public void setDAO(DAO dao) {
          this.dao = dao;
     }

     public DAO getDAO() {
          return dao;
     }
}
@Controller // suponho que esteja no Spring MVC
public UsuarioController extends GenericController<UsuarioDAO> {
    ...
}

acredito que isto resolva seu problema inicial, a partir dai, e só tentar formar algo de seu gosto =)

Criado 18 de junho de 2012
Ultima resposta 18 de jun. de 2012
Respostas 5
Participantes 2