1. Interceptores e filtros
Antes de falar sobre a bota da primavera, vamos primeiro olhar para filtros e interceptores. Os dois são muito semelhantes em termos de funções, mas ainda há uma grande lacuna na implementação técnica específica. Antes de analisar as diferenças entre os dois, vamos primeiro entender o conceito de AOP. AOP não é uma tecnologia específica, mas uma ideia de programação. No processo de programação orientada a objetos, é fácil resolver a expansão vertical por meio de herança e polimorfismo. No entanto, para funções horizontais, como ativar transações em todos os métodos de serviço ou log unificado, funções orientadas a objetos não podem ser resolvidas. Portanto, a programação orientada à AOP é na verdade um suplemento à idéia de programação orientada a objetos. Os filtros e interceptores de que estamos falando hoje são implementações específicas da programação orientada a aspectos. As principais diferenças entre os dois incluem os seguintes aspectos:
1. O filtro depende dos recipientes de servlet e faz parte da especificação do servlet. Os interceptores existem independentemente e podem ser usados em quaisquer circunstâncias.
2. A execução do filtro é concluída pelo retorno de chamada do contêiner do servlet e o interceptador é geralmente executado através de um proxy dinâmico.
3. O ciclo de vida do filtro é gerenciado pelo recipiente do servlet, enquanto o interceptador pode ser gerenciado através de contêineres do IOC. Portanto, instâncias de outros feijões podem ser obtidas por meio de injeção e outros métodos, por isso será mais conveniente de usar.
2. Configuração do filtro
Agora, usamos filtros para perceber a função de registrar o tempo de execução das solicitações, que é implementado da seguinte maneira:
public class LogCostFilter implementa o filtro {@Override public void init (filterConfig filterConfig) lança servletexception {} @Override public void Dofilter (servletRequest servletReQuest, servletResponse servletResponse, filtro de longa data) THROWSECECCECCENCEIRA, servEntexexexexexonsexexertRestonsestonsensensensensensensexing); filterChain.dofilter (servletRequest, servletResponse); System.out.println ("Execute Cost ="+(System.CurrentTimemillis ()-Start)); } @Override public void Destroy () {}}A lógica desse código é relativamente simples, que é registrar o registro de data e hora antes do método ser executado e, em seguida, concluir a execução da solicitação através da cadeia de filtro e calcular o tempo de execução entre os resultados retornados. O principal aqui é que essa classe deve herdar a classe de filtro. Esta é a especificação do servlet, que não é diferente dos projetos da Web anteriores. No entanto, com a classe Filter, os projetos da Web anteriores podem ser configurados no web.xml, mas o projeto de inicialização da primavera não possui o arquivo web.xml, então como configurá -lo? Na inicialização da primavera, precisamos do FilterRegistrationBean para concluir a configuração. O processo de implementação é o seguinte:
@ConfigurationPublic Class filterConfig {@Bean public filterRegistrationBean registrofilter () {filterRegistrationBean registro = new filterRegistrationBean (); registro.setFilter (new LogCostFilter ()); registro.addurlpatterns ("/*"); registro.setName ("LogCostFilter"); registro.setorder (1); Registro de retorno; }}Esta configuração está concluída. As opções que precisam ser configuradas incluem principalmente instanciando a classe de filtro e, em seguida, especificando o padrão de correspondência da URL, definindo o nome do filtro e a ordem de execução. Na verdade, esse processo não é diferente da configuração no web.xml, mas o formulário é apenas diferente. Agora podemos iniciar o servidor para acessar qualquer URL:
Você pode ver que a configuração acima entrou em vigor. Além de configurar o FilterRegistrationBean, também há uma maneira mais direta, que pode ser concluída diretamente através de anotações:
@Webfilter (urlpatterns = "/*", filterame = "logFilter2") public class LogCostFilter2 implementa o filtro {@Override public void init (filterConfig filterConfig) lança servletexcept {} @override public void dofilter (servleTleTleTreLeTReTreLeTRexcept {} @Override public void dofilter (servleTleTleTrelTreLeTReTreLeTRexcept {} @Override Ioexception, servletexception {long start = system.currenttimemillis (); filterChain.dofilter (servletRequest, servletResponse); System.out.println ("LogFilter2 Execute Cost =" + (System.currenttimemillis () - Start)); } @Override public void Destroy () {}}Aqui você pode configurá -lo diretamente com @webfilter. Da mesma forma, você pode definir o modo de correspondência de URL, nome de filtro, etc. Uma coisa a observar aqui é que a anotação @webfilter é uma especificação do servlet 3.0 e não é fornecida pela Spring Boot. Além desta anotação, também precisamos adicionar outra anotação à classe de configuração: @ServletComPonetScan, especificando o pacote digitalizado.
@SpringbootApplication@mapperscan ("com.pandy.blog.dao")@servletComponentscan ("com.pandy.blog.filters") public class Application {public static void main (string [] args) lança exceção {springApplication.run (aplicação.class, args); }} Agora, vamos visitar qualquer URL novamente:
Como você pode ver, os dois filtros que configuramos entraram em vigor. Os leitores cuidadosos descobrirão que não especificamos a ordem de execução do segundo filtro, mas executamos antes do primeiro filtro. Deve -se explicar aqui que a anotação @Webfilter não especifica o atributo da ordem de execução. Sua ordem de execução depende do nome do filtro e é organizada em ordem inversa com base na ordem alfabética do nome da classe do filtro (observe que não é o nome do filtro configurado). A prioridade do filtro especificada pelo @Webfilter é maior que o filtro configurado pelo filtroRegistrationBean. Amigos interessados podem experimentar por conta própria.
3. Configuração do interceptador
Já introduzimos o método de configuração do filtro acima. Em seguida, vamos dar uma olhada em como configurar um interceptador. Usamos um interceptador para implementar a mesma função acima, registrando o tempo de execução da solicitação. Primeiro, implementamos a classe interceptadora:
public class LogCostIntercept implementa HandlerInterCorpt {Long start = System.currenttimemillis (); @Override public boolean prehandle (httpServletRequest httpServletRequest, httpServletResponse httpServletResponse, objeto o) lança exceção {start = system.currenttimemillis (); retornar true; } @Override public void PostHandle (httpServletRequest httpServletRequest, httpServletResponse httpServletResponse, objeto o, modelandview ModelAndView) lança exceção {System.out.println (interceptor Cost = "+(System.curntEntEntEnmilis () () (interceptor) (System) (System) (System). } @Override public void Aftercompletion (httpServletRequest httpServletRequest, httpServletResponse httpServletResponse, objeto o, exceção e) lança exceção {}}Aqui precisamos implementar a interface HandlerInterceptor. Esta interface inclui três métodos. O pré -manuse é executado antes da execução da solicitação e o pós -pó é executado após a execução ser executada, mas ela será executada apenas quando o método de pré -manuse retornar true. O pós -conclusão é executado após a conclusão da renderização da exibição. Prehandle também precisa retornar verdadeiro. Esse método é geralmente usado para limpeza de recursos e outras tarefas. Além de implementar a interface acima, também precisamos configurá -la:
@ConfigurationPublic Class InterceptConfig estende o webmvcConfigureRAdApter {@Override public void AddInterceptores (InterceptorRegistry Registry) {Registry.addintercept (new LogCostInterceptor ()). AddPathatterns ("/**"); super.addinterceptores (Registro); }}Aqui, herdamos o webmvcConfigureRAdapter. Amigos que leram os artigos anteriores deveriam ter visto essa aula. Usamos essa classe ao configurar o diretório de recursos estáticos. Aqui, reescrevemos o método AddIntercepts para configurar o interceptador. Existem dois itens principais de configuração: um é especificar o interceptador e o outro é especificar o URL interceptador. Agora iniciamos o sistema e acessamos qualquer URL:
Como você pode ver, alcançamos a mesma função através do interceptador. No entanto, deve -se notar aqui que essa implementação é realmente problemática, porque o Prehandle e o PostHandle são dois métodos; portanto, precisamos definir uma variável compartilhada iniciar para armazenar o valor inicial, mas isso terá problemas de segurança de threads. Obviamente, podemos resolver esse problema por meio de outros métodos, como o Threadlocal, que podem ser bem resolvidos, e os alunos interessados podem implementá -lo. No entanto, com isso, podemos realmente ver que, embora os interceptores sejam melhores que os filtros em muitos cenários, nesse cenário, os filtros são mais simples de implementar do que os interceptores.
4. Resumo
Este artigo explica principalmente a configuração de filtros e interceptores com base na inicialização da mola. Tanto os filtros quanto os interceptores pertencem à implementação específica da idéia de AOP (programação orientada para a seção). Além dessas duas implementações, também vimos outra tecnologia de implementação de AOP mais flexível, como aspecto, onde podemos completar cada vez mais funções poderosas através do aspecto. Vou compartilhar isso com você mais tarde.