JavaServer Faces (JSF) com Spring

JavaServer Faces (JSF) com Spring

1. Visão geral

Neste artigo, veremos uma receita para acessar beans definidos no Spring a partir de um bean gerenciado JSF e de uma página JSF, com o objetivo de delegar a execução da lógica de negócios nos beans Spring.

Este artigo presume que o leitor tenha um entendimento prévio do JSF e do Spring separadamente. O artigo é baseado emthe Mojarra implementation de JSF.

2. Na primavera

Vamos definir o seguinte feijão na primavera. O beanUserManagementDAO adiciona um nome de usuário a um armazenamento na memória e é definido pela seguinte interface:

public interface UserManagementDAO {
    boolean createUser(String newUserData);
}

A implementação do bean é configurada usando a seguinte configuração Java:

public class SpringCoreConfig {
    @Bean
    public UserManagementDAO userManagementDAO() {
        return new UserManagementDAOImpl();
    }
}

Ou usando a seguinte configuração XML:


Definimos o bean em XML e registramosCommonAnnotationBeanPostProcessor para garantir que a anotação@PostConstruct seja obtida.

3. Configuração

As seções a seguir explicam os itens de configuração que permitem a integração dos contextos Spring e JSF.

3.1. Configuração Java semweb.xml

Ao implementar oWebApplicationInitializer, podemos configurar programaticamente oServletContext.. A seguir está a implementaçãoonStartup() dentro da classeMainWebAppInitializer:

public void onStartup(ServletContext sc) throws ServletException {
    AnnotationConfigWebApplicationContext root = new AnnotationConfigWebApplicationContext();
    root.register(SpringCoreConfig.class);
    sc.addListener(new ContextLoaderListener(root));
}

OAnnotationConfigWebApplicationContext inicializa o contexto Spring’g e adiciona os beans registrando a classeSpringCoreConfig.

Da mesma forma, na implementação do Mojarra existe uma classeFacesInitializer que configura oFacesServlet.. Para usar esta configuração é suficiente estender oFacesInitializer.. A implementação completa doMainWebAppInitializer, é agora do seguinte modo:

public class MainWebAppInitializer extends FacesInitializer implements WebApplicationInitializer {
    public void onStartup(ServletContext sc) throws ServletException {
        AnnotationConfigWebApplicationContext root = new AnnotationConfigWebApplicationContext();
        root.register(SpringCoreConfig.class);
        sc.addListener(new ContextLoaderListener(root));
    }
}

3.2. Comweb.xml

Começaremos configurando oContextLoaderListener no arquivoweb.xml do aplicativo:


    
        org.springframework.web.context.ContextLoaderListener
    

Esse ouvinte é responsável por iniciar o contexto do aplicativo Spring quando o aplicativo da web é iniciado. Este ouvinte irá procurar por um arquivo de configuração do Spring chamadoapplicationContext.xml por padrão.

3.3. faces-config.xml

Agora configuramos oSpringBeanFacesELResolver no arquivoface-config.xml:

org.springframework.web.jsf.el.SpringBeanFacesELResolver

Um resolvedor EL é um componente conectável suportado pela estrutura JSF, permitindo personalizar o comportamento do tempo de execução JSF ao avaliar expressões de Expression Language (EL). Esse resolvedor EL permitirá que o tempo de execução JSF acesse os componentes Spring por meio de expressões EL definidas no JSF.

4. Acessando Spring Beans em JSF

Neste ponto, nosso aplicativo da web JSF está preparado para acessar nosso bean Spring a partir de um bean de backup JSF ou de uma página JSF.

4.1. De um Backing Bean JSF 2.0

Agora o bean Spring pode ser acessado a partir de um bean de backup JSF. Dependendo da versão do JSF que você está executando, existem dois métodos possíveis. Com o JSF 2.0, você usa a anotação@ManagedProperty no bean gerenciado JSF.

@ManagedBean(name = "registration")
@RequestScoped
public class RegistrationBean implements Serializable {
    @ManagedProperty(value = "#{userManagementDAO}")
    transient private IUserManagementDAO theUserDao;

    private String userName;
    // getters and setters
}

Observe que getter e setter são obrigatórios ao usar@ManagedProperty. Now - para garantir a acessibilidade de um bean Spring a partir de um bean gerenciado, adicionaremos o métodocreateNewUser():

public void createNewUser() {
    FacesContext context = FacesContext.getCurrentInstance();
    boolean operationStatus = userDao.createUser(userName);
    context.isValidationFailed();
    if (operationStatus) {
        operationMessage = "User " + userName + " created";
    }
}

A essência do método é usar o beanuserDao Spring e acessar sua funcionalidade.

4.2. De um Backing Bean em JSF 2.2

Outra abordagem, válida apenas no JSF2.2 e acima, é usar a anotação@Inject do CDI. Isso se aplica a beans gerenciados JSF (com a anotação@ManagedBean) e a beans gerenciados por CDI (com a anotação@Named).

De fato, com uma anotação CDI, este é o único método válido de injetar o bean:

@Named( "registration")
@RequestScoped
public class RegistrationBean implements Serializable {
    @Inject
    UserManagementDAO theUserDao;
}

Com essa abordagem, o getter e o setter não são necessários. Observe também que a expressão EL está ausente.

4.3. De uma visão JSF

O métodocreateNewUser() será acionado a partir da seguinte página JSF:


    
        
        
        
        
        
    

Para renderizar a página, inicie o servidor e navegue para:

http://localhost:8080/jsf/index.jsf

Também podemos usar EL na visualização JSF, para acessar o bean Spring. Para testá-lo, basta alterar o número da linha 7 da página JSF apresentada anteriormente para:

Aqui, chamamos o métodocreateUser diretamente no Spring DAO, passando o valor de vinculação deuserName para o método de dentro da página JSF, contornando o bean gerenciado todos juntos.

5. Conclusão

Examinamos uma integração básica entre os contextos Spring e JSF, onde podemos acessar um bean Spring em um bean e página JSF.

Vale ressaltar que, embora o tempo de execução JSF forneça a arquitetura conectável que permite que a estrutura Spring forneça componentes de integração, as anotações da estrutura Spring não podem ser usadas em um contexto JSF e vice-versa.

Isso significa que você não poderá usar anotações como@Autowired ou@Component etc. em um bean gerenciado JSF ou use a anotação@ManagedBean em um bean gerenciado Spring. No entanto, você pode usar a anotação@Inject em um bean gerenciado JSF 2.2+ e um bean Spring (porque Spring suporta JSR-330).

O código-fonte que acompanha este artigo está disponível emGitHub.