web-dev-qa-db-fra.com

Méthode Init dans Spring Controller (version d'annotation)

Je convertis un contrôleur vers la nouvelle version d'annotation. Dans l'ancienne version, j'avais l'habitude de spécifier la méthode init dans springmvc-servlet.xml en utilisant:

<beans>
    <bean id="myBean" class="..." init-method="init"/>
</beans>

Comment puis-je spécifier la méthode init en utilisant la version d'annotation?

103
Krt_Malta

Vous pouvez utiliser

@PostConstruct
public void init() {
   // ...
}
225
Johan Sjöberg

Vous pouvez également demander à votre classe d'implémenter l'interface InitializingBean afin de fournir une fonction de rappel (afterPropertiesSet()) que le champ ApplicationContext appellera lors de la construction du bean.

20
matt b

Il existe plusieurs manières d’intercepter le processus d’initialisation au printemps. Si vous devez initialiser tous les haricots et les transférer automatiquement/les injecter, il y a au moins deux façons dont je sais que cela assurera cela. Je n’ai fait que tester le second mais je crois que les deux fonctionnent de la même manière.

Si vous utilisez @Bean, vous pouvez référencer par initMethod, comme ceci.

@Configuration
public class BeanConfiguration {

  @Bean(initMethod="init")
  public BeanA beanA() {
    return new BeanA();
  }
}

public class BeanA {

  // method to be initialized after context is ready
  public void init() {
  }

} 

Si vous utilisez @Component, vous pouvez annoter avec @EventListener comme ceci.

@Component
public class BeanB {

  @EventListener
  public void onApplicationEvent(ContextRefreshedEvent event) {
  }
}

Dans mon cas, j’ai un système hérité dans lequel je prends maintenant l’utilisation de IoC/DI, où Spring Boot est le cadre choisi. L'ancien système apporte de nombreuses dépendances circulaires à la table et je dois donc utiliser beaucoup de dépendances. Cela m'a donné des maux de tête car je ne pouvais plus faire confiance à @PostConstruct car le câblage/injection automatique par poseur n'était pas encore terminé. L'ordre est constructeur, @PostConstruct, puis des décodeurs automatiques. Je l'ai résolu avec l'annotation @EventListener qui s'exécutera en dernier et à la "même" heure pour tous les beans. L'exemple montre l'implémentation de InitializingBean aswell.

J'ai deux classes (@Component) avec dépendance les uns aux autres. Les classes ont la même apparence pour les besoins de cet exemple et n’en affichent qu’une.

@Component
public class BeanA implements InitializingBean {
  private BeanB beanB;

  public BeanA() {
    log.debug("Created...");
  }

  @PostConstruct
  private void postConstruct() {
    log.debug("@PostConstruct");
  }

  @Autowired
  public void setBeanB(BeanB beanB) {
    log.debug("@Autowired beanB");
    this.beanB = beanB;
  }

  @Override
  public void afterPropertiesSet() throws Exception {
    log.debug("afterPropertiesSet()");
  }

  @EventListener
  public void onApplicationEvent(ContextRefreshedEvent event) {
    log.debug("@EventListener");
  } 
}

Il s’agit de la sortie du journal indiquant l’ordre des appels au démarrage du conteneur.

2018-11-30 18:29:30.504 DEBUG 3624 --- [           main] com.example.demo.BeanA                   : Created...
2018-11-30 18:29:30.509 DEBUG 3624 --- [           main] com.example.demo.BeanB                   : Created...
2018-11-30 18:29:30.517 DEBUG 3624 --- [           main] com.example.demo.BeanB                   : @Autowired beanA
2018-11-30 18:29:30.518 DEBUG 3624 --- [           main] com.example.demo.BeanB                   : @PostConstruct
2018-11-30 18:29:30.518 DEBUG 3624 --- [           main] com.example.demo.BeanB                   : afterPropertiesSet()
2018-11-30 18:29:30.518 DEBUG 3624 --- [           main] com.example.demo.BeanA                   : @Autowired beanB
2018-11-30 18:29:30.518 DEBUG 3624 --- [           main] com.example.demo.BeanA                   : @PostConstruct
2018-11-30 18:29:30.518 DEBUG 3624 --- [           main] com.example.demo.BeanA                   : afterPropertiesSet()
2018-11-30 18:29:30.607 DEBUG 3624 --- [           main] com.example.demo.BeanA                   : @EventListener
2018-11-30 18:29:30.607 DEBUG 3624 --- [           main] com.example.demo.BeanB                   : @EventListener

Comme vous pouvez le constater, @EventListener est exécuté en dernier lorsque tout est prêt et configuré.

2
Avec