public class GrailsEarlyPluginRegistrationPostProcessor extends java.lang.Object implements BeanDefinitionRegistryPostProcessor, ApplicationListener
Runs the plugin bean-registration phase of the Grails lifecycle before Spring Boot's
auto-configuration is processed, so that beans contributed by plugins via doWithSpring
are already present in the registry when Boot evaluates its @ConditionalOnMissingBean
guards — auto-configured defaults then back off in favour of the plugin beans, without any
override or removal afterwards.
It runs for a Grails application only: GrailsPluginLifecycleInitializer is registered for every Spring Boot application that has grails-core on its class path, and this phase stands down unless GrailsApp launched the application or one of the context's sources is a GrailsApplicationClass. A Spring Boot application using a Grails library - GSP for its views, say - gets that library's auto-configuration and nothing else: no plugin manager, no GrailsApplication, and no beans from plugins it never asked for.
It is added to the context programmatically (see GrailsPluginLifecycleInitializer), so its
postProcessBeanDefinitionRegistry runs ahead of Boot's ConfigurationClassPostProcessor
(which expands the @AutoConfiguration imports). Manually-added
BeanDefinitionRegistryPostProcessors always run before registry-discovered ones; Spring does
not sort manually-added post-processors by getOrder(), so this class deliberately does not
implement PriorityOrdered.
This phase builds the one true GrailsApplication and GrailsPluginManager: plugins
are discovered via the promoted PluginDiscovery singleton and instantiated exactly once.
Artefact discovery also happens here, mirroring
GrailsApplicationPostProcessor.performGrailsInitializationSequence(), because core plugins
(controllers, services, interceptors) iterate grailsApplication artefacts inside their
doWithSpring closures. Application classes are resolved from the source classes stashed by
GrailsApp (see APPLICATION_SOURCE_CLASSES_BEAN_NAME) and scanned with the
same logic GrailsAutoConfiguration.classes uses; an application GrailsApp did not
start has its sources read from the context instead.
Once complete, the grailsApplication and pluginManager singletons are promoted to
the bean factory together with the EARLY_REGISTRATION_COMPLETE_BEAN_NAME marker, so
GrailsApplicationPostProcessor reuses them instead of rebuilding and skips the already-drained
plugin runtime configuration.
| Modifiers | Name | Description |
|---|---|---|
static java.lang.String |
APPLICATION_SOURCE_CLASSES_BEAN_NAME |
Name of the Class[] singleton under which GrailsApp stashes the
application source classes so this phase can perform early artefact discovery. |
static java.lang.String |
EARLY_REGISTRATION_COMPLETE_BEAN_NAME |
Name of the marker singleton registered once this phase has completed, checked by GrailsApplicationPostProcessor to reuse the promoted singletons and skip the already-performed lifecycle steps. |
| Constructor and description |
|---|
GrailsEarlyPluginRegistrationPostProcessor(ConfigurableApplicationContext applicationContext) |
| Type Params | Return Type | Name and description |
|---|---|---|
|
public void |
onApplicationEvent(ContextRefreshedEvent event) |
|
public void |
postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) |
| Methods inherited from class | Name |
|---|---|
class java.lang.Object |
java.lang.Object#equals(java.lang.Object), java.lang.Object#getClass(), java.lang.Object#hashCode(), java.lang.Object#notify(), java.lang.Object#notifyAll(), java.lang.Object#toString(), java.lang.Object#wait(), java.lang.Object#wait(long), java.lang.Object#wait(long, int) |
Name of the Class[] singleton under which GrailsApp stashes the
application source classes so this phase can perform early artefact discovery.
Name of the marker singleton registered once this phase has completed, checked by GrailsApplicationPostProcessor to reuse the promoted singletons and skip the already-performed lifecycle steps. Always checked on the local bean factory only.