Spring Controller中的Init方法(注释版本)

Krt*_*lta 103 java spring annotations controller

我正在将控制器转换为更新的注释版本.在旧版本中,我曾使用以下命令在springmvc-servlet.xml中指定init方法:

<beans>
    <bean id="myBean" class="..." init-method="init"/>
</beans>
Run Code Online (Sandbox Code Playgroud)

如何使用注释版本指定init方法?

Joh*_*erg 226

您可以使用

@PostConstruct
public void init() {
   // ...
}
Run Code Online (Sandbox Code Playgroud)


mat*_*t b 20

或者,您可以让您的类实现InitializingBean接口以提供回调函数(afterPropertiesSet()),当构造bean时,ApplicationContext将调用该函数.


Ave*_*vec 5

Spring中有几种方法可以拦截初始化过程。如果您必须初始化所有 bean 并自动装配/注入它们,我知道至少有两种方法可以确保这一点。我只测试了第二个,但我相信两者的工作方式相同。

如果你使用@Bean,你可以通过 initMethod 引用,就像这样。

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

} 
Run Code Online (Sandbox Code Playgroud)

如果您使用@Component,您可以像这样使用@EventListener 进行注释。

@Component
public class BeanB {

  @EventListener
  public void onApplicationEvent(ContextRefreshedEvent event) {
  }
}
Run Code Online (Sandbox Code Playgroud)

就我而言,我有一个遗留系统,我现在正在使用 IoC/DI,其中 Spring Boot 是选择的框架。旧系统给表带来了许多循环依赖,因此我必须大量使用 setter-dependency。这让我有些头疼,因为我无法信任 @PostConstruct,因为尚未完成 setter 的自动装配/注入。顺序是构造函数,@PostConstruct 然后是自动装配的 setter。我用 @EventListener 注释解决了它,该注释将在所有 bean 的最后和“相同”时间运行。该示例还显示了 InitializingBean 的实现。

我有两个相互依赖的类(@Component)。出于本示例的目的,这些类看起来相同,仅显示其中之一。

@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");
  } 
}
Run Code Online (Sandbox Code Playgroud)

这是显示容器启动时调用顺序的日志输出。

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
Run Code Online (Sandbox Code Playgroud)

如您所见,@EventListener 在一切准备就绪并配置后最后运行。