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?


Antworten:


238

Sie können verwenden

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

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.


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.


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

}
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.