Introdução: Uma dependência circular é uma referência aninhada em loop nas classes N. Se essa dependência circular ocorrer no desenvolvimento diário usando o novo método de objeto, o programa continuará chamando -o de loop em tempo de execução até que a memória transborda e relate um erro. Vamos falar sobre a primavera se resolver dependências circulares.
O primeiro tipo: dependência cíclica do parâmetro construtor
O contêiner de mola colocará cada identificador de feijão que está sendo criado em um "pool de feijão atual" e o identificador de feijão permanecerá nesse pool durante o processo de criação. Portanto, se você achar que já está no "pool de feijão atual" durante o processo de criação, ele será jogado.
A exceção do BeanCurrentlyinCreationException indica uma dependência circular; O feijão criado será liberado do "pool de feijão atualmente criado".
Primeiro, inicializamos três feijões.
Classe pública estudante {private StudentB StudentB; public void setStudentB (StudentB StudentB) {this.studentb = studentB; } public studentA () {} public StudentA (StudentB StudentB) {this.studentb = StudentB; }} Classe pública StudentB {private Studentc Studentc; public void setStudentc (Studentc studentc) {this.studentc = studentc; } public studentB () {} public studentb (Studentc studentc) {this.studentc = studentc; }} Public Class Studentc {Private Studentra StudentA; public void SetStudenta (StudentA studentA) {this.studenta = studesa; } public studentc () {} public studentc (StudentA StudentA) {this.studenta = studentA; }}Ok, os acima são três classes muito básicas. A estrutura de parâmetros do StudentA é StudentB. A estrutura de parâmetros do StudentB é o Studentc, e a estrutura de parâmetros do Studentc é o StudentA, que cria uma situação de dependência circular.
Todos nós entregamos esses três feijões ao gerenciamento da primavera e os instantamos com construções de parâmetros
<bean id = "a"> <construtor-arg index = "0" ref = "b"> </construtor-arg> </bean> <bean id = "b"> <construtor-arg index = "0" ref = "C"> <Construtor-s </construtor-arg> </bean> <Bean = "c"> </ Bean>
Aqui está a aula de teste:
classe pública teste {public static void main (string [] args) {ApplicationContext context = new ClassPathXMLApplicationContext ("com/zfx/student/ApplicationContext.xml"); //System.out.println(context.getbean("a ", studentra.class)); }}A mensagem de erro do resultado da execução é:
Causado por: org.springframework.beans.factory.beanCurrentlyIncreationException:
Erro a criação de bean com o nome 'A': o feijão solicitado está atualmente em criação: existe uma referência circular não resolvida?
Se você entender a frase no início, não deve se surpreender ao relatar esse erro. O contêiner da primavera cria primeiro um estudante de singleton. Estudante depende do StudentB e depois coloca um na "piscina atual do feijão". Neste momento, o StudentB é criado, o StudentB depende do Studentc e B é colocado no "Pool de feijão atual". Neste momento, o StudentC é criado, o StudentC depende do StudentA. No entanto, neste momento, o aluno já está no pool, então um erro será relatado. Como todos os feijões na piscina não foram inicializados, eles dependerão de erros. (O feijão inicializado será removido da piscina)
O segundo tipo: Método Setter Singleton, método padrão
Se você quiser falar sobre injeção de setter, é melhor olhar para uma foto de feijões instantantes na primavera
Conforme mostrado nas duas primeiras etapas da figura, a mola instancia o objeto Bean e depois define as propriedades do objeto.
Modifique o arquivo de configuração para injetá -lo no modo de conjunto:
<!-scope = "singleton" (o padrão é o método singleton)-> <bean id = "a" scope = "singleton"> <propriedade name = "studentb" ref = "b"> </property> </bean> <bean id = "b" scope = "singleton"> <nome da propriedade "benc" ref = "c" c "> Scope = "Singleton"> <Nome da propriedade = "Studesa" Ref = "A"> </sition> </i bean>
Aqui está a aula de teste:
classe pública teste {public static void main (string [] args) {ApplicationContext context = new ClassPathXMLApplicationContext ("com/zfx/student/ApplicationContext.xml"); System.out.println (context.getBean ("A", StudentA.class)); }}O resultado da impressão é:
com.zfx.student.studenta@1fbfd6
Por que você não relata um erro usando o método definido?
Vejamos a foto acima. A primavera primeiro instancia o objeto Bean usando construções. No momento, a primavera colocará o objeto instanciado em um mapa e a Spring fornece um método para obter a referência de objeto instanciado com o atributo Unset. Com base em nosso exemplo, quando a primavera instanta a Studes, StudentB e Studentc, ele definirá as propriedades do objeto. Neste momento, o StudentA confiará no StudentB e eliminará o objeto Singleton StudentB no mapa e assim por diante, não haverá problema de loop.
A seguir, é apresentado o método de implementação no código -fonte da primavera. O seguinte código -fonte está na classe Padrão de Legalão
/ ** Cache dos objetos de singleton: Nome do feijão -> Instância do feijão (coleção de mapa que armazenam os objetos instantados de singleton)*/ mapa final privado <string, objeto> singletonObjects = new concursonthashmap <string, objeto> (64); / ** Cache de fábricas de singleton: nome do feijão -> ObjectFactory (coleção de cache do feijão de fábrica de singleton)*/ mapa final privado <string, objectFactory> singletonFactory = new Hashmap <string, objectFactory> (16); / ** Cache dos primeiros objetos de singleton: Nome do feijão -> Instância do feijão*/ mapa final privado <string, object> EarnSingletonObjects = new Hashmap <string, objeto> (16); / ** Conjunto de singletons registrados, contendo os nomes do feijão na ordem de registro*/ conjunto final privado <string> registradoSingLetons = new LinkedHashSet <String> (64); /*** Adicione uma instância singleton* Resolva o problema das referências circulares* Adicione a fábrica singleton dada para criar o singleton especificado*, se necessário. * <p> a ser chamado por um registro ansioso de singletons, por exemplo, para poder * resolver referências circulares. * @param beanname O nome do feijão * @param singletonfactory A fábrica para o objeto singleton */ vazio protegido AddsingletonFactory (string beanname, objectFactory SingletonFactory) {Assert.NotNull (SingletonFactory, "Singleton Factory não deve ser Null"); sincronizado (this.singletonObjects) {if (! this.singletonObjects.containsKey (beanname)) {this.singletonfactories.put (beanname, singletonfactory); this.earlysingletonObjects.remove (beanname); this.RegisterDSingLetons.add (Beanname); }}O terceiro tipo: protótipo de setter, protótipo
Modifique o arquivo de configuração para:
<bean id = "a" <span style = "cor:#ff0000;"> scope = "prototype" </span>> <propriedades name = "studentb" ref = "b"> </propriedade> </bean> <bean id = "b" <span style = "color:#ff0000;"> scope = "protótipo" </span "> <bean id = "c" <span style = "cor:#ff0000;"> scope = "prototype" </span>> <propriedade name = "studentc" ref = "c"> </propriedade> </bean> <bean id = "c" <span style = "color:#ff0000;"> scope = "protótipo" </span>
scope = "protótipo" significa que um objeto de instância é criado sempre que você solicitar. A diferença entre os dois é: os feijões estabelecidos usam o escopo do protótipo, enquanto o sem estado de estado geralmente usa o escopo Singleton Singleton.
Casos de teste:
classe pública teste {public static void main (string [] args) {ApplicationContext context = new ClassPathXMLApplicationContext ("com/zfx/student/ApplicationContext.xml"); <strong> // No momento, você deve obter uma instância do Spring gerenciado, porque agora Scope = "Prototype" apenas instanciará o objeto ao solicitar para obter </strong> System.out.println (context.getBean ("A", Studesa.class)); }} Resultado de impressão:
Causado por: org.springframework.beans.factory.beanCurrentlyIncreationException: Erro a criação de bean com o nome 'a': o feijão solicitado está atualmente em criação: existe uma referência circular não resolvida?
Por que o modelo de protótipo está errado?
Para feijões com escopo "protótipo", o recipiente de mola não pode concluir a injeção de dependência porque o recipiente de mola não cache os grãos no feijão escopo "protótipo", para que um feijão criado não possa ser exposto com antecedência.
O exposto acima é todo o conteúdo deste artigo. Espero que seja útil para o aprendizado de todos e espero que todos apoiem mais o wulin.com.