@SpringBootApplication
public class DataProcessorApplication {
public static void main(String[] args) throws UnknownHostException {
SpringApplication app = new SpringApplication(DataProcessorApplication.class);
app.run();
}
PostProcessor类
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class BeanRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
private static final Logger LOG = LoggerFactory.getLogger(BeanRegistryPostProcessor.class);
@Autowired
private DataConfigurationService dataConfigurationService;
@Override
public void postProcessBeanFactory(final ConfigurableListableBeanFactory factory)
throws BeansException {
// we don't want to touch existing beans
}
@Override
public void postProcessBeanDefinitionRegistry(final BeanDefinitionRegistry registry){
dataConfigurationService.something(); // service bean is null here
}
}
我的服务类
@Service
public class DataConfigurationService implements ApplicationListener<ApplicationReadyEvent> {
private static final Logger LOG = LoggerFactory.getLogger(DataConfigurationService.class);
@Override
public void onApplicationEvent(final ApplicationReadyEvent e) {
LOG.debug("Loading active DataConfiguration instance...");
}
}
异常
java.lang.NullPointerException: null
at dataprocessor.configmodels.processor.BeanRegistryPostProcessor.postProcessBeanDefinitionRegistry(BeanRegistryPostProcessor.java:40)
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:118)
at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:685)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:523)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:736)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:369)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:313)
at dataprocessor.DataProcessorApplication.main(DataProcessorApplication.java:47)
2017-01-07 12:42:47.802 WARN 8880 --- [ main] ationConfigEmbeddedWebApplicationContext : Exception thrown from LifecycleProcessor on context close
java.lang.IllegalStateException: LifecycleProcessor not initialized - call 'refresh' before invoking lifecycle methods via the context: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@7a138fc5: startup date [Sat Jan 07 12:42:46 CET 2017]; root of context hierarchy
at org.springframework.context.support.AbstractApplicationContext.getLifecycleProcessor(AbstractApplicationContext.java:416)
at org.springframework.context.support.AbstractApplicationContext.doClose(AbstractApplicationContext.java:1004)
at org.springframework.context.support.AbstractApplicationContext.close(AbstractApplicationContext.java:963)
at org.springframework.boot.SpringApplication.handleRunFailure(SpringApplication.java:793)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:324)
at dataprocessor.DataProcessorApplication.main(DataProcessorApplication.java:47)
2017-01-07 12:42:47.803 ERROR 8880 --- [ main] o.s.b.f.s.DefaultListableBeanFactory : Destroy method on bean with name 'org.springframework.boot.autoconfigure.internalCachingMetadataReaderFactory' threw an exception
java.lang.IllegalStateException: ApplicationEventMulticaster not initialized - call 'refresh' before multicasting events via the context: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@7a138fc5: startup date [Sat Jan 07 12:42:46 CET 2017]; root of context hierarchy
at org.springframework.context.support.AbstractApplicationContext.getApplicationEventMulticaster(AbstractApplicationContext.java:403)
at org.springframework.context.support.ApplicationListenerDetector.postProcessBeforeDestruction(ApplicationListenerDetector.java:97)
at org.springframework.beans.factory.support.DisposableBeanAdapter.destroy(DisposableBeanAdapter.java:233)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroyBean(DefaultSingletonBeanRegistry.java:578)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroySingleton(DefaultSingletonBeanRegistry.java:554)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.destroySingleton(DefaultListableBeanFactory.java:951)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroySingletons(DefaultSingletonBeanRegistry.java:523)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.destroySingletons(DefaultListableBeanFactory.java:958)
at org.springframework.context.support.AbstractApplicationContext.destroyBeans(AbstractApplicationContext.java:1035)
at org.springframework.context.support.AbstractApplicationContext.doClose(AbstractApplicationContext.java:1011)
at org.springframework.context.support.AbstractApplicationContext.close(AbstractApplicationContext.java:963)
at org.springframework.boot.SpringApplication.handleRunFailure(SpringApplication.java:793)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:324)
at dataprocessor.DataProcessorApplication.main(DataProcessorApplication.java:47)
POM
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.0.BUILD-SNAPSHOT</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
答案 0 :(得分:0)
Spring在下一个序列中初始化上下文:
首先,基于应用程序配置和自动检测的类(@Component
,@Service
等),将在BeanDefinitionRegistry
中创建并注册bean定义。
之后,Spring会自动检测在bean定义中实现BeanFactoryPostProcessor的bean,并在创建任何其他bean之前应用它们。由于BeanRegistryPostProcessor
是BeanFactoryPostProcessor
的实施,因此将在此步骤中应用它。
之后Spring将自动检测实现BeanPostProcessor接口的所有bean,并将它们应用于随后创建的任何bean。其中一个bean是AutowiredAnnotationBeanPostProcessor
,它处理@Autoware
注释。这意味着您的服务将在此步骤中注入。
如您所见,在将DataConfigurationService
bean注入BeanRegistryPostProcessor
之前,您正尝试使用它。要解决此问题,您可以在ApplicationContextAware
中实现BeanRegistryPostProcessor
接口,然后直接从应用程序上下文获取服务实例:
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class BeanRegistryPostProcessor
implements BeanDefinitionRegistryPostProcessor, ApplicationContextAware{
private ApplicationContext applicationContext;
...
@Override
public void postProcessBeanDefinitionRegistry(final BeanDefinitionRegistry registry){
DataConfigurationService service = applicationContext.getBean(DataConfigurationService.class);
service.something();
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
}
有关所谓的容器扩展点的更多详细信息,您可以在Spring documentation中找到。