Init-Methode in Spring Controller (Anmerkungsversion)

105

Ich konvertiere einen Controller in die neuere Annotation-Version. In der alten Version habe ich die init-Methode in springmvc-servlet.xml mit folgenden Angaben angegeben:

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

Wie kann ich die init-Methode mithilfe der Anmerkungsversion angeben?

Krt_Malta
quelle

Antworten:

238

Sie können verwenden

@PostConstruct
public void init() {
   // ...
}
Johan Sjöberg
quelle
1
Sie haben Recht, seine "Common Annotations 1.0", Java1.7 wird auch funktionieren.
Grimmiger
Wenn Sie den Benutzer von SecurityContextHolder verwenden müssen, wird er zum Zeitpunkt von PostConstruct nicht initialisiert. Es muss wie eine zustandslose Methode verwendet werden. (getUser () ... {return Security ... user ();}
Joao Polo
öffentlich oder privat
anshulkatta
20

Alternativ können Sie Ihre Klasse die InitializingBeanSchnittstelle implementieren lassen, um eine Rückruffunktion ( afterPropertiesSet()) bereitzustellen, die der ApplicationContext beim Erstellen der Bean aufruft.

matt b
quelle
4

Es gibt verschiedene Möglichkeiten, den Initialisierungsprozess im Frühjahr abzufangen. Wenn Sie alle Beans initialisieren und automatisch verdrahten / injizieren müssen, gibt es mindestens zwei Möglichkeiten, die ich kenne, um dies sicherzustellen. Ich habe nur den zweiten getestet, aber ich glaube, dass beide gleich funktionieren.

Wenn Sie @Bean verwenden, können Sie mit initMethod wie folgt referenzieren.

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

} 

Wenn Sie @Component verwenden, können Sie mit @EventListener wie folgt kommentieren.

@Component
public class BeanB {

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

In meinem Fall habe ich ein Legacy-System, in dem ich jetzt IoC / DI verwende, wobei Spring Boot das ausgewählte Framework ist. Das alte System bringt viele zirkuläre Abhängigkeiten in die Tabelle und ich muss daher viel Setter-Abhängigkeit verwenden. Das bereitete mir einige Kopfschmerzen, da ich @PostConstruct nicht vertrauen konnte, da die automatische Verdrahtung / Injektion durch den Setter noch nicht durchgeführt wurde. Die Reihenfolge ist Konstruktor, @PostConstruct und dann automatisch verdrahtete Setter. Ich habe es mit der Annotation @EventListener gelöst, die zuletzt und zur "gleichen" Zeit für alle Beans ausgeführt wird. Das Beispiel zeigt auch die Implementierung von InitializingBean.

Ich habe zwei Klassen (@Component) mit Abhängigkeit voneinander. Die Klassen sehen für den Zweck dieses Beispiels gleich aus und zeigen nur eine davon an.

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

Dies ist die Protokollausgabe, die die Reihenfolge der Aufrufe beim Start des Containers anzeigt.

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

Wie Sie sehen, wird @EventListener zuletzt ausgeführt, nachdem alles fertig und konfiguriert ist.

Avec
quelle
-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
quelle