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?

Krt_Malta
la source

Réponses:

238

Vous pouvez utiliser

@PostConstruct
public void init() {
   // ...
}
Johan Sjöberg
la source
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.

mat b
la source
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é.

Avec
la source
-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
   }

}
Yasir Shabbir Choudhary
la source