Estou estudando para a certificação Spring Core e tenho algumas dúvidas sobre como o Spring lida com o ciclo de vida dos beans e, em particular, sobre o pós-processador do bean .
Então, eu tenho este esquema:
É muito claro para mim o que significa:
As etapas a seguir ocorrem na fase de Definições do bean de carregamento :
As classes @Configuration são processadas e / ou @Components são verificados e / ou arquivos XML são analisados.
Definições de bean adicionadas ao BeanFactory (cada um indexado sob seu id)
Beans BeanFactoryPostProcessor especiais chamados, ele pode modificar a definição de qualquer bean (por exemplo, para as substituições de valores de placeholder de propriedade).
Em seguida, as seguintes etapas ocorrem na fase de criação de feijão :
Cada bean é instanciado avidamente por padrão (criado na ordem correta com suas dependências injetadas).
Após a injeção de dependência, cada bean passa por uma fase de pós-processamento em que configuração e inicialização adicionais podem ocorrer.
Após o pós-processamento, o bean é totalmente inicializado e pronto para uso (rastreado por seu id até que o contexto seja destruído)
Ok, isso está muito claro para mim e também sei que existem dois tipos de pós-processadores de feijão :
Inicializadores: inicializam o bean se instruído (isto é, @PostConstruct).
e Todo o resto: que permite configuração adicional e que pode ser executado antes ou depois da etapa de inicialização
E eu posto este slide:
Portanto, está muito claro para mim o que os inicializadores bean post processors (eles são os métodos anotados com a anotação @PostContruct e que são chamados automaticamente imediatamente após os métodos setter (após a injeção de dependência), e eu sei que posso usar para execute algum lote de inicialização (como preencher um cache como no exemplo anterior).
Mas o que exatamente representa o outro pós-processador de bean? O que queremos dizer quando afirmamos que essas etapas são realizadas antes ou depois da fase de inicialização ?
Portanto, meus beans são instanciados e suas dependências são injetadas, então a fase de inicialização é concluída (pela execução de um método anotado @PostContruct ). O que queremos dizer ao dizer que um Bean Post Processor é usado antes da fase de inicialização? Isso significa que isso acontece antes da execução do método anotado @PostContruct ? Isso significa que pode acontecer antes da injeção de dependência (antes que os métodos setter sejam chamados)?
E o que exatamente queremos dizer quando dizemos que é executado após a etapa de inicialização . Significa que depois disso ocorre a execução de um método anotado @PostContruct , ou o quê?
Posso imaginar facilmente por que preciso de um método anotado @PostContruct , mas não consigo imaginar algum exemplo típico do outro tipo de pós-processador de bean. Você pode me mostrar algum exemplo típico de quando são usados?
fonte
Respostas:
Spring doc explica os BPPs em Customizando Beans usando BeanPostProcessor . Os beans BPP são um tipo especial de beans que são criados antes de quaisquer outros beans e interagem com os beans recém-criados. Com essa construção, o Spring oferece meios para conectar e personalizar o comportamento do ciclo de vida simplesmente implementando um
BeanPostProcessor
você mesmo.Ter um BPP personalizado como
seria chamado e imprimiria a classe e o nome do bean para cada bean criado.
Para entender como o método se encaixa no ciclo de vida do bean, e quando exatamente o método é chamado, verifique os documentos
O importante também é que
No que diz respeito à relação com a
@PostConstruct
nota, essa anotação é uma maneira conveniente de declarar umpostProcessAfterInitialization
método, e o Spring toma conhecimento disso quando você registraCommonAnnotationBeanPostProcessor
ou especifica o<context:annotation-config />
arquivo de configuração do bean. Se o@PostConstruct
método será executado antes ou depois de qualquer outropostProcessAfterInitialization
depende daorder
propriedadefonte
O exemplo típico de um pós-processador de bean é quando você deseja envolver o bean original em uma instância de proxy, por exemplo, ao usar a
@Transactional
anotação.O pós-processador do bean receberá a instância original do bean, ele pode chamar quaisquer métodos no destino, mas também consegue retornar a instância do bean real que deve ser ligada no contexto do aplicativo, o que significa que pode realmente retornar qualquer objeto que deseja. O cenário típico quando isso é útil é quando o pós-processador do bean envolve o destino em uma instância de proxy. Todas as invocações no bean vinculado ao contexto do aplicativo passarão pelo proxy, e o proxy então executa alguma mágica antes e / ou depois das invocações no bean de destino, por exemplo, AOP ou gerenciamento de transação.
fonte
A diferença é que
BeanPostProcessor
se conectará à inicialização do contextopostProcessBeforeInitialization
e,postProcessAfterInitialization
em seguida, chamará e para todos os beans definidos.Mas
@PostConstruct
é usado apenas para a classe específica que você deseja personalizar a criação do bean após o construtor ou método de definição.fonte