Injeção de Dependências

A idéia básica da injeção de dependências com VRaptor é injetar objetos na sua lógica de negócios ...

  1. Um simples exemplo poderia ser uma fábrica DaoFactory para criar os daos ... o exemplo seguinte é uma implementação simplificada somente para mostrar o conceito:
    public class DaoFactory {
    
            public PersonDao getPersonDao() {
                    return new PersonDao();
            }
    
            public StudentDao getStudentDao() {
                    return new StudentDao();
            }
    
    }
  2. Agora vamos criar um simples interceptor que cria a fabrica DaoFactory:

    Observe: A anotação @Out é usada para ejetar a fabrica no escopo da requisição ...

    public class DaoInterceptor implements Interceptor {
    
            @Out
            private DaoFactory factory = new DaoFactory();
    
            public void intercept(LogicFlow flow) throws LogicException,
                            ViewException {
                    // executa o próximo interceptor ou lógica
                    flow.execute();
            }
    
    }
  3. E finalmente, vamos criar o componente que recebe a fábrica pela injeção:
    @Component("injection")
    @InterceptedBy(DaoInterceptor.class)
    public class InjectionExample {
    
            @In
            private DaoFactory factory;
    
            public void test() {
                    // faz alguma coisa com a fábrica injetada
            }
    
    }

    Se você chama injection.test.logic o fluxo seguinte será executado:

    Criar Interceptor --> Chamar o método intercept -->
    
    Interceptor chama flow.execute --> Ejeção da fábrica -->
    
    Criar o Componente de Negócios --> Ler Parâmetros -->
    
    Chamar o Método da Lógica--> Redirecionamento ao View -->
    
    Finalização do Método intercept

Escopo da injeção

A injeção tem como padrão o escopo da requisição. Você pode usar os mesmos escopos da anotação @Out: também veja Tipo de escopo.

Injeção da dependência pelo construtor

VRaptor fornece a injeção pelo construtor procurando o objeto em todos os escopos. For exemplo:

public class InjectionExample {

        private DaoFactory factory;

        public InjectionExample(DaoFactory factory) {
                this.factory = factory;
        }

        public void test() {
                // faz alguma coisa com a fábrica injetada
        }

}

Se a fábrica pertence ao package org.vraptor.dao, VRaptor procura a chave org.vraptor.dao.DaoFactory em todos os escopos: lógica, requisição, sessão e aplicação, nesse ordem.

Se ele não acha nenhuma chave num escopo, o componente não pode ser criado e VRaptor gera uma exceção.

Ao contrário, se VRaptor consegue achar a chave, ele usa o seu valor e o passa para o construtor.

Nenhum componente pode ter mais do que um construtor, senão seria possível criar objetos complexos e componentes esquisitos com perigo de bugs .

Para implementar o exemplo acima corretamente, use a chave na anotação @Out:

public class DaoInterceptor implements Interceptor {

        @Out(key="org.vraptor.dao.DaoFactory")
        private DaoFactory factory = new DaoFactory();

        public void intercept(LogicFlow flow) throws LogicException,
                        ViewException {
                // executa o próximo interceptor ou lógica
                flow.execute();
        }

}

Como acessar diretamente o request/response/session/servlet context?

Para acessá-los basta definir um construtor que os receba como argumento:

public MyLogicConstructor(HttpServletRequest request) {
        this.request = request;
}

Armazene o request (ou outro objeto) como variável membro e faça o que quiser com ele.

Outra maneira é usar a injeção via @In:

          @In
          private HttpServletRequest request;

          @In
          private HttpServletResponse response;

          @In
          private HttpSession session;

                  @In
                  private ServletContext servletContext;