1. Interceptores y filtros
Antes de hablar sobre Spring Boot, veamos primero filtros e interceptores. Los dos son muy similares en términos de funciones, pero todavía hay una gran brecha en la implementación técnica específica. Antes de analizar las diferencias entre los dos, primero entendamos el concepto de AOP. AOP no es una tecnología específica, sino una idea de programación. En el proceso de programación orientada a objetos, es fácil para nosotros resolver la expansión vertical a través de la herencia y el polimorfismo. Sin embargo, para las funciones horizontales, como habilitar las transacciones en todos los métodos de servicio, o el registro unificado, las funciones orientadas a objetos no se pueden resolver. Por lo tanto, la programación orientada a AOP es en realidad un suplemento a la idea de la programación orientada a objetos. Los filtros e interceptores de los que estamos hablando hoy son implementaciones específicas de la programación orientada a los aspectos. Las principales diferencias entre los dos incluyen los siguientes aspectos:
1. El filtro depende de los contenedores de servlet y es parte de la especificación de servlet. Los interceptores existen de forma independiente y pueden usarse bajo cualquier circunstancia.
2. La ejecución del filtro se completa con la devolución de la devolución del contenedor Servlet, y el interceptor generalmente se ejecuta a través de un proxy dinámico.
3. El ciclo de vida del filtro es administrado por el contenedor de servlet, mientras que el interceptor se puede gestionar a través de contenedores del COI. Por lo tanto, se pueden obtener instancias de otros frijoles a través de la inyección y otros métodos, por lo que será más conveniente de usar.
2. Configuración de filtro
Ahora usamos filtros para realizar la función de registrar el tiempo de ejecución de las solicitudes, que se implementa de la siguiente manera:
Public Class logCostFilter implementa el filtro {@Override public void init (filterConfig FilterConfig) lanza ServletException {} @Override public void dofilter (servletRequest ServletRequest, servletResponse ServletResponse, Filterchain Filterchain) Trails ioexception, servletexception filterChain.dofilter (ServLetRequest, ServLetResponse); System.out.println ("Ejecutar cost ="+(System.CurrentTimemillis ()-inicio)); } @Override public void destruye () {}}La lógica de este código es relativamente simple, que es registrar la marca de tiempo antes de ejecutar el método, y luego completar la ejecución de la solicitud a través de la cadena de filtro y calcular el tiempo de ejecución entre los resultados devueltos. Lo principal aquí es que esta clase debe heredar la clase de filtro. Esta es la especificación de Servlet, que no es diferente de los proyectos web anteriores. Sin embargo, con la clase de filtro, los proyectos web anteriores se pueden configurar en Web.xml, pero el proyecto Spring Boot no tiene el archivo web.xml, entonces, ¿cómo configurarlo? En Spring Boot, necesitamos FilterRregistrationBean para completar la configuración. El proceso de implementación es el siguiente:
@ConfigurationPublic Class FilterConfig {@Bean public FilterRegistrationBean RegistrationFilter () {FilterRegistrationBean Registration = new FilterRegistrationBean (); Registration.SetFilter (new LogCostFilter ()); Registration.addurlPatterns ("/*"); Registration.SetName ("LogCostFilter"); Registration.SetOrder (1); Registro de devolución; }}Esta configuración se completa. Las opciones que deben configurarse incluyen principalmente instanciar la clase de filtro y luego especificar el patrón de coincidencia de la URL, configurar el nombre del filtro y el orden de ejecución. Este proceso en realidad no es diferente de la configuración en Web.xml, pero la forma es simplemente diferente. Ahora podemos iniciar el servidor para acceder a cualquier URL:
Puede ver que la configuración anterior ha entrado en vigencia. Además de configurar a través de FilterRregistrationBean, también hay una forma más directa, que se puede completar directamente a través de anotaciones:
@WebFilter (urlPatherns = "/*", filtername = "logFilter2") public class logCostFilter2 implementa filtro {@Override public void init (filterconfig filtreConfig) lanza ServletException {} @Override public Void void dofilter (servletRequest SERVEL IoException, servletException {long start = system.currentTimemillis (); filterChain.dofilter (ServLetRequest, ServLetResponse); System.out.println ("logFilter2 ejecute cost =" + (system.currentTimemillis () - inicio)); } @Override public void destruye () {}}Aquí puede configurarlo directamente con @WebFilter. Del mismo modo, puede establecer el modo de coincidencia de URL, el nombre del filtro, etc. Una cosa a tener en cuenta aquí es que la anotación @WebFilter es una especificación de Servlet 3.0 y no lo proporciona el arranque de Spring. Además de esta anotación, también necesitamos agregar otra anotación a la clase de configuración: @ServletComponetScan, especificando el paquete escaneado.
@Springbootapplication@mapperscan ("com.pandy.blog.dao")@servletComponentsCan ("com.pandy.blog.filters") aplicación de clase pública {public static void main (string []) lanza la excepción {springapplication.run (aplicación.class, args); }} Ahora, visitemos cualquier URL nuevamente:
Como puede ver, ambos filtros que configuramos han entrado en vigencia. Los lectores cuidadosos encontrarán que no especificamos el orden de ejecución del segundo filtro, sino que ejecutarán antes del primer filtro. Debe explicarse aquí que la anotación @WebFilter no especifica el atributo de orden de ejecución. Su orden de ejecución depende del nombre del filtro y se organiza en orden inverso en función del orden alfabético del nombre de la clase del filtro (tenga en cuenta que no es el nombre del filtro configurado). La prioridad del filtro especificada por @WebFilter es más alta que el filtro configurado por FilterRegistrationBean. Los amigos interesados pueden experimentar por su cuenta.
3. Configuración del interceptor
Ya hemos introducido el método de configuración de filtro anterior. A continuación, echemos un vistazo a cómo configurar un interceptor. Utilizamos un interceptor para implementar la misma función anterior, registrando el tiempo de ejecución de la solicitud. Primero implementamos la clase Interceptor:
public class logCostInterceptor implementa HandlerInterceptor {Long Start = System.CurrentTimemillis (); @Override public boolean prehandle (httpservletRequest httpservletRequest, httpservletResponse httpServletResponse, objeto o) arroja excepción {start = system.currentTimEmillis (); devolver verdadero; } @Override public void postthandle (httpservletRequest httpservletRequest, httpservletResponse httpServletResponse, objeto o, modelandView modelandView) lanza la excepción {System.out.println ("Interceptor Costo ="+(System.CurrentTimemillis ()-Start)))); } @Override public void AfterComppletion (httpservletRequest httpservletRequest, httpservletResponse httpServletResponse, objeto o, excepción e) arroja excepción {}}Aquí necesitamos implementar la interfaz Handlerinterceptor. Esta interfaz incluye tres métodos. El prehufe se ejecuta antes de ejecutar la solicitud, y el posthandler se ejecuta después de ejecutar la solicitud, pero solo se ejecutará cuando el método Prehandle devuelva verdadero. AfterComppletion se ejecuta después de que se completa la representación de la vista. Prehandle también necesita devolver verdadero. Este método generalmente se usa para limpiar recursos y otras tareas. Además de implementar la interfaz anterior, también necesitamos configurarla:
@ConfigurationPublic Class InterceptorConfig extiende WebMVCConfigurerAdapter {@Override public void addInterceptors (InterceptorRegistry Registry) {Registry.Addinterceptor (new LogCostInterceptore ()). AddPathPatherns ("/**"); super.addinterceptors (registro); }}Aquí heredamos WebMVCConfigurerAdapter. Los amigos que han leído los artículos anteriores deberían haber visto esta clase. Hemos utilizado esta clase al configurar el directorio de recursos estáticos. Aquí hemos reescrito el método AddInterceptors para configurar el interceptor. Hay dos elementos de configuración principales: uno es especificar el interceptor y el otro es especificar la URL del interceptor. Ahora iniciamos el sistema y accedemos a cualquier URL:
Como puede ver, logramos la misma función a través del interceptor. Sin embargo, debe tenerse en cuenta aquí que esta implementación es realmente problemática, ya que Prehandle y Postthandle son dos métodos, por lo que tenemos que establecer una variable compartida que comience a almacenar el valor de inicio, pero esto tendrá problemas de seguridad de los subprocesos. Por supuesto, podemos resolver este problema a través de otros métodos, como Threadlocal, que se pueden resolver bien, y los estudiantes interesados pueden implementarlo ellos mismos. Sin embargo, a través de esto podemos ver que aunque los interceptores son mejores que los filtros en muchos escenarios, en este escenario, los filtros son más simples de implementar que los interceptores.
4. Resumen
Este artículo explica principalmente la configuración de filtros e interceptores en función del arranque de primavera. Tanto los filtros como los interceptores pertenecen a la implementación específica de la idea de AOP (programación orientada a la sección). Además de estas dos implementaciones, también hemos visto otra tecnología de implementación de AOP más flexible, a saber, el aspecto, donde podemos completar funciones cada vez más poderosas a través del aspecto. Compartiré esto contigo más tarde.