@SpringBootApplication
public class DataProcessorApplication {
public static void main(String[] args) throws UnknownHostException {
SpringApplication app = new SpringApplication(DataProcessorApplication.class);
app.run();
}
PostProcessor 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
}
}
My Service 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...");
}
}
Exception
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 initializes context in next sequence:
First, based on application configuration and automatically detected classes(
@Component
,@Service
etc) bean definitions will be created and registered inBeanDefinitionRegistry
.After that Spring will auto-detect beans which implement BeanFactoryPostProcessor in their bean definitions and apply them before any other beans get created. Since your
BeanRegistryPostProcessor
is implementation ofBeanFactoryPostProcessor
it will be applied on this step.After that Spring will auto-detect all beans which implement BeanPostProcessor interface and will apply them to any beans subsequently created. One of this beans is
AutowiredAnnotationBeanPostProcessor
which processes@Autoware
annotation. That means your service will be injected on this step.As you see you're trying to use
DataConfigurationService
bean before it will be injected intoBeanRegistryPostProcessor
. For solve this problem you can implementApplicationContextAware
interface inBeanRegistryPostProcessor
and then get instance of service directly from application context:More details about so called Container Extension Points you can find in Spring documentation.