Prefácio
Este artigo apresenta principalmente o conteúdo relevante sobre a pesquisa (injeção de método) na primavera. É compartilhado para sua referência e aprendizado. Não vou dizer muito abaixo. Vamos dar uma olhada na introdução detalhada juntos:
Isso pode acontecer ao usar a primavera: um feijão de singleton depende de outro feijão que não seja de Singleton. Se você simplesmente usar a montagem automática para injetar dependências, alguns problemas podem surgir, como mostrado abaixo:
Classe A para Singleton
@ComponentPublic Classe Classa {@AUTOWIRED Classb private ClassB; public void printClass () {System.out.println ("Esta é a classe A:" + this); Classb.printClass (); }}Classe B para não-solucionar
@Componente@scope (value = scope_prototype) public classB {public void printClass () {System.out.println ("Esta é a classe B:" + this); }} Aqui, a classe A adota o escopo padrão de singleton e depende da classe B. O escopo da classe B é o protótipo, por isso não é um singleton. Neste momento, você pode ver o problema de escrever assim depois de executar um teste:
@Runwith (springrunner.class) @ContextConfiguration (classes = {Classa.class, classb.class}) classe public mytest {@autowired private Classa Classa; @Test public void simletest () {for (int i = 0; i <3; i ++) {Classa.printClass (); }}}O resultado da saída é:
Esta é a Classe A: Classa@282003E1
Esta é a classe B: Classb@7fad8c79
Esta é a Classe A: Classa@282003E1
Esta é a classe B: Classb@7fad8c79
Esta é a Classe A: Classa@282003E1
Esta é a classe B: Classb@7fad8c79
Como você pode ver, o código de hash de ambas as classes é o mesmo nas três saídas. É compreensível que o valor da classe A permaneça inalterado porque é um singleton, mas o escopo da classe B é um protótipo, mas também mantém o código de hash inalterado, que parece ter se tornado um singleton?
A razão para essa situação é que o escopo da classe A é o singleton padrão, portanto o contexto só criará o feijão da classe A uma vez, então há apenas uma chance de injetar dependências e o contêiner não pode fornecer a Classe A uma nova classe B sempre.
Solução não tão boa
Para resolver o problema acima, você pode fazer algumas modificações na Classe A para implementar o ApplicationContexTAWee.
@ComPonenPublic Classe Classlemmm a ApplicationContextAWe {private ApplicationContext ApplicationContext; public void printClass () {System.out.println ("Esta é a classe A:" + this); getClassB (). printClass (); } public ClassB getClassB () {return ApplicationContext.getBean (classb.class); } public void setApplicationContext (ApplicationContext ApplicationContext) lança beansexception {this.ApplicationContext = ApplicationContext; }}Dessa forma, você pode encontrar manualmente um novo feijão no contexto toda vez que precisar ir para a classe B. Depois de executar outro teste, obtive a seguinte saída:
Esta é a classe A: com.devhao.classa@4df828d7
Esta é a classe B: com.devhao.classb@31206beb
Esta é a classe A: com.devhao.classa@4df828d7
Esta é a classe B: com.devhao.classb@3e77a1ed
Esta é a classe A: com.devhao.classa@4df828d7
Esta é a classe B: com.devhao.classb@3ffcd140
Você pode ver que o código de hash da classe A permanece inalterado nas três saídas, enquanto a classe B é diferente toda vez, o que mostra que o problema foi resolvido e a nova instância é usada toda vez que for chamada.
No entanto, este método de escrita é fortemente acoplado à primavera e a primavera fornece outra maneira de reduzir a invasividade.
@Lookup
A primavera fornece uma anotação chamada @lookup, que é uma anotação que funciona no método. O método marcado por ele será substituído. Então, de acordo com o tipo de seu valor de retorno, o contêiner chama o método getBean () do Beanfactory para retornar um feijão.
@ComPonentPublic Class Classa {public void printClass () {System.out.println ("Esta é a classe A:" + this); getClassB (). printClass (); } @Lookup public ClassB getClassB () {return null; }} Pode -se descobrir que é muito mais simples e não é mais fortemente acoplado à primavera. A execução do teste novamente ainda pode obter a saída correta.
O valor de retorno do método anotado não é mais importante, porque o contêiner gerará dinamicamente uma subclasse e reescreve/implementará o método anotado, e o método da subclasse é finalmente chamado.
O método @lookup usado deve cumprir a seguinte assinatura:
<public | Protected> [Resumo] <Tort-Type> temethodName (sem argumentos);
Resumir
O acima é o conteúdo inteiro deste artigo. Espero que o conteúdo deste artigo tenha certo valor de referência para o estudo ou trabalho de todos. Se você tiver alguma dúvida, pode deixar uma mensagem para se comunicar. Obrigado pelo seu apoio ao wulin.com.