Spring 引导 bean 空异常
Spring boot bean null exception
@SpringBootApplication
public class DataProcessorApplication {
public static void main(String[] args) throws UnknownHostException {
SpringApplication app = new SpringApplication(DataProcessorApplication.class);
app.run();
}
后处理器class
@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
}
}
我的服务class
@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>
Spring 在下一个序列中初始化上下文:
首先,基于应用程序配置和自动检测类(@Component
、@Service
等)bean定义将被创建并注册到BeanDefinitionRegistry
.
之后 Spring 将自动检测在其 bean 定义中实现 BeanFactoryPostProcessor 的 bean,并在创建任何其他 bean 之前应用它们。由于您的 BeanRegistryPostProcessor
是 BeanFactoryPostProcessor
的实现,它将应用于此步骤。
之后 Spring 将自动检测所有实现 BeanPostProcessor 接口的 bean,并将它们应用于随后创建的任何 bean。其中一个 bean 是 AutowiredAnnotationBeanPostProcessor
,它处理 @Autoware
注释。这意味着您的服务将在此步骤中注入。
如您所见,您正尝试在将 DataConfigurationService
bean 注入 BeanRegistryPostProcessor
之前使用它。为了解决这个问题,您可以在 BeanRegistryPostProcessor
中实现 ApplicationContextAware
接口,然后直接从应用程序上下文中获取服务实例:
@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.
中找到
@SpringBootApplication
public class DataProcessorApplication {
public static void main(String[] args) throws UnknownHostException {
SpringApplication app = new SpringApplication(DataProcessorApplication.class);
app.run();
}
后处理器class
@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
}
}
我的服务class
@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>
Spring 在下一个序列中初始化上下文:
首先,基于应用程序配置和自动检测类(@Component
、@Service
等)bean定义将被创建并注册到BeanDefinitionRegistry
.
之后 Spring 将自动检测在其 bean 定义中实现 BeanFactoryPostProcessor 的 bean,并在创建任何其他 bean 之前应用它们。由于您的 BeanRegistryPostProcessor
是 BeanFactoryPostProcessor
的实现,它将应用于此步骤。
之后 Spring 将自动检测所有实现 BeanPostProcessor 接口的 bean,并将它们应用于随后创建的任何 bean。其中一个 bean 是 AutowiredAnnotationBeanPostProcessor
,它处理 @Autoware
注释。这意味着您的服务将在此步骤中注入。
如您所见,您正尝试在将 DataConfigurationService
bean 注入 BeanRegistryPostProcessor
之前使用它。为了解决这个问题,您可以在 BeanRegistryPostProcessor
中实现 ApplicationContextAware
接口,然后直接从应用程序上下文中获取服务实例:
@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.
中找到