Metodo Init in Spring Controller (versione annotazione)


105

Sto convertendo un controller nella versione di annotazione più recente. Nella vecchia versione ho usato per specificare il metodo init in springmvc-servlet.xml usando:

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

Come posso specificare il metodo init utilizzando la versione dell'annotazione?


Risposte:


238

Puoi usare

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

1
Hai ragione, le sue "Common Annotations 1.0", Java1.7 funzioneranno anche.
Grim

Se è necessario utilizzare l'utente da SecurityContextHolder, al momento PostConstruct non è inizializzato. Deve essere utilizzato come un metodo senza stato. (getUser () ... {return Security ... user ();}
Joao Polo

pubblico o privato
anshulkatta

20

In alternativa puoi fare in modo che la tua classe implementi l' InitializingBeaninterfaccia per fornire una funzione di callback ( afterPropertiesSet()) che ApplicationContext richiamerà quando il bean viene costruito.


4

Esistono diversi modi per intercettare il processo di inizializzazione in Spring. Se devi inizializzare tutti i bean e autowire / iniettarli, ci sono almeno due modi che conosco per garantire ciò. Ho solo testato il secondo ma credo che entrambi funzionino allo stesso modo.

Se stai usando @Bean puoi fare riferimento tramite initMethod, in questo modo.

@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() {
  }

} 

Se stai usando @Component puoi annotare con @EventListener in questo modo.

@Component
public class BeanB {

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

Nel mio caso ho un sistema legacy in cui ora sto utilizzando IoC / DI in cui Spring Boot è il framework scelto. Il vecchio sistema porta molte dipendenze circolari alla tabella e quindi devo usare molto la dipendenza setter. Questo mi ha dato qualche grattacapo poiché non potevo fidarmi di @PostConstruct poiché l'autowiring / injection dal setter non era ancora stato fatto. L'ordine è costruttore, @PostConstruct quindi setter autowired. L'ho risolto con l'annotazione @EventListener che verrà eseguita per ultima e alla "stessa" ora per tutti i bean. L'esempio mostra anche l'implementazione di InitializingBean.

Ho due classi (@Component) dipendenti l'una dall'altra. Le classi hanno lo stesso aspetto ai fini di questo esempio che ne mostra solo una.

@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");
  } 
}

Questo è l'output del registro che mostra l'ordine delle chiamate all'avvio del contenitore.

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

Come puoi vedere @EventListener viene eseguito per ultimo dopo che tutto è pronto e configurato.


-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
   }

}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.