web-dev-qa-db-fra.com

Commande de câblage automatique de printemps et @PostConstruct

J'ai une question sur l'ordre de câblage automatique et la logique @PostConstruct Dans Spring. Par exemple, après le code de démonstration, j'ai une classe Spring Boot principale:

@SpringBootApplication
public class Demo1Application {

    @Autowired
    BeanB beanb;

    public static void main(String[] args) {
        SpringApplication.run(Demo1Application.class, args);
    }
}

et 2 @Service Définitions:

@Service
public class BeanB {

    @Autowired
    private BeanA beana ;

    @PostConstruct
    public void init(){
        System.out.println("beanb is called");
    }

    public void printMe(){
        System.out.println("print me is called in Bean B");
    }
}

@Service
public class BeanA {

    @Autowired
    private BeanB b;

    @PostConstruct
    public void init(){
        System.out.println("bean a is called");
        b.printMe();
    }
}

et j'ai la sortie suivante:

haricot a s'appelle

m'imprimer s'appelle dans Bean B

beanb s'appelle


Ma question est la suivante: comment le câblage automatique se déroule-t-il pas à pas comme dans le cas ci-dessus?
Et comment la méthode printMe() de beanb est-elle appelée sans appeler d'abord son @PostConstruct?

25
cacert

Ci-dessous devrait être possible séquence

  1. beanb commence à être auto-câblé
  2. Lors de l'initialisation de la classe de Beanb, beana commence à se connecter automatiquement
  3. Une fois que beana est créé, le @PostConstruct C'est-à-dire init() de beana est appelé
  4. À l'intérieur de init(), System.out.println("bean a is called"); est appelée
  5. Ensuite, on appelle b.printMe();, ce qui provoque l'exécution de System.out.println("print me is called in Bean B");
  6. Avoir le beana complété le @PostConstruct C'est-à-dire que init() de beanb est appelé
  7. Ensuite, System.out.println("beanb is called"); est appelée

Idéalement, la même chose peut être mieux observée par un débogueur dans Eclipse.

Le manuel de référence Spring explique comment les dépendances circulaires sont résolues. Les fèves sont d'abord instanciées, puis injectées les unes dans les autres.

14
Mudassar

Votre réponse est correcte comme vous l'avez montré dans votre question.

Obtenir maintenant le concept de notation @Autowired. Tout @Autowired Les objets sont initialisés et chargés en mémoire juste après le chargement de la classe.

Maintenant voici votre SpringBootApplication

@SpringBootApplication
public class Demo1Application {
    @Autowired
    BeanB beanb;   // You are trying to autowire a Bean class Named BeanB.

Dans la console ci-dessus que vous avez écrite, essayez de vous connecter automatiquement et d’injecter un objet de type BeanB.

Maintenant, voici votre définition de BeanB

@Service
public class BeanB {

    @Autowired
    private BeanA beana ;

Dans BeanB class, vous essayez d’injecter l’objet de la classe BeanA qui est également défini dans votre projet de console.

Donc, dans votre Demo1Application pour injecter un objet de classe BeanB, il est nécessaire d’injecter un objet de classe BeanA. Maintenant, BeanA L'objet de classe est créé en premier.

Maintenant, si vous voyez la définition de votre classe BeanA

 @Service
public class BeanA {

    @Autowired
    private BeanB b;

    @PostConstruct   // after Creating bean init() will be execute.
    public void init(){
        System.out.println("bean a is called");
        b.printMe();
    }
}

Ainsi, après avoir injecté la méthode Object BeanA, lier avec @PostContruct annotation va être exécutée.

Donc, le flux d'exécution sera ..

System.out.println("bean a is called");
System.out.println("print me is called in Bean B");
System.out.println("beanb is called");
5
Vikrant Kashyap