Ir al contenido principal

Instalando Apache NetBeans 10 y configurarlo con Jakarta EE

AOP con Java EE 6

En un anterior Post hablé sobre AOP usando Spring. Es un post algo antiguo, y me había basado de un artículo publicado en JavaRanch.

Esa vez fue usando el famoso Framework Spring, pero esta vez mencionaré como funciona el AOP desde Java EE6. Creo que ya existía desde la versión EE 5, pero no importa, aquí lo mencionamos para el deleite de todos.

A diferencia del Spring, es que este AOP funciona desde un contenedor Java EE, y sobretodo, en un EJB. En Spring funciona desde cualquier aplicación que tenga la biblioteca Spring.

Así que, para que funcione nuestro ejemplo, debemos crear un módulo EJB.. pero esta vez - a diferencia de otros tutoriales - crearemos una Aplicación Enterprise (EA) con un módulo EJB y WAR. El EA se llama aop-ea, y los módulos se llaman aop-ejb y aop-war respectivamente.



Luego, en nuestro módulo EJB crearemos una clase común y silvestre llamada MonitoreoInterceptor y tendrá el siguiente contenido:
package com.apuntesdejava.aop.ejb.interceptor;

import java.lang.reflect.Method;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.interceptor.AroundInvoke;
import javax.interceptor.InvocationContext;

public class MonitoreoInterceptor {
    static final Logger LOGGER=Logger.getLogger(MonitoreoInterceptor.class.getName()); //para mostrar el log
    
    @AroundInvoke //Define un método interceptor que se interpondrá en los métodos del EJB
    public Object seguimientoMetodo(InvocationContext invocationContext) throws Exception{
        Object objetoInterceptado=invocationContext.getTarget();
        Method metodoInterceptado=invocationContext.getMethod();
        // para mostrar el metodo que se va a ejecutar
        LOGGER.log(Level.INFO, "Ejecutando m\u00e9todo: {0}.{1}()", 
                new Object[]{objetoInterceptado.getClass().getName(), metodoInterceptado.getName()});
        
        Object o=invocationContext.proceed(); //hacemos ejecutar el método, o si hay otro interceptor, le damos la posta
        // la variable devuelta es el resultado del método, o NULL si es un método VOID
        
        LOGGER.log(Level.INFO, "Saliendo del m\u00e9todo: {0}.{1}()", 
                new Object[]{objetoInterceptado.getClass().getName(), metodoInterceptado.getName()});
        
        LOGGER.log(Level.INFO, "EL m\u00e9todo devuelve el valor: {0}", o);
        
        return o; //que continue la secuencia
    }
    
}

Solo aquí hemos definido el interceptor. Ahora, crearemos un EJB en el móduglo EJB con un par de métodos y lo interceptamos con la clase que acabamos de crear.
package com.apuntesdejava.aop.ejb.facade;

import com.apuntesdejava.aop.ejb.domain.Persona;
import com.apuntesdejava.aop.ejb.interceptor.MonitoreoInterceptor;
import java.util.ArrayList;
import java.util.List;
import javax.ejb.Stateless;
import javax.interceptor.Interceptors;


@Stateless
public class PersonaFacade {

    private static List<Persona> personas = new ArrayList<Persona>();

    @Interceptors({MonitoreoInterceptor.class}) //le colocamos un conjunto de interceptores
    public void nuevo(Persona p) { //el método es uno común y corriente.
        personas.add(p);
    }

    @Interceptors({MonitoreoInterceptor.class})// tambien le colocamos un conjunto de interceptores
    public List<Persona> lista() { //este método devuelve algo
        return personas;
    }
}

Y desde un Servlet llamamos al EJB como si fuera cualquier EJB común.

Uno de los grandes beneficios es que no necesitaremos que heredar código para hacer algo repetitivo, ni repetir el código en todo lugar donde se necesite. Por ejemplo, si queremos monitorear el acceso a ciertas partes de la lógica de negocio, lo colocamos en el Interceptor, y si queremos cambiar la manera cómo vamos a manejar el monitereo, pues claro.. cambiamos solo un interceptor.
//...
@WebServlet(name = "ListaServlet", urlPatterns = {"/ListaServlet"})
public class ListaServlet extends HttpServlet {

    @EJB
    private PersonaFacade personaFacade;

    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        List<Persona> lista = personaFacade.lista();
        request.setAttribute("lista", lista);
        RequestDispatcher rd = request.getRequestDispatcher("/lista.jsp");
        rd.forward(request, response);
    }

//...
Además, también podemos ejecutarlo desde un Cliente EJB... Con algunas consideraciones en el EJB, tenemos el siguiente código para el cliente EJB:

//...
public class Main {

    @EJB
    private static PersonaFacadeRemote personaFacade;

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        Persona p1 = new Persona(1, "Ana");
        Persona p2 = new Persona(1, "Bernardo");
        Persona p3 = new Persona(1, "Carl");
        personaFacade.nuevo(p1);
        personaFacade.nuevo(p2);
        personaFacade.nuevo(p3);
    }
}


El resultado en el Servidor es el siguiente..


Y listo!.. ya estoy monitoreando los métodos!!

Este post  no pretendió ser un tutorial de  EJB, por lo que me he saltado muchas cosas. El objetivo de este post es solo mostrar como funciona el AOP. Para la creación de un EJB con cliente lo veremos en otro artículo.


El código fuente de este post, incluyendo el cliente de EJB se puede descargar desde aquí: http://kenai.com/projects/apuntes/downloads/download/AOP/aop-ea.tar.gz


Más información sobre los Interceptors, aquí, en la documentación de Java EE 6: http://download.oracle.com/javaee/6/tutorial/doc/gkeed.html

Twitter

Facebook

Comentarios

Entradas más populares de este blog

RESTful... la forma más ligera de hacer WebServices (Parte 1)

Quienes hayan usado SOAP para WebService, sabrán que es bien fácil de diseñar, pero algo complicado de consumir: se necesita toda una API para construir los clientes utilizando el WSDL. Por ejemplo, para PHP se necesita de la biblioteca NuSOAP. Entonces, para lograr el concepto de "lenguaje único XML" es un dolor de cabeza. Y más aún si el cliente es tan simple como JavaScript, manejar XML de SOAP provocaría suicidos masivos... o no usar WebServices.

Además, con SOAP se permite crear un solo servicio y ponerle varios métodos. Esto puede llevar a un mal diseño del servicio ya que podría tener un servicio que haga de todo: por ejemplo, un servicio de manejo de Clientes que permita también manejar Proveedores.

RESTful es una propuesta muy interesante de Roy Fielding que permite manejar los servicios web con métodos definidos, manteniendo la simpleza del protocolo como XML, pero que cada servicio sea identificado únicamente con un solo URI.

En este post veremos cómo crear un Ser…

¿Por valor o por referencia?

Esta es una pregunta existencial para todo programador Java. Cada uno encuentra una respuesta satisfactoria. Pero ahora veremos, basándonos en el libro para Certificación SCJP 1.5 de Katty Sierra, sobre la respuesta correcta.

Contraseñas encriptadas con Java

¿Quién no ha querido encriptar texto o archivo? Hay diversas maneras para hacer eso, por ejemplo, utilizando un diccionario donde se reemplazara cada caracter por un código.. y para poder desencriptarlo se debería utilizar el mismo diccionario para revertir el proceso. Pero si el diccionario cae en manos de alguien que no queremos que lo sepa, entonces estamos en peligro.
Cuando yo programaba en pascal, mi encriptación favorita era invirtiendo los bits... pero cualquiera también puede invertir los bits y listo.
Pero ya gente experta logró algoritmos de encriptación populares. Los más conocidos: MD5 y SHA.
En este post hablaremos cómo encriptar texto, sobretodo las contraseñas, utilizando MD5 o SHA.