Estou aprendendo o Spring Framework, que está sendo usado no meu projeto. Encontrei a entrada ContextLoaderListener no meu arquivo web.xml . Mas não conseguiu descobrir exatamente como isso ajuda um desenvolvedor?
Na documentação oficial do ContextLoaderListener, ele diz que é para iniciar o WebApplicationContext . Em relação ao WebApplicationContext JavaDocs, diga:
Interface para fornecer configuração para um aplicativo Web.
Mas não consigo entender o que estou conseguindo com o ContextLoaderListener que inicializa internamente o WebApplicationContext ?
Pelo meu entendimento , ContextLoaderListener lê o arquivo de configuração do Spring (com o valor fornecido contra contextConfigLocation em web.xml ), analisa e carrega o bean singleton definido nesse arquivo de configuração. Da mesma forma, quando queremos carregar o protótipo de bean , usaremos o mesmo contexto de aplicativo da web para carregá-lo. Portanto, inicializamos o aplicativo da web com o ContextLoaderListener para ler / analisar / validar o arquivo de configuração antecipadamente e sempre que quisermos injetar dependência, podemos fazê-lo imediatamente sem demora. Esse entendimento está correto?
fonte
Respostas:
Sua compreensão está correta. O
ApplicationContext
é o lugar onde seus feijões Spring Live. O objetivo doContextLoaderListener
é duplo:amarrar o ciclo de vida do
ApplicationContext
ao ciclo de vida doServletContext
epara automatizar a criação do
ApplicationContext
, para que você não precise escrever código explícito para criá-lo - é uma função de conveniência.Outra coisa conveniente sobre o
ContextLoaderListener
é que ele cria umWebApplicationContext
eWebApplicationContext
fornece acesso aoServletContext
viaServletContextAware
beans e aogetServletContext
método.fonte
WebApplicationContext
. Caso contrário, ele precisaria ser criado manualmente.ContextLoaderListener
implementar um método destroy para destruir todos os grãos quando os fecha contêiner web para baixo?contextDestroyed
é chamado. Veja os documentos da API.web.xml
. No meu arquivo xml, existem dois ouvintesContextLoaderListener
eDispatcherServlet
. Então, eu acho que não há necessidade de ambos, é seguro remover oContextLoaderListener
motivo pelo qual estou perguntando porque o aplicativo está ativo desde 7 a 8 meses. web.xml está aqui para sua referência.ContextLoaderListener
é opcional . Apenas para fazer um ponto aqui: você pode inicializar um aplicativo Spring sem nunca configurarContextLoaderListener
, apenas um mínimo básicoweb.xml
comDispatcherServlet
.Aqui está o que seria:
web.xml
Crie um arquivo chamado
dispatcher-servlet.xml
e armazene-o emWEB-INF
. Como mencionamosindex.jsp
na lista de boas-vindas, adicione este arquivo emWEB-INF
.dispatcher-servlet.xml
No
dispatcher-servlet.xml
defina seus beans:fonte
Para um aplicativo Spring simples, você não precisa definir
ContextLoaderListener
no seuweb.xml
; você pode simplesmente colocar todos os seus arquivos de configuração do Spring em<servlet>
:Para um aplicativo Spring mais complexo, em que você tenha várias definições
DispatcherServlet
definidas, é possível ter os arquivos de configuração comuns do Spring que são compartilhados por todos osDispatcherServlet
definidos emContextLoaderListener
:Lembre-se de que
ContextLoaderListener
executa o trabalho de inicialização real para o contexto do aplicativo raiz .Achei que este artigo ajuda bastante: Spring MVC - Contexto do Aplicativo x Contexto do Aplicativo da Web
fonte
O blog " Objetivo do ContextLoaderListener - Spring MVC " fornece uma explicação muito boa.
Segundo ele, os contextos de aplicativos são hierárquicos e, portanto, o contexto de DispatcherSerlvet se torna filho do contexto de ContextLoaderListener. Por esse motivo, a tecnologia usada na camada do controlador (Struts ou Spring MVC) pode ser independente do contexto raiz criado ContextLoaderListener.
fonte
Quando você deseja colocar seu arquivo Servlet em seu local personalizado ou com um nome personalizado, em vez da convenção de nomenclatura padrão
[servletname]-servlet.xml
e do caminhoWeb-INF/
, é possível usarContextLoaderListener
.fonte
ContextLoaderListner é um ouvinte de Servlet que carrega todos os diferentes arquivos de configuração (configuração da camada de serviço, configuração da camada de persistência, etc.) no contexto de aplicativo de mola única.
Isso ajuda a dividir as configurações de primavera em vários arquivos XML.
Depois que os arquivos de contexto são carregados, o Spring cria um objeto WebApplicationContext com base na definição do bean e o armazena no ServletContext do seu aplicativo da web.
fonte
Esse ouvinte do Bootstrap deve iniciar e desligar o WebApplicationContext raiz do Spring . Como um aplicativo da Web pode ter vários servlet de despachante e cada um com seu próprio contexto de aplicativo contendo controladores, resolvedor de exibição, mapeamentos de manipuladores, etc. contexto do aplicativo criado pelos servlets do expedidor).
O segundo uso desse ouvinte é quando você deseja usar a segurança da primavera.
fonte
Contextos raiz e filho Antes de ler mais, entenda que -
A primavera pode ter vários contextos ao mesmo tempo. Um deles será o contexto raiz e todos os outros contextos serão contextos filhos.
Todos os contextos filhos podem acessar os beans definidos no contexto raiz; mas o contrário não é verdade. O contexto raiz não pode acessar os beans de contextos filhos.
ApplicationContext:
applicationContext.xml é a configuração de contexto raiz para todos os aplicativos da web. O Spring carrega o arquivo applicationContext.xml e cria o ApplicationContext para todo o aplicativo. Haverá apenas um contexto de aplicativo por aplicativo da web. Se você não declarar explicitamente o nome do arquivo de configuração de contexto em web.xml usando o parâmetro contextConfigLocation, o Spring procurará o applicationContext.xml na pasta WEB-INF e lançará FileNotFoundException se não conseguir encontrar esse arquivo.
ContextLoaderListener Executa o trabalho de inicialização real para o contexto do aplicativo raiz. Lê um parâmetro de contexto "contextConfigLocation" e passa seu valor para a instância de contexto, analisando-o em caminhos de arquivos potencialmente múltiplos que podem ser separados por qualquer número de vírgulas e espaços, por exemplo, "WEB-INF / applicationContext1.xml, WEB-INF / applicationContext2.xml ". ContextLoaderListener é opcional. Apenas para fazer um ponto aqui: você pode inicializar um aplicativo Spring sem nunca configurar o ContextLoaderListener, apenas um web.xml mínimo básico com o DispatcherServlet.
DispatcherServlet DispatcherServlet é essencialmente um Servlet (estende HttpServlet) cujo objetivo principal é lidar com solicitações da Web recebidas que correspondem ao padrão de URL configurado. É necessário um URI de entrada e encontra a combinação certa de controlador e visualização. Portanto, é o controlador frontal.
Ao definir um DispatcherServlet na configuração de primavera, você fornece um arquivo XML com entradas de classes do controlador, exibe mapeamentos etc. usando o atributo contextConfigLocation.
WebApplicationContext Além do ApplicationContext, pode haver vários WebApplicationContext em um único aplicativo Web. Em palavras simples, cada DispatcherServlet associado a um único WebApplicationContext. O arquivo xxx-servlet.xml é específico ao DispatcherServlet e um aplicativo da Web pode ter mais de um DispatcherServlet configurado para manipular as solicitações. Em tais cenários, cada DispatcherServlet teria um xxx-servlet.xml separado configurado. Mas, applicationContext.xml será comum a todos os arquivos de configuração do servlet. Por padrão, o Spring carregará o arquivo chamado "xxx-servlet.xml" da pasta WEB-INF dos webapps, em que xxx é o nome do servlet em web.xml. Se você deseja alterar o nome desse arquivo ou alterar o local, adicione initi-param com contextConfigLocation como nome do parâmetro.
Comparação e relação entre eles:
ContextLoaderListener vs DispatcherServlet
ContextLoaderListener cria o contexto do aplicativo raiz. As entradas DispatcherServlet criam um contexto de aplicativo filho por entrada de servlet. Contextos filhos podem acessar beans definidos no contexto raiz. Os beans no contexto raiz não podem acessar os beans nos contextos filhos (diretamente). Todos os contextos são adicionados ao ServletContext. Você pode acessar o contexto raiz usando a classe WebApplicationContextUtils.
Depois de ler a documentação do Spring, a seguir está o entendimento:
a) Os contextos de aplicativos são hierárquicos e o WebApplicationContexts. Consulte a documentação aqui.
b) ContextLoaderListener cria um contexto de aplicativo da Web raiz para o aplicativo da Web e o coloca no ServletContext. Esse contexto pode ser usado para carregar e descarregar os beans gerenciados por mola, respectivamente, de qual tecnologia está sendo usada na camada do controlador (Struts ou Spring MVC).
c) DispatcherServlet cria seu próprio WebApplicationContext e os manipuladores / controladores / resolvedores de exibição são gerenciados por esse contexto.
d) Quando ContextLoaderListener é usado em conjunto com DispatcherServlet, um contexto de aplicativo da web raiz é criado primeiro como dito anteriormente e um contexto filho também é criado pelo DispatcherSerlvet e é anexado ao contexto do aplicativo raiz. Consulte a documentação aqui.
Quando trabalhamos com o Spring MVC e também usamos o Spring na camada de serviços, fornecemos dois contextos de aplicativos. O primeiro é configurado usando ContextLoaderListener e o outro com DispatcherServlet
Geralmente, você definirá todos os beans relacionados ao MVC (controlador e visualizações etc.) no contexto DispatcherServlet e todos os beans transversais, como segurança, transação, serviços etc. no contexto raiz por ContextLoaderListener.
Consulte isso para obter mais detalhes: https://siddharthnawani.blogspot.com/2019/10/contextloaderlistener-vs.html
fonte
Basicamente, você pode isolar o contexto do aplicativo raiz e o contexto do aplicativo Web usando ContextLoaderListner.
O arquivo de configuração mapeado com o parâmetro context se comportará como configuração de contexto do aplicativo raiz. E o arquivo de configuração mapeado com o servlet do dispatcher se comportará como o contexto do aplicativo da web.
Em qualquer aplicativo da Web, podemos ter vários servlets do dispatcher, portanto, múltiplos contextos de aplicativos da Web.
Porém, em qualquer aplicativo Web, podemos ter apenas um contexto de aplicativo raiz compartilhado com todos os contextos de aplicativo Web.
Devemos definir nossos serviços, entidades, aspectos etc. comuns no contexto do aplicativo raiz. E controladores, interceptadores etc. estão no contexto relevante de aplicativos da web.
Uma amostra web.xml é
Aqui, a classe de configuração example.config.AppConfig pode ser usada para configurar serviços, entidades, aspectos etc. no contexto do aplicativo raiz que serão compartilhados com todos os outros contextos de aplicativos da Web (por exemplo, aqui temos duas classes de configuração do contexto de aplicativos da Web RestConfig e WebConfig)
PS: Aqui o ContextLoaderListener é completamente opcional. Se não mencionarmos ContextLoaderListener no web.xml aqui, o AppConfig não funcionará. Nesse caso, precisamos configurar todos os nossos serviços e entidades no WebConfig e Rest Config.
fonte
Isso dará a você um ponto de conexão para colocar algum código que você deseja executar no tempo de implantação de aplicativos da web
fonte
Classe ouvinte - ouve um evento (por exemplo, inicialização / desligamento do servidor)
ContextLoaderListener -
Os arquivos de configuração podem ser fornecidos assim em web.xml
fonte
No contexto da estrutura de primavera, o objetivo do ContextLoaderListener é carregar os outros beans em seu aplicativo, como os componentes da camada intermediária e da camada de dados que conduzem o backend do aplicativo.
fonte
Sua compreensão está correta. Gostaria de saber por que você não vê nenhuma vantagem no ContextLoaderListener. Por exemplo, você precisa criar uma fábrica de sessões (para gerenciar o banco de dados). Esta operação pode demorar algum tempo, por isso é melhor fazê-lo na inicialização. Claro que você pode fazer isso com servlets init ou qualquer outra coisa, mas a vantagem da abordagem do Spring é que você faz a configuração sem escrever código.
fonte
Se escrevermos web.xml sem ContextLoaderListener, não poderemos fornecer a documentação usando customAuthenticationProvider na segurança da primavera. Como DispatcherServelet é o contexto filho de ContextLoaderListener, customAuthenticationProvider é a parte de parentContext que é ContextLoaderListener. Portanto, o Contexto pai não pode ter as dependências do contexto filho. Portanto, é uma prática recomendada escrever spring-context.xml no contextparam em vez de gravá-lo no initparam.
fonte
Eu acredito que seu uso real ocorre quando você deseja ter mais de um arquivo de configuração ou você tem o arquivo xyz.xml em vez de applicationcontext.xml, por exemplo
<context-param><param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/training-service.xml, /WEB-INF/training-data.xml</param-value> </context-param>
Outra abordagem para ContextLoaderListener está usando ContextLoaderServlet como abaixo
<servlet> <servlet-name>context</servlet-name> <servlet-class>org.springframework.web.context.ContextLoaderServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet>
fonte