1. Intercepteurs et filtres
Avant de parler de Spring Boot, regardons d'abord les filtres et les intercepteurs. Les deux sont très similaires en termes de fonctions, mais il y a toujours un grand écart dans la mise en œuvre technique spécifique. Avant d'analyser les différences entre les deux, comprenons d'abord le concept d'AOP. AOP n'est pas une technologie spécifique, mais une idée de programmation. Dans le processus de programmation orientée objet, il est facile pour nous de résoudre l'expansion verticale par l'héritage et le polymorphisme. Cependant, pour les fonctions horizontales, telles que l'activation des transactions dans toutes les méthodes de service, ou la journalisation unifiée, les fonctions orientées objet ne peuvent pas être résolues. Par conséquent, la programmation orientée AOP est en fait un complément à l'idée de la programmation orientée objet. Les filtres et les intercepteurs dont nous parlons aujourd'hui sont tous deux des implémentations spécifiques de la programmation axée sur l'aspect. Les principales différences entre les deux incluent les aspects suivants:
1. Le filtre dépend des conteneurs servlet et fait partie de la spécification du servlet. Les intercepteurs existent indépendamment et peuvent être utilisés en toutes circonstances.
2. L'exécution du filtre est complétée par le rappel de servlet, et l'intercepteur est généralement exécuté via un proxy dynamique.
3. Le cycle de vie du filtre est géré par le conteneur servlet, tandis que l'intercepteur peut être géré via des conteneurs IOC. Par conséquent, les instances d'autres haricots peuvent être obtenues par injection et d'autres méthodes, il sera donc plus pratique à utiliser.
2. Configuration du filtre
Nous utilisons maintenant des filtres pour réaliser la fonction de l'enregistrement du temps d'exécution des demandes, qui est implémentée comme suit:
classe publique LogCostFilter implémente Filter {@Override public void init (FilterConfig filterConfig) lève ServletException {} @Override public void Dofilter (ServletRequest ServletRequest, ServletResponse ServletResponse, filterChain filterChain) lance ioexception, servletException {Long Start = System.CurrentImmille ();); FilterChain.Dofilter (ServletRequest, ServletResponse); System.out.println ("Execute Cost =" + (System.Currenttimemillis () - START)); } @Override public void destre () {}}La logique de ce code est relativement simple, qui est d'enregistrer l'horodatage avant l'exécution de la méthode, puis de compléter l'exécution de la demande via la chaîne de filtre, et de calculer le temps d'exécution entre les résultats renvoyés. L'essentiel ici est que cette classe doit hériter de la classe de filtre. Il s'agit de la spécification de Servlet, qui n'est pas différente des projets Web précédents. Cependant, avec la classe de filtre, les projets Web précédents peuvent être configurés dans web.xml, mais le projet Spring Boot n'a pas le fichier web.xml, alors comment le configurer? Dans Spring Boot, nous avons besoin de filterRegistrationBean pour terminer la configuration. Le processus de mise en œuvre est le suivant:
@ConfigurationPublic Class FilterConfig {@Bean Public FilterRegistrationBean RegistrationFilter () {FilterRegistrationBean Enregistrement = new FilterRegistrationBean (); Enregistrement.SetFilter (new LogCostFilter ()); Enregistrement.AddurlPatterns ("/ *"); Enregistrement.SetName ("LogCostFilter"); Enregistrement. Enregistrement de retour; }}Cette configuration est terminée. Les options qui doivent être configurées incluent principalement l'instanciation de la classe de filtre, puis en spécifiant le modèle de correspondance de l'URL, en définissant le nom du filtre et l'ordre d'exécution. Ce processus n'est en fait pas différent de la configuration dans web.xml, mais le formulaire est tout simplement différent. Nous pouvons maintenant démarrer le serveur pour accéder à n'importe quelle URL:
Vous pouvez voir que la configuration ci-dessus a pris effet. En plus de configurer via FilterRegistrationBean, il existe également un moyen plus direct, qui peut être achevé directement par annotations:
@WebFilter (URLPatterns = "/ *", filterName = "logFilter2") classe publique LogCostFilter2 implémente Filter {@Override public void init (FilterConfig filterConfig) lance Servlexception {} @Override public Void Doflter (Servlequest ServletRequest, servletRespriser ServletRerespèdeResponse, filtrequest Servlequest, servletRespriser ServletReSpERSERSERSERSPONSE, FILTCHAINEST. FilterChain) lève IOException, Servlexception {long start = System.currentTimeMillis (); FilterChain.Dofilter (ServletRequest, ServletResponse); System.out.println ("LogFilter2 Exécuter Cost =" + (System.CurrentTimemillis () - START)); } @Override public void destre () {}}Ici, vous pouvez le configurer directement avec @WebFilter. De même, vous pouvez définir le mode de correspondance de l'URL, le nom du filtre, etc. Une chose à noter ici est que l'annotation @webfilter est une spécification de Servlet 3.0 et n'est pas fournie par Spring Boot. En plus de cette annotation, nous devons également ajouter une autre annotation à la classe de configuration: @ServletComponetScan, spécifiant le package numérisé.
@ SpringbootApplication @ MAPPERSCAN ("com.pandy.blog.dao") @ servletcomponentscan ("com.pandy.blog.filters") Application de classe publique {public static void main (String [] args) lance une exception {SpringApplication.Run (application.class, args); }} Maintenant, visitons à nouveau n'importe quelle URL:
Comme vous pouvez le voir, les deux filtres que nous avons configurés ont pris effet. Les lecteurs prudents constateront que nous ne spécifions pas l'ordre d'exécution du deuxième filtre, mais que nous exécutons avant le premier filtre. Il faut expliquer ici que l'annotation @webfilter ne spécifie pas l'attribut d'ordre d'exécution. Son ordre d'exécution dépend du nom du filtre et est organisé dans l'ordre inverse en fonction de l'ordre alphabétique du nom de la classe de filtre (notez qu'il n'est pas le nom du filtre configuré). La priorité du filtre spécifiée par @WebFilter est supérieure au filtre configuré par le filterRegistrationBean. Les amis intéressés peuvent expérimenter seuls.
3. Configuration d'intercepteur
Nous avons déjà introduit la méthode de configuration du filtre ci-dessus. Ensuite, jetons un coup d'œil à la configuration d'un intercepteur. Nous utilisons un intercepteur pour implémenter la même fonction ci-dessus, enregistrant le temps d'exécution de la demande. Nous mettons d'abord à la classe d'interceptor:
La classe publique LogCostInterceptor implémente HandlerInterceptor {long start = System.Currenttimemillis (); @Override Public Boolean Prehandle (httpServletRequest httpservletRequest, httpservletResponse httpservletResponse, objet o) exception {start = system.currentTimemillis (); Retour Vrai; } @Override public void posthandle (httpservletRequest httpservletRequest, httpservletResponse httpservletResponse, objet o, modelandView ModelAndView) lève exception {System.out.println ("interceptor cost =" + (system.currentTimeMillis () - start)); } @Override public void afterCompletion (httpServletRequest httpservletRequest, httpservletResponse httpservletResponse, objet o, exception e) lève une exception {}}Ici, nous devons implémenter l'interface HandlerInterceptor. Cette interface comprend trois méthodes. La pré-maintenance est exécutée avant l'exécution de la demande, et le post-standleur est exécuté après l'exécution de la demande, mais il ne sera exécuté que lorsque la méthode de pré-maintenance renvoie true. Aftercompletion est exécuté une fois le rendu de la vue terminé. Prehandle doit également retourner vrai. Cette méthode est généralement utilisée pour nettoyer les ressources et autres tâches. En plus d'implémenter l'interface ci-dessus, nous devons également le configurer:
@ConfigurationPublic Class InterceptorConfig étend webmvcconfigurerAdapter {@Override public void addInterceptors (InterceptorRegistry Registry) {registry.addinterceptor (new LogCostIterceptor ()). AddPathPatterns ("/ **"); super.addinterceptors (registre); }}Ici, nous avons hérité de webmvcconfigurerAdapter. Les amis qui ont lu les articles précédents auraient dû voir cette classe. Nous avons utilisé cette classe lors de la configuration du répertoire de ressources statique. Ici, nous avons réécrit la méthode AddInterceptors pour configurer l'intercepteur. Il y a deux éléments de configuration principaux: l'un consiste à spécifier l'intercepteur et l'autre est de spécifier l'URL d'interception. Maintenant, nous commençons le système et accédons à n'importe quelle URL:
Comme vous pouvez le voir, nous avons atteint la même fonction via l'intercepteur. Cependant, il convient de noter ici que cette implémentation est en fait problématique, car la pré-main et le post-poste sont deux méthodes, nous devons donc définir une variable partagée de démarrage pour stocker la valeur de démarrage, mais cela aura des problèmes de sécurité du fil. Bien sûr, nous pouvons résoudre ce problème grâce à d'autres méthodes, telles que Threadlocal, qui peuvent être bien résolues, et les étudiants intéressés peuvent le mettre en œuvre eux-mêmes. Cependant, à travers cela, nous pouvons réellement voir que bien que les intercepteurs soient meilleurs que les filtres dans de nombreux scénarios, dans ce scénario, les filtres sont plus simples à mettre en œuvre que les intercepteurs.
4. Résumé
Cet article explique principalement la configuration des filtres et des intercepteurs basés sur le démarrage de Spring. Les filtres et les intercepteurs appartiennent à la mise en œuvre spécifique de l'idée AOP (programmation axée sur la section). En plus de ces deux implémentations, nous avons également vu une autre technologie de mise en œuvre AOP plus flexible, à savoir l'aspect, où nous pouvons remplir des fonctions de plus en plus puissantes à travers l'aspect. Je partagerai cela avec vous plus tard.