在BeanDefinitionRegistryPostProcessor内部访问Spring ApplicationContext

时间:2018-10-11 22:20:51

标签: java spring spring-bean

一个人如何访问ApplicationContext(BDRPP)内部的BeanDefinitionRegistryPostProcessor?我有以下BDRPP。

public class MyCustomBeansFactoryPostProcessor implements BeanDefinitionRegistryPostProcessor {

  @Override
  public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
    // Need to access ApplicationContext here
    System.out.println("Got Application Context: " + applicationContext);
  }

  @Override
  public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
  }
}

尝试添加@Autowired,甚至使我的CustomBDRPP实现ApplicationContextAware,但未注入/初始化ApplicationContext。

public class MyCustomBeansFactoryPostProcessor implements BeanDefinitionRegistryPostProcessor, ApplicationContextAware {

  //@Autowired
  private ApplicationContext applicationContext;

  public void setApplicationContext(ApplicationContext context) {
    applicationContext = context;
  }

  @Override
  public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
    System.out.println("Got Application Context: " + applicationContext);
  }

  @Override
  public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
  }
}

输出:

Got Application Context: null

如何实现?

3 个答案:

答案 0 :(得分:2)

我有一个类似的任务,并声明BDRPP作为Bean起作用:

public class MyCustomBdrpp implements BeanDefinitionRegistryPostProcessor {

  private ApplicationContext context;

  private MyCostomBdrpp(ApplicationContext context) {
    this.context = context;
  }

  @Override
  public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
    //foo
  }

  @Override
  public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
    //bar
  }
}

然后:

@Configuration
class MyConfig {

  @Bean
  public MyCustomBdrpp myBdrpp(@Autowired ApplicationContext context) {
    return new MyCustomBdrpp(context);
  }

}

但是我要说的是我是在手动创建上下文:

AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
context.register(MyConfig.class);
context.refresh();

答案 1 :(得分:0)

您可以使用以下代码静态访问Application上下文

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Service;

@Service
public class BeanUtil implements ApplicationContextAware {

    private static ApplicationContext context;
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        context = applicationContext;
    }
    public static <T> T getBean(Class<T> beanClass) {
        return context.getBean(beanClass);
    }
}

答案 2 :(得分:0)

这有效,至少在 Sprint Boot 2.3.5 中:

@Configuration
public class TestConfig implements BeanDefinitionRegistryPostProcessor, 
    ApplicationContextAware {

    private ApplicationContext context;

    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
        String driver = context.getEnvironment().getProperty("spring.datasource.driver-class-name");
    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws 
BeansException {
        this.context = applicationContext;
    }
}