Usam instanciacao normal?
Usam algum container de DI ? Qual? Poderia ilustrar um exemplo de configuração dessa injeção?
Usam aspectos? Poderiam me passar um exemplo?
Estou com dúvidas nisso! Obrigado!
Usam instanciacao normal?
Usam algum container de DI ? Qual? Poderia ilustrar um exemplo de configuração dessa injeção?
Usam aspectos? Poderiam me passar um exemplo?
Estou com dúvidas nisso! Obrigado!
Normalmente uso uma interface na camada de domínio.
E na camada de persistência uma classe que implementa essa interface.
E, pra que o domínio saiba qual classe que implementa aquela interface, uso DI.
Normalmente uso uma interface na camada de domínio.E na camada de persistência uma classe que implementa essa interface.
E, pra que o domínio saiba qual classe que implementa aquela interface, uso DI.
Você quer dizer que usa DI, assim:
class Person {
private PersonRepository repository; // <---- AQUI VOCÊ USA DI?
}
Usam instanciacao normal?
Usam algum container de DI ? Qual? Poderia ilustrar um exemplo de configuração dessa injeção?
Usam aspectos? Poderiam me passar um exemplo?
Em tese todos esses métodos são iguais.
Vc precisa definir o repositorio no construtor da classe.
Se vc o passa manualmente ou com injeção é irrelevante para a construção da classe.
class Person {
private final PersonRepository repository;
public Person (PersonRepository repository){
this.repository = repository;
}
}
O que vc não deve fazer é
class Person {
private PersonRepository repository;
}
e esperar milagres.
Esse código espera que exista um DI e isso fazer suposição. Supor é sempre ruim.
Usam instanciacao normal?
Usam algum container de DI ? Qual? Poderia ilustrar um exemplo de configuração dessa injeção?
Usam aspectos? Poderiam me passar um exemplo?
Em tese todos esses métodos são iguais.
Vc precisa definir o repositorio no construtor da classe.
Se vc o passa manualmente ou com injeção é irrelevante para a construção da classe.class Person { private final PersonRepository repository; public Person (PersonRepository repository){ this.repository = repository; } }O que vc não deve fazer é
class Person { private PersonRepository repository; }e esperar milagres.
Esse código espera que exista um DI e isso fazer suposição. Supor é sempre ruim.
Isso significa que há outra camada de uso acima da Person, demosntrada neste exemplo?
Como ficaria a sua utilização ?
Edit: Em outras palavras, de uma maneira de boa prática: quem estaria criando o repositório e passando a Person ?
Isso significa que há outra camada de uso acima da Person, demosntrada neste exemplo?
Como ficaria a sua utilização ?Edit: Em outras palavras, de uma maneira de boa prática: quem estaria criando o repositório e passando a Person ?
Não existe essa outra camada.
Agora, onde vc precisa inicializar Person ? Vc faria isso no repository/dao usando create() algo como
PersonRepository rep = new PersonRepository ();
Person p = rep.create();
// dentro de create
public Person create(){
return new Person(this);
}
Assim é fácil. O Repositorio auto injeta-se no person.
Na prática vc nunca pode dar um new em Person directamente. Vc precisa de um outro objeto
para fazer isso. Seja o repositorio/dao , seja um objeto especifico para isso , ou seja via DI
Se vc usar DI então o container irá prover a implementação de PersonRepository para Person quando criar o objeto person. Para isso vc precisa inicializar Person sempre através do container. Algo como (com Guice)
Person p = Guice.getInjector().getInstance(Person.class);
Claro que, assim, não precisa do método create() no repositorio/dao
Isso significa que há outra camada de uso acima da Person, demosntrada neste exemplo? Como ficaria a sua utilização ?Edit: Em outras palavras, de uma maneira de boa prática: quem estaria criando o repositório e passando a Person ?
Não existe essa outra camada.
Agora, onde vc precisa inicializar Person ? Vc faria isso no repository/dao usando create() algo como
PersonRepository rep = new PersonRepository (); Person p = rep.create(); // dentro de create public Person create(){ return new Person(this); }Assim é fácil. O Repositorio auto injeta-se no person.
Na prática vc nunca pode dar um new em Person directamente. Vc precisa de um outro objeto
para fazer isso. Seja o repositorio/dao , seja um objeto especifico para isso , ou seja via DISe vc usar DI então o container irá prover a implementação de PersonRepository para Person quando criar o objeto person. Para isso vc precisa inicializar Person sempre através do container. Algo como (com Guice)
Person p = Guice.getInjector().getInstance(Person.class);Claro que, assim, não precisa do método create() no repositorio/dao
Valeu amigão, só para finalizar, poderias validar minha arquitetura baseada em DDD, e dizer se está correta ou não?
class arch.domain.business.entity.Person {
private PersonRepository rep;
public Person(PersonRepository rep) { this.rep = rep; }
//gets / sets
//comportamentos
public void store() {
rep.save(this);
}
}
class arch.domain.business.repository.PersonRepositoryImpl implements PersonRepository {
private PersonDAO personDAO;
public void save(Person p) {
personDAO.save(p);
}
}
Pelo codigo que vc mosrtrou não tem nada errado. Você está usando ActiveRecord com Repositorio mutável e DAO. Eu não usaria active record, mas isso sou eu.
Valeu amigão, só para finalizar, poderias validar minha arquitetura baseada em DDD, e dizer se está correta ou não?
Pelo codigo que vc mosrtrou não tem nada errado. Você está usando ActiveRecord com Repositorio mutável e DAO. Eu não usaria active record, mas isso sou eu.
Obrigado pelo esclarecimento, amigo!
Poderia me dizer o que faria você optar por utilizar gerenciadores ao invés de AR ?
Concordo com o Sergio: pelo construtor fica direto e sem magia negra.
Poderia me dizer o que faria você optar por utilizar gerenciadores ao invés de AR ?
A pergunta seria “O que me faria usar AR”. A resposta : nada.
AR não é sério para sistema grandes. Essa é a minha opinião.
Quando vc está gerenciando transações com objetos (padrão WorkUnit) o fato do objeto poder passar por cima disso tudo é muiito ruim. O objeto simplesmente não deve ter essa responsabilidade. Atrapalha.
Se o objeto está vindo do Contexto Persistente (EntityManager, Hibernate Session) quem injeta?
Só injeto coisas na entidade quando elas são necessárias para as responsabilidades da entidade. Salvar-se não é uma responsabilidade da entidade.
Não faz sentido algum uma entidade precisar se salvar.
Uma sugestão bem legal em minha opinião está aqui:
New Improvements in Domain Object Dependency Injection Feature
Não sou fã do @Configurable, mas as outras opções de usar uma interface marcadora ou uma annotation própria para DI me pareceu interessante.
Alguém sabe se é possível fazer algo parecido com o Guice?
Se o objeto está vindo do Contexto Persistente (EntityManager, Hibernate Session) quem injeta?
Neste caso, imagino que o ideal seria passar o repositório por parâmetro do método da entidade.
turma.getAlunosReprovados(alunoRepository);
Na opinião de vocês é também uma opção válida?
Se o objeto está vindo do Contexto Persistente (EntityManager, Hibernate Session) quem injeta?
No Hibernate e JPA+Hibernate, que injeta é um interceptor configurado no hibernate.cfg.xml ou programaticamente. Fica bem legal.
(atualmente ou injeto na mão ou faço magia negra com AOP)
Se o objeto está vindo do Contexto Persistente (EntityManager, Hibernate Session) quem injeta?
Neste caso, imagino que o ideal seria passar o repositório por parâmetro do método da entidade.
turma.getAlunosReprovados(alunoRepository);
Na opinião de vocês é também uma opção válida?
Válida sim, util, dificilmente. Isso obriga a ter uma referencia ao repositorio e não ha como injetar pq
é um método que vc vai usar em alguns casos. Por outro lado, se vc tem a referencia ao repositorio
vc simplesmente faz rep.getAlunosReprovados(turma) que é muito mais claro.
Ou seja, em principio vc não passa objetos de infra como parametros dos seus métodos de negocio. É estranho.
Quanto ao Guice. Guice é muito mais simples que Spring. Ele já parte do conceito de que é possivel injetar qualquer coisa em qualquer lugar. Vc coloca um @Inject onde quer que ele assuma a configuração.
E não ha xml envolvido. É um conceito melhor: configuração via codigo.
Além disso o Guice é extensivel. Vc pode configurar um escopo especial para os seus objetos de entidade , por exemplo, e injetar coisas neles sempre que eles são criados. Isso é muito baba com Guice.
Ou seja, assim como no spring, seu eu fizer
o guice conseguirá fazer a injeção de dependência nesta nova instância de aluno?
Se é isso mesmo que entendi Sérgio, que maravilha. Eu já estava mesmo querendo uma opção ao Spring, mas as vezes que procurei recurso como este para o Guice não encontrei.
Se o objeto está vindo do Contexto Persistente (EntityManager, Hibernate Session) quem injeta?
Só injeto coisas na entidade quando elas são necessárias para as responsabilidades da entidade. Salvar-se não é uma responsabilidade da entidade.
Não faz sentido algum uma entidade precisar se salvar.
Mas e o ActiveRecord ? Faz isso muito bem, não acha ?
Nao confundir Active Record (o padrao, que tb eh diferente de ActiveRecord, a implementacao do Rails) com DDD, please. Uma briga de cada vez 
IMHO, HashMaps convertidos do HttpServletRequest, sanitizados e enfiados no PreparedStatement sao um bom comeco. O que vem dali eh organizacao latente e a putaria toda tem que ser ditada pela sua linguagem ubiqua. Se o cliente disse que o usuario salva o documento no servidor, o melhor eh chegar o mais perto possivel de um
…em algum lugar do seu sistema.
É mesmo estranho uma entidade se salvar. Por exemplo, a entidade está se salvando onde? O próprio comando save lembra que o estado da entidade está sendo levado (salvo) em algum lugar fora de onde sua aplicação está rodando naquele momento.
Já no caso do repositório, você tem os métodos add e remove. Você coloca o objeto no repositório. Vc recupera um objeto do repositório. Aonde seu objeto está sendo guardado? No repositório… o seu domínio + repositório é auto suficiente.
Repositório por si só já traz pra você este desacoplamento do mundo exterior (persistência), enquanto o AR parece trazer este mundo externo para dentro do seu domínio.
…voce prefere que ela seja estuprada por um Repositorio. Sem problemas. Eu prefiro objetos que não arrancam as cuecas dos outros nos meus sistemas, muitobrigado.
E tambem eh uma dependencia circular enorme.
Ou seja, assim como no spring, seu eu fizero guice conseguirá fazer a injeção de dependência nesta nova instância de aluno?
Não. Não é isso. Não ha milagres. Ninguem ( ainda) consegue interceptar new.
Vc faz assim
class AlgumServicoDeAlunos {
@Inject AlunoRepository rep;
public void fazAlgo (){
Aluno aluno = rep.encontraPorInscrição(123454554);
// faz algo
rep.store(aluno);
}
}
class AlunoRepository {
@Inject DAO dao;
@Inject Provider<Aluno> pa;
public Aluno create(){
return pa.get();
}
public ALuno encontraPorInscrição(int inscricao){
Map <String,Object > res = dao.executeQuery("select * from aluno where aluno.inscricao = " + inscrisao);
Aluno aluno = pa.get();
// preenche aluno com os campos do mapa
aluno.setID(res.get("id"));
aluno.setInscricao(res.get("inscricao"));
aluno.setNome(res.get("nome"));
// claro que poderia usar algum mapper... é só um exemplo.
// o ponto é que o aluno é obtido vazio e preenchido
retorna aluno;
}
}
class Aluno {
@Inject AlunoRepository rep;
public List<Notas> getNotas(Curso curso){
return rep.getNotas(curso);
}
}
// no modulo de configuração (que é uma classe)
binder.bind(Provider<Aluno>.class).to(AlunoFactory.class).in(Singleton.class) ;
binder.bind(AlunoRepository.class).to(AlunoRepositoryImpl1.class).in(Singleton.class) ;
binder.bind(DAO.class).to(JDBCDAO.class).in(Singleton.class) ;
Provider é uma interface do guice para atuar como fabrica. Vc pode criar suas proprias.
Repare que vc amarra classes/interfaces com classes, mas pode amarrar classes/interfaces com instancias tb.
E pode fazer a amarração num certo escopo (Singleton vem incluso, mas o padrão é “sem escopo” ao contrário do Spring em que o padrão é o singleton.
Nota: Embora o escopo se chame singleton ele é na realidade a implementação do padrão Shared Object.
humm, sobre o Guice, bacana, Sérgio.
mas…
O link que eu coloquei anteriormente é exatamente isso. Como interceptar o new. Eu já consegui implementar, só que usando o primeiro exemplo citado no exemplo, usando @Configurable.
Agora que o surgiram essas novas features no spring (aperfeiçoando as opções além de @Configurable), podemos optar por colocar uma anotação própria do domain para marcar o objeto para receber a dependência, ou se preferir, marcar seu objeto com uma interface de marcação.
Mas e o ActiveRecord ? Faz isso muito bem, não acha ?
IMHO, se alguém anota uma classe de @Entity e logo em seguida enfia um save() e passa a chamá-la de Active Record, esse cara não entendeu nem o que é um Contexto Persistente pra início de conversa.
Escreví isso na minha coluna da MundoJava no artigo de ORM. Entidades não possuem operação salvar().
humm, sobre o Guice, bacana, Sérgio.mas…
O link que eu coloquei anteriormente é exatamente isso. Como interceptar o new.
?!? Pode citar onde diz isso ? Não encontrei.
O que o SPring faz é dar o new por vc (padrão factory) não interceptar o new.
Na realidade ele invoca o construtor via reflection. Nem sequer manipula o new per se.
Mas e o ActiveRecord ? Faz isso muito bem, não acha ?IMHO, se alguém anota uma classe de @Entity e logo em seguida enfia um save() e passa a chamá-la de Active Record, esse cara não entendeu nem o que é um Contexto Persistente pra início de conversa.
@Entity marca o objeto como entidade não como persistente. Logo, pode ser usada mesmo fora de um contexto persistente. ( ha uma gambiarra no JPA associando entity==persistente. são duas coisas diferentes).
Se usa AR é porque não usa Contexto Persistente. Logo, não precisa entender o que é um Contexto Persistente porque nem está usando isso. AR é “contextless” e exactamente por isso é um problema.
Podem se usarem o padrão ActiveRecord …
Talvez ir direto no artigo seja meio confuso, mal.
Direto na fonte:
The support is intended to be used for objects created outside of the control of any container. Domain objects often fall into this category because they are often created programmatically using the new operator, or by an ORM tool as a result of a database query.The @Configurable annotation marks a class as eligible for Spring-driven configuration. In the simplest case it can be used just as a marker annotation:
http://static.springframework.org/spring/docs/2.5.x/reference/aop.html#aop-atconfigurable
Sergio… ou é Entidade ou é Active Record. Se vc colocou @Entity presume-se que você está usando JPA. Se está usando JPA presume-se que está usando um Contexto Persistente. Então, que sentido faria você anotar uma classe como @Entity sendo que ela não é persistente?
E mais uma vez… que sentido faz um Active Record ser anotado como @Entity.
Entity desde sempre nos dão sentido de continuidade. São objetos que você obtém hoje, altera e daqui a 2 meses eles vão manter esse estado. Que sentido faz uma entidade não ser persistente?
Talvez ir direto no artigo seja meio confuso, mal.Direto na fonte:
http://static.springframework.org/spring/docs/2.5.x/reference/aop.html#aop-atconfigurable
Isso só está dizendo que pode injetar coisas em objetos que não são criados no contexto. Não está dizendo
que intercepta o new.
Ele usa Load Time Weaving, e a injeção de dependência é feito por aspecto. No final, é só chamar um new da sua entidade e as dependências serão injetadas sem você tomar conhecimento disso. Ou seja, é DI + AOP.
Sergio… ou é Entidade ou é Active Record. Se vc colocou @Entity presume-se que você está usando JPA. Se está usando JPA presume-se que está usando um Contexto Persistente. Então, que sentido faria você anotar uma classe como @Entity sendo que ela não é persistente?
E mais uma vez… que sentido faz um Active Record ser anotado como @Entity.
Entity desde sempre nos dão sentido de continuidade. São objetos que você obtém hoje, altera e daqui a 2 meses eles vão manter esse estado. Que sentido faz uma entidade não ser persistente?
Ninguem falou que ela não é persistente. Apenas que não pertence a um Contexto de Persistencia. Ela é “detached” é livre e solta e se persiste a si mesma onde quiser. Annotações são metadados. Metadados não significam nada sem um contexto. Se o objeto não está no contexto do JPA a anotação entity é irrelevante.
Magia negra com AOP rulezowisky:
http://www.guj.com.br/posts/list/70275.java
Bom… a conversa encerra aqui. Sergio, realmente é difícil seguir uma linha de raciocínio com você. Na boa cara, sem briga. Se a porcaria do objeto tá marcado como @Entity você quer persistir ele num contexto JPA, não interessa se ele pode estar dettached. Precisa tomar cuidado, pois na maioria das vezes que ví um AR em JPA é porque o “arquiteto” não compreendeu direito os estados da entidade e não porque ele queria um AR.
Para os iniciantes: JPA não presume existência de Active Records (pelo menos nesse momento). Toda a infra é baseada em entities. Montar um AR goelabaixo só porque não compreendeu os estados da entidade é forçar a barra demais. Compreendo que é intuitivo colocar um salvar() naquilo que você quer salvar, mas não é assim que as coisas funcionam para uma entidade.
Usam instanciacao normal?
Usam algum container de DI ? Qual? Poderia ilustrar um exemplo de configuração dessa injeção?
Usam aspectos? Poderiam me passar um exemplo?Estou com dúvidas nisso! Obrigado!
Eu passo o repositorio como parametro no metodo da entidade.
E só complementando a informação, já existe um movimentozinho nesse sentido: http://www.javapolis.com/confluence/display/JP07/A+First+Look+at+ActiveHibernate. Tudo bem que é pra JRuby, mas não impede a utilização com Java. Enfim, é uma abordagem interesssante. Resta saber se vai dar certo!
Um detalhe, quando voces citam AR marcado como @Entity vcs estão levando em consideração um atributo do tipo EntityManager ou não?
@Entity marca o objeto como entidade não como persistente.
Bom… a conversa encerra aqui. Sergio, realmente é difícil seguir uma linha de raciocínio com você. Na boa cara, sem briga. Se a porcaria do objeto tá marcado como @Entity você quer persistir ele num contexto JPA,
Isso é o que vc acha. Por isso eu lhe disse que marcar como entity significa apenas isso: marcar como entity.
não significa ser persistente. Mas tb disse algo que vc olvidou: O JPA faz uma gambiarra associando entity==persistente. Tb lhe disse que @Entity é uma anotação , e como metadado que é não representa nada em si mesmo sem um contexto. Isso queria dizer que eu marco com @Entity o que bem me apetecer. Sem que isso tenha significado de persistencia. Apenas e quando, eu utilizar isso no contexto de JPA é que significa uma intensão de colocar o objeto/classe num contexto persistente. Mas isso acontece apenas e porque o JPA tem essa gamb. (O certo seria ter uma annotação @Persistable em separado de @Entity)
O objeto pode ser persistente sem utilizar JPA e mesmo assim usar @Entity. Ele pode ser marcado como entity e mesmo assim usar AR. (Claro que para começo de conversa ninguem falou de AR annotado com @entity … )
Não sei como naquelas duas frases vc encontra alguma contradição.