Olá Pessoal, bom dia!
Tenho uma classe PortariaService, que é responsável pela regra de negócio
@Component
public class PortariaService extends Service<MovimentacaoPortaria>{
private PortariaRepository repository;
public PortariaService(PortariaRepository repository) {
super(repository);
}
/* outros métodos de regra de negócio */
}
MovimentacaoPortaria é uma interface, estas classes a implementam, e cada uma tem seu respectivo DAO que implementa PortariaRepository
-
MovimentacaoEquipamento - MovimentacaoEquipamentoDAO
-
MovimentacaoFuncionario - MovimentacaoFuncionarioDAO
-
MovimentacaoVisitante - MovimentacaoVisitanteDAO
Quando eu receber a requisição no controller, por exemplo na action adiciona, eu vou receber uma MovimentacaoPortaria, e passar pro PortariaService
@Resource
public class PortariaController {
private final Result result;
private final PortariaService service;
public PortariaController(Result result, PortariaService service) {
this.result = result;
this.service = service;
}
@Post
public void adiciona(MovimentacaoPortaria portaria) throws AdicionarException{
this.service.adiciona(portaria);
}
}
O VRaptor usa o Spring pra gerenciar DI, certo?
A minha dúvida é: Como o Spring/VRaptor (não sei quem irá fazer isso) saberá qual DAO injetar?
Há alguma config que eu possa fazer pra dizer qual deve ser injetado?
Desde já agradeço galera!
Abraço!
mausexdd, já li a documentação.
Quando eu tenho um Service que recebe um repository implementado por apenas um DAO, ele injeta normal.
Mas quando eu tenho mais de um DAO implementando um repository, como o Spring/Vraptor saberá qual injetar?
Essa é minha dúvida.
Por exemplo, eu teria a interface PortariaRepository
public interface PortariaRepository extends Repository<MovimentacaoPortaria> { }
E teria 3 classes implementando ela
@Component
public class MovimentacaoEquipamentoDAO implements PortariaRepository{ /* */ }
@Component
public class MovimentacaoFuncionarioDAO implements PortariaRepository{ /* */ }
@Component
public class MovimentacaoVisitanteDAO implements PortariaRepository{ /* */ }
Como o Spring ou Vraptor, vai saber qual injetar no Service?
Boa tarde
Então Bruno, como o VRaptor é baseado em Spring você pode realizar a injeção através do construtor ou atributo, para resolver seu problema eu tentaria através do atributo e com a anotação @Autowired, ficaria assim:
@Autowired
@Qualifier(value="nomeImplementacao")
private Service service;
Falou.
Legal Vinicius, não sabia disso. Valeu 
Mas, ainda não resolve meu problema, pois só vou saber qual implementação veio em tempo de execução
e como vc vai decidir qual é a implementação em tempo de execução?
o @Autowired resolve no caso do spring, mas é em tempo de compilação.
se for algo dinâmico (por exemplo baseado na requisição) vc poderia criar um ComponentFactory
Será decidido qual é a implementação por meio de um Enum, que cada tipo contém Lucas.
public enum TipoMovimentacaoPortaria {
EQUIPAMENTO("Equipamentos"), FUNCIONARIO("Funcionário"), VISITANTE("Visitante");
private String nome;
TipoMovimentacaoPortaria(String nome) {
this.nome = nome;
}
public String getNome() {
return nome;
}
}
Lucas, o ComponentFactory seria como este, certo?
http://vraptor.caelum.com.br/cookbook/componentfactory-como-seletor-de-implementacoes/
Mas, como eu pegaria o TipoMovimentacaoPortaria dessa maneira?
é esse componentFactory mesmo
Não sei, onde está essa informação?
Lucas, vou receber no controller uma MovimentacaoEquipamento, por exemplo, pelo método adiciona
/* No Controller */
@Post("/portaria/adiciona/equipamento")
public void adiciona(MovimentacaoEquipamento movimentacao){ /* lógica */ }
public interface MovimentacaoPortaria {
TipoMovimentacaoPortaria getTipo();
}
public class MovimentacaoEquipamento implements MovimentacaoPortaria{
/* getters e setters */
public TipoMovimentacaoPortaria getTipo() {
return TipoMovimentacaoPortaria.EQUIPAMENTO;
}
}
Pelo TipoMovimentacaoPortaria, da pra saber qual implementação injetar.
Mas, como eu pegaria isso no ComponentFactory?
bglbruno já que vc está trabalhando com um tipo especifico de Movimentacao vc faz no seu método a chamada ao repositorio especifico.
do contrario, vc poderia trabalhar com movimentacao e chamar um rep. generico pra isso
abrasss
jeito mais fácil:
crie uma classe:
@Component
public class Portarias {
//recebe todas as portariasRepository no construtor
PortariaRepository getRepository(TipoMovimentacaoPortaria tipo) {
//retorna o cara certo
}
}
recebe esse cara no controller e usa ele pra pegar o cara desejado.
vc pode ainda deixar isso mais dinâmico, recebendo uma List no construtor da Portarias, e decidindo qual vai ser usada por um método nessa interface (tipo um getTipo)
Verdade cara, valeu!
Mas, e pra fazer desse modo dinâmico, se eu receber uma List<PortariaRepository>, os repositórios terão que estar anotados com @Component, certo?
E como funciona, o VRaptor vai saber montar a List<PortariaRepository> de todos repositórios anotados?
Não entendi como seria esse método getTipo que disse cara, pode dar um exemplo?
sim, se vc tem vários componentes que implementam uma interface, vc pode receber uma lista dela no construtor.
o get tipo seria algo do tipo:
class MovimentacaoEquipamentoDAO... {
getTipo => EQUIPAMENTO
}
Legal, beleza Lucas!
Entendi, é ,esse método já tem, pensei que fosse algo diferente 
Obrigado, vou implementar 