Java Spring控制器中的Init方法(注释版本)

Java Spring控制器中的Init方法(注释版本),java,spring,annotations,controller,Java,Spring,Annotations,Controller,我正在将控制器转换为较新的注释版本。在旧版本中,我使用以下命令指定springmvc-servlet.xml中的init方法: <beans> <bean id="myBean" class="..." init-method="init"/> </beans> 如何使用注释版本指定init方法?您可以使用 @PostConstruct public void init() { // ... } 或者,您可以让您的类实现接口,以提供回调函

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

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

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

您可以使用

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

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

有几种方法可以在Spring中拦截初始化过程。如果必须初始化所有bean并自动连接/注入它们,我知道至少有两种方法可以确保这一点。我只测试了第二个,但我相信两个都是一样的

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
   }

}
如果您使用的是@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
public class BeanB {

  @EventListener
  public void onApplicationEvent(ContextRefreshedEvent event) {
  }
}
如果您使用的是@Component,那么可以像这样使用@EventListener进行注释

@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
public class BeanB {

  @EventListener
  public void onApplicationEvent(ContextRefreshedEvent event) {
  }
}
在我的例子中,我有一个遗留系统,我现在使用IoC/DI,其中springboot是choosen框架。旧系统给表带来了许多循环依赖,因此我必须经常使用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在一切就绪并配置好之后最后运行。

另请参见您是对的,它的“Common Annotations 1.0”,Java1.7也可以工作。如果您需要使用SecurityContextHolder中的用户,则在构造后一刻它还没有初始化。它需要像无状态方法一样使用。(getUser()…{return Security…user();}公共或私有