Ponto de extensão 2 da mola: Análise do princípio do beanPostProcessor customizado

beanPostProcessor é uma das interfaces que eu vi mais extensões no estudo do código-fonte do spring, como: aop, transação do spring, callback do método de inicialização, que são todas extensões e implementações desta interface, exceto para o framework do spring, como Dubbo's ReferenceAnnotationBeanPostProcessor Esta classe estendida é um pós-processador, usado para analisar a anotação @Reference

O pós-processador do bean, no processo de inicialização do bean, spring definiu qual método do pós-processador é executado primeiro e qual método é executado posteriormente. Portanto, quando expandimos, devemos estar familiarizados com a posição de execução e a sequência de esses métodos. Sequência, de acordo com eles, para esclarecer em qual etapa sua empresa precisa ser expandida

Precisamos apenas implementá-lo de acordo com diferentes subclasses de beanPostProcess

Prefácio

Não importa qual classe de extensão implementamos, precisamos considerar duas questões:
1. Depois de estendermos, se colocarmos nossa classe de extensão personalizada no contêiner de primavera
2. Depois de colocá-la no contêiner, ela seguirá as etapas que imaginamos? chamar
para o primeiro ponto, podemos passar diretamente a anotação @Component, coloque o BeanPostProcessor como feijão comum na beanDefinitionMap, porque no processo de inicialização primavera, há um passo para registrar e inicializar todo o pós-processamento em separado é,
portanto, , o primeiro ponto, só precisamos lembrar, contanto que o beanPostProcessor como um bean possa ser adicionado ao beanDefinitionMap, o spring irá nos ajudar automaticamente a inicializar o pós-processador

Com relação ao segundo ponto, depois de fornecermos uma classe de implementação, como o spring aplica o beanPostProcessor que definimos ao processo de inicialização? Ele também está relacionado ao beanPostProcessor registrado mencionado acima. Após o spring inicializar todos os pós-processadores, ele colocará os pós-processadores inicializados em uma coleção, e o spring irá chamar o método do pós-processador todas as vezes. Neste momento, todos os pós-processadores elegíveis serão obtido a partir desta lista definida para filtrar

Na verdade, para o princípio do mecanismo de extensão do pós-processador na primavera, acho que se eu entender essas duas frases, vou entender tudo.

Com relação ao primeiro ponto, como colocar o pós-processador que fornecemos no recipiente do Spring, você pode consultar a nota anterior Código-fonte do Spring: Registrando o pós-processador

Registrar pós-processador

O segundo ponto:
vamos primeiro falar sobre nosso pós-processador customizado, onde ele é armazenado em
org.springframework.context.support.PostProcessorRegistrationDelegate # registerBeanPostProcessors ()
Este método é a mola para inicializar todos os pós-processadores, então após a inicialização ser concluída, há uma operação mais crítica
registerBeanPostProcessors (beanFactory, orderPostProcessors);
registerBeanPostProcessors (beanFactory, nonOrderedPostProcessors);
registerBeanPostProcessors (beanFactory, internalPostProcessors);

Essas três linhas de código chamam a mesma lógica, mas os parâmetros de entrada são diferentes. Observe a lógica de processamento específica do método

private static void registerBeanPostProcessors(
      ConfigurableListableBeanFactory beanFactory, List<BeanPostProcessor> postProcessors) {
    
    

    for (BeanPostProcessor postProcessor : postProcessors) {
    
    
      beanFactory.addBeanPostProcessor(postProcessor);
    }
  }


  @Override
  public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
    
    
    Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null");
    // Remove from old position, if any
    this.beanPostProcessors.remove(beanPostProcessor);
    // Track whether it is instantiation/destruction aware
    if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) {
    
    
      this.hasInstantiationAwareBeanPostProcessors = true;
    }
    if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) {
    
    
      this.hasDestructionAwareBeanPostProcessors = true;
    }
    // Add to end of list
    this.beanPostProcessors.add(beanPostProcessor);
  }

A coisa mais importante aqui é a última linha de código, coloque beanPostProcess na lista final privada beanPostProcessors = new CopyOnWriteArrayList <> (); nesta coleção, esta coleção está atrás do código-fonte, veremos, primeiro tenha uma impressão

Como o pós-processador personalizado entra em vigor

Vamos tomar o quinto método pós-processador org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation
como exemplo. Este método é chamado antes da injeção de propriedade para determinar se a injeção de propriedade é necessária.
1. Se este método retornar falso, significa que o bean atual não precisa ser injetado de propriedade.
2 . Portanto, se eu tiver um requisito no momento, preciso processar a classe PayOrderService. Não há necessidade de injeção de atributo nesta classe. Aqui, apenas dou um exemplo. Neste momento, posso fornecer uma classe de implementação InstantiationAwareBeanPostProcessor sozinho e, em seguida, implemente-o. No método postProcessAfterInstantiation () da classe, considera-se que se o bean atualmente inicializado for payOrderService, ele retornará falso.
3. Deve-se notar que, se estendermos a classe de implementação nós mesmos, devemos adicionar o julgamento do bean para o método de implementação. Caso contrário, todos os beans não realizarão injeção de propriedade, por quê? Porque cada bean chamará nossa própria classe de implementação quando for inicializado para determinar se injetar propriedades

Aqui está um ponto para explicar porque é o método InstantiationAwareBeanPostProcessor, porque InstantiationAwareBeanPostProcessor herda BeanPostProcessor, então esta também é uma interface de extensão do pós-processador;
para o terceiro ponto, devemos determinar se o bean deve pular a injeção de atributo por si mesmo Bean, você pode olhar o código-fonte do Spring. O método de implementação padrão basicamente retorna true, o que requer injeção de atributo.

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean

boolean continueWithPropertyPopulation = true;

if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
    
    
  for (BeanPostProcessor bp : getBeanPostProcessors()) {
    
    
    if (bp instanceof InstantiationAwareBeanPostProcessor) {
    
    
      InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
      if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
    
    
        continueWithPropertyPopulation = false;
        break;
      }
    }
  }
}

if (!continueWithPropertyPopulation) {
    
    
  return;
}

Este trecho de código é o processamento de postProcessAfterInstantiation. Pode-se ver que no código-fonte, ele primeiro determinará se o beanDefinition atual é um beanDefinition sintético e, em seguida, determinará se há uma classe de implementação de InstantiationAwareBeanPostProcessor no contêiner atual.

protected boolean hasInstantiationAwareBeanPostProcessors() {
    
    
  return this.hasInstantiationAwareBeanPostProcessors;
}

Quando hasInstantiationAwareBeanPostProcessors é atribuído? Registre o pós-processador acima no método addBeanPostProcessor aqui

Depois de julgá-los, ele irá percorrer a coleção de listas retornada por getBeanPostProcessors ()

public List<BeanPostProcessor> getBeanPostProcessors() {
    
    
	return this.beanPostProcessors;
}

Conforme mencionado anteriormente, a lista de beanPostProcessors será usada posteriormente, que está aqui.
Então, aqui está uma explicação. Como nossa classe de implementação beanPostProcess personalizada entra em vigor?
No código-fonte do Spring, toda vez que um método pós-processador é chamado, ele percorre todos os pós-processadores no contêiner e chama seus métodos pós-processador para processamento

Resumindo

Finalmente, um pequeno resumo, se quisermos estender uma classe de implementação beanPostProcess, esta classe de implementação deve implementar diferentes interfaces beanPostProcess de acordo com o que queremos fazer e, em seguida, injetar a classe de implementação no container spring por meio da anotação @Component. não há necessidade de fazer outras operações. O Spring nos ajudará a completar a chamada para o resto.
No entanto, quando estendemos, precisamos entender como nossa lógica de negócios estendida é implementada.

Acho que você gosta

Origin blog.csdn.net/CPLASF_/article/details/115079069
Recomendado
Clasificación