Méthode init dans Spring Controller (version annotation)


105

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 à l'aide de la version d'annotation?


Réponses:


238

Vous pouvez utiliser

@PostConstruct
public void init() {
   // ...
}

1
Vous avez raison, sa "Common Annotations 1.0", Java1.7 fonctionnera également.
— Grim

Si vous devez utiliser l'utilisateur de SecurityContextHolder, au moment de PostConstruct, il n'est pas initialisé. Il doit être utilisé comme une méthode sans état. (getUser () ... {return Security ... user ();}
— Joao Polo

public ou privé
— anshulkatta

20

Vous pouvez également demander à votre classe d'implémenter l' InitializingBeaninterface pour fournir une fonction de rappel ( afterPropertiesSet()) que ApplicationContext appellera lorsque le bean est construit.


4

Il existe plusieurs façons d'intercepter le processus d'initialisation dans Spring. Si vous devez initialiser tous les beans et les autowire / injecter, il y a au moins deux façons que je connaisse qui assureront cela. Je n'ai testé que le second mais je pense 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 j'utilise maintenant IoC / DI où Spring Boot est le framework choisi. L'ancien système apporte de nombreuses dépendances circulaires à la table et je dois donc beaucoup utiliser la dépendance setter. Cela m'a donné des maux de tête car je ne pouvais pas faire confiance à @PostConstruct car l'autowiring / injection par setter n'était pas encore fait. L'ordre est constructeur, @PostConstruct puis setters autowired. Je l'ai résolu avec l'annotation @EventListener qui s'exécutera en dernier et en "même" temps pour tous les beans. L'exemple montre également l'implémentation d'InitializingBean.

J'ai deux classes (@Component) avec une dépendance l'une à l'autre. Les classes ont la même apparence dans le cadre de cet exemple en affichant une seule d'entre elles.

@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 montrant l'ordre des appels lorsque le conteneur démarre.

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 voir, @EventListener est exécuté en dernier une fois que tout est prêt et configuré.


-2
public class InitHelloWorld implements BeanPostProcessor {

   public Object postProcessBeforeInitialization(Object bean,
             String beanName) throws BeansException {
       System.out.println("BeforeInitialization : " + beanName);
       return bean;  // you can return any other object as well
   }

   public Object postProcessAfterInitialization(Object bean,
             String beanName) throws BeansException {
       System.out.println("AfterInitialization : " + beanName);
       return bean;  // you can return any other object as well
   }

}
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.