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

时间:2011-03-24 13:11:02

标签: java spring annotations controller

我正在将控制器转换为较新的注释版本。在旧版本中,我曾使用:

在springmvc-servlet.xml中指定init方法
<beans>
    <bean id="myBean" class="..." init-method="init"/>
</beans>

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

4 个答案:

答案 0 :(得分:222)

您可以使用

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

答案 1 :(得分:19)

或者你可以让你的类实现InitializingBean接口来提供一个回调函数(afterPropertiesSet()),ApplicationContext将在构造bean时调用它。

答案 2 :(得分:1)

有几种方法可以拦截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() {
  }

} 

如果您使用的是@Component,则可以使用@EventListener进行注释。

@Component
public class BeanB {

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

在我的情况下,我有一个旧系统,现在使用IoC / DI,其中选择了Spring Boot框架。旧系统为表带来了许多循环依赖,因此我必须大量使用setter依赖。这让我有些头疼,因为我无法信任@PostConstruct,因为尚未完成setter的自动装配/注入。顺序是构造函数,然后是@PostConstruct,然后是自动绑定的二传手。我用@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");
  } 
}

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

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

您可以看到@EventListener在一切准备就绪并配置完毕后最后运行。

答案 3 :(得分:-1)

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
   }

}