Método de inicio en Spring Controller (versión de anotación)


105

Estoy convirtiendo un controlador a la versión de anotación más nueva. En la versión anterior, solía especificar el método init en springmvc-servlet.xml usando:

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

¿Cómo puedo especificar el método init usando la versión de anotación?


Respuestas:


238

Puedes usar

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

1
Tiene razón, su "Common Annotations 1.0", Java1.7 también funcionará.
— Grim

Si necesita utilizar el usuario de SecurityContextHolder, en el momento de PostConstruct no se inicializa. Debe usarse como un método sin estado. (getUser () ... {return Security ... user ();}
— Joao Polo

público o privado
— anshulkatta

20

Alternativamente, puede hacer que su clase implemente la InitializingBeaninterfaz para proporcionar una función de devolución de llamada ( afterPropertiesSet()) que ApplicationContext invocará cuando se construya el bean.


4

Hay varias formas de interceptar el proceso de inicialización en Spring. Si tiene que inicializar todos los beans y conectarlos automáticamente / inyectarlos, hay al menos dos formas que conozco que asegurarán esto. Solo he probado el segundo, pero creo que ambos funcionan igual.

Si está utilizando @Bean, puede hacer referencia mediante initMethod, así.

@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 está utilizando @Component, puede anotar con @EventListener de esta manera.

@Component
public class BeanB {

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

En mi caso, tengo un sistema heredado en el que ahora estoy usando IoC / DI donde Spring Boot es el marco elegido. El sistema antiguo trae muchas dependencias circulares a la tabla y, por lo tanto, debo usar mucho la dependencia del setter. Eso me dio algunos dolores de cabeza ya que no podía confiar en @PostConstruct ya que aún no se había realizado el cableado automático / inyección por parte del colocador. El orden es constructor, @PostConstruct y luego configuradores con cableado automático. Lo resolví con la anotación @EventListener que se ejecutará en último lugar y al "mismo" tiempo para todos los beans. El ejemplo también muestra la implementación de InitializingBean.

Tengo dos clases (@Component) con dependencia entre sí. Las clases tienen el mismo aspecto para el propósito de este ejemplo que muestra solo una de ellas.

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

Esta es la salida del registro que muestra el orden de las llamadas cuando se inicia el contenedor.

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

Como puede ver, @EventListener se ejecuta en último lugar después de que todo esté listo y configurado.


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

}
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.