Dúvida sobre o ciclo de vida do Model no Spring

Olá pessoal, estou com a seguinte dúvida.

Tenho uma view que mostrar os dados da minha tabela Contato mapeado na url /buscarContatos.

A requisição é feita para /buscarContatos, o controle recebe a lista do repository, adiciona
a lista no modelAndView e redireciona para a mesma view mostrarContatos.

@GetMapping("/buscarContatos")
    public ModelAndView mostrarContatos(){

        List<Contato> lista = contatoRepositorio.findAll();
        ModelAndView modelAndView = new ModelAndView("mostrarContatos");
        modelAndView.addObject("lista",lista);
        return modelAndView;
    }

Nesta view mostrarContatos, cada contato tem um link para excluir o contato.

	<div th:each="contato : ${lista}">
           <label th:text="${contato.id}"></label>
           <label th:text="${contato.nome}"></label>
           <label th:text="${contato.telefone}"></label>
           <a th:href="@{/excluirContato(id=${contato.id})}">Excluir</a>
	</div>

Clicando neste link, é feita uma requisição para a url /excluirContato que recebe
o id do contato e o repository deleta. O usuário é redirecionado para a mesma tela|
mostrarContatos.

@GetMapping("/excluirContato")
    public ModelAndView excluirContato(@RequestParam Long id){

        contatoRepositorio.deleteById(id);
        ModelAndView modelAndView = new ModelAndView("mostrarContatos");
        return modelAndView;

    }

Quando a view mostrarContatos é visualizada, ela aparece em branco, pois a lista não está
presente no model em view. Para corrigir isso, eu teria que invocar o repo para buscar a lista atualizada e inserir no modelAndView novamente.

Até aqui tudo bem para mim, tudo faz sentido.

Agora neste trecho:

O usuário faz a requisição para a url /cadastrarContato e o formulário de cadastro é apresentado (view formCadastrarContato).

	<form action="/salvarContato" method="post">
           <label>Nome:</label><input type="text"  th:field="${contato.nome}">
           <label>Telefone:</label><input type="text"  th:field="${contato.telefone}">
           <label>Rua:</label><input type="text"  th:field="${contato.endereco.rua}">
           <label>Número:</label><input type="text"  th:field="${contato.endereco.numero}">
          <input type="submit" value="Salvar">
       </form>

Nesta view utilizo o atributo field do thymeleaf, por este motivo crio uma instância de contato
e adiciono ao modelAndView, como no código abaixo:

@GetMapping("/cadastrarContato")
    public ModelAndView mostrarPaginaInicial(){

        ModelAndView modelAndView = new ModelAndView("formCadastrarContato");
        modelAndView.addObject("contato",new Contato());
        return modelAndView;
    }

Quando o usuário clica em salvar ele faz a requisição para /salvarContato e recebo o contato da view. O repositorio salva e redireciona o usuário para a mesma view formCadastrarContato.

    @PostMapping("/salvarContato")
    public ModelAndView salvarContato(Contato contato){

        contatoRepositorio.save(contato);
        ModelAndView modelAndView = new ModelAndView("formCadastrarContato");
        return modelAndView;
    }

Os dados são salvos, a view formCadastrarContato é apresentada inclusive com os dados que foram digitados pelo usuário.

Aqui está o ponto da minha dúvida.
Eu criei um novo modelAndView em salvarContato, ele não deveria ter perdido essa instância de contato?
No primeiro exemplo, a lista foi perdida na segunda requisição, por que com o objeto contato a instância não foi perdida?
Por que a view formCadastrarContato continuou tendo acesso ao objeto contato mesmo se uma nova requisição foi feita e um novo modelAndView foi retornado?

Desde já agradeço!!

Fiz uns testes aqui e descobri o seguinte:

O Spring “injeta” automaticamente no model os parametros do seu método.

Por isso que no método salvarContato(), apesar de vc nunca invocar modelAndView.addObject(), vc consegue acessá-lo normalmente no seu template, porque vc está recebendo seu contato pelo parametro do método.

Boa noite. Obrigado pelo retorno.
Faz todo sentido o que vc falou. Não esperava esse comportamento, pois uma nova instância do modelAndView foi criada.
Vou fazer alguns testes e aprofundar as leituras.

Grande abraço

1 curtida