Skip to content

Commit 29476e5

Browse files
authored
Merge pull request #1205 from rainboyan
* pr/1205: Refactor GrailsApplicationLifeCycle Closes gh-1205
2 parents e3af96e + 8d7161d commit 29476e5

File tree

8 files changed

+67
-190
lines changed

8 files changed

+67
-190
lines changed
Lines changed: 6 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2015-2022 the original author or authors.
2+
* Copyright 2015-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -15,40 +15,16 @@
1515
*/
1616
package grails.core
1717

18+
import groovy.transform.CompileStatic
19+
1820
/**
1921
* Marker interface for the GrailsApplicationClass
2022
*
2123
* @author Graeme Rocher
24+
* @author Michael Yan
2225
* @since 3.0.10
2326
*/
24-
trait GrailsApplicationClass implements GrailsApplicationLifeCycle {
25-
26-
@Override
27-
Closure doWithSpring() { null }
28-
29-
@Override
30-
void doWithDynamicMethods() {
31-
// no-op
32-
}
33-
34-
@Override
35-
void doWithApplicationContext() {
36-
// no-op
37-
}
38-
39-
@Override
40-
void onConfigChange(Map<String, Object> event) {
41-
// no-op
42-
}
43-
44-
@Override
45-
void onStartup(Map<String, Object> event) {
46-
// no-op
47-
}
48-
49-
@Override
50-
void onShutdown(Map<String, Object> event) {
51-
// no-op
52-
}
27+
@CompileStatic
28+
trait GrailsApplicationClass implements GrailsApplicationLifecycle {
5329

5430
}

grace-api/src/main/groovy/grails/core/GrailsApplicationLifeCycleAdapter.groovy

Lines changed: 0 additions & 60 deletions
This file was deleted.

grace-api/src/main/groovy/grails/core/GrailsApplicationLifeCycle.groovy renamed to grace-api/src/main/groovy/grails/core/GrailsApplicationLifecycle.java

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2014-2023 the original author or authors.
2+
* Copyright 2014-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -13,57 +13,69 @@
1313
* See the License for the specific language governing permissions and
1414
* limitations under the License.
1515
*/
16-
package grails.core
16+
package grails.core;
17+
18+
import java.util.Map;
19+
20+
import groovy.lang.Closure;
1721

1822
/**
1923
* API which plugins implement to provide behavior in defined application lifecycle hooks.
2024
*
21-
* The {@link GrailsApplicationLifeCycle#doWithSpring()} method can be used register Spring beans.
25+
* The {@link GrailsApplicationLifecycle#doWithSpring()} method can be used register Spring beans.
2226
*
27+
* @author Graeme Rocher
28+
* @author Michael Yan
2329
* @since 3.0
24-
* @see {@link grails.plugins.Plugin}
2530
*/
26-
interface GrailsApplicationLifeCycle {
31+
public interface GrailsApplicationLifecycle {
2732

2833
/**
29-
* Sub classes should override to provide implementations
34+
* Subclasses should override to provide implementations
3035
*
3136
* @return A closure that defines beans to be registered by Spring
3237
*/
33-
Closure doWithSpring()
38+
default Closure<?> doWithSpring() {
39+
return null;
40+
}
3441

3542
/**
3643
* Invoked once the {@link org.springframework.context.ApplicationContext} has been refreshed in a phase
3744
* where plugins can add dynamic methods. Subclasses should override
3845
*/
39-
void doWithDynamicMethods()
46+
default void doWithDynamicMethods() {
47+
}
4048

4149
/**
4250
* Invoked once the {@link org.springframework.context.ApplicationContext} has been refreshed
4351
* and after {#doWithDynamicMethods()} is invoked. Subclasses should override
4452
*/
45-
void doWithApplicationContext()
53+
default void doWithApplicationContext() {
54+
}
4655

4756
/**
4857
* Invoked when the application configuration changes
4958
*
5059
* @param event The event
5160
*/
52-
void onConfigChange(Map<String, Object> event)
61+
default void onConfigChange(Map<String, Object> event) {
62+
}
5363

5464
/**
55-
* Invoked once all prior initialization hooks: {@link GrailsApplicationLifeCycle#doWithSpring()},
56-
* {@link GrailsApplicationLifeCycle#doWithDynamicMethods()} and {@link GrailsApplicationLifeCycle#doWithApplicationContext()}
65+
* Invoked once all prior initialization hooks: {@link GrailsApplicationLifecycle#doWithSpring()},
66+
* {@link GrailsApplicationLifecycle#doWithDynamicMethods()} and {@link GrailsApplicationLifecycle#doWithApplicationContext()}
5767
*
5868
* @param event The event
5969
*/
60-
void onStartup(Map<String, Object> event)
70+
default void onStartup(Map<String, Object> event) {
71+
}
6172

6273
/**
6374
* Invoked when the {@link org.springframework.context.ApplicationContext} is closed
6475
*
6576
* @param event The event
6677
*/
67-
void onShutdown(Map<String, Object> event)
78+
default void onShutdown(Map<String, Object> event) {
79+
}
6880

6981
}

grace-boot/src/main/groovy/grails/boot/config/GrailsApplicationEventListener.java

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2014-2023 the original author or authors.
2+
* Copyright 2014-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -33,7 +33,7 @@
3333
import org.springframework.util.Assert;
3434

3535
import grails.core.GrailsApplication;
36-
import grails.core.GrailsApplicationLifeCycle;
36+
import grails.core.GrailsApplicationLifecycle;
3737
import grails.plugins.GrailsPluginManager;
3838
import grails.util.Environment;
3939
import grails.util.Holders;
@@ -42,7 +42,7 @@
4242
import org.grails.datastore.mapping.model.MappingContext;
4343

4444
/**
45-
* A {@link ApplicationListener} to initialize Grails with Plugins and GrailsApplicationLifeCycles
45+
* A {@link ApplicationListener} to initialize Grails with Plugins and GrailsApplicationLifecycles
4646
* when an {@link ApplicationContext} gets refreshed or closed.
4747
*
4848
* @author Graeme Rocher
@@ -67,8 +67,8 @@ public void onApplicationEvent(ApplicationContextEvent event) {
6767
GrailsApplication grailsApplication = applicationContext.getBean(GrailsApplication.APPLICATION_ID, GrailsApplication.class);
6868
GrailsPluginManager pluginManager = applicationContext.getBean(GrailsPluginManager.BEAN_NAME, GrailsPluginManager.class);
6969

70-
List<GrailsApplicationLifeCycle> lifeCycleBeans =
71-
applicationContext.getBeansOfType(GrailsApplicationLifeCycle.class)
70+
List<GrailsApplicationLifecycle> lifecycleBeans =
71+
applicationContext.getBeansOfType(GrailsApplicationLifecycle.class)
7272
.values()
7373
.stream().sorted(OrderComparator.INSTANCE)
7474
.collect(Collectors.toList());
@@ -84,15 +84,15 @@ public void onApplicationEvent(ApplicationContextEvent event) {
8484
StartupStep dynamicMethods = this.applicationStartup.start("grails.application.context.dynamic-methods");
8585
pluginManager.setApplicationContext(applicationContext);
8686
pluginManager.doDynamicMethods();
87-
for (GrailsApplicationLifeCycle lifeCycle : lifeCycleBeans) {
88-
lifeCycle.doWithDynamicMethods();
87+
for (GrailsApplicationLifecycle lifecycle : lifecycleBeans) {
88+
lifecycle.doWithDynamicMethods();
8989
}
9090
dynamicMethods.end();
9191

9292
StartupStep postProcessing = this.applicationStartup.start("grails.application.context.post-processing");
9393
pluginManager.doPostProcessing(applicationContext);
94-
for (GrailsApplicationLifeCycle lifeCycle : lifeCycleBeans) {
95-
lifeCycle.doWithApplicationContext();
94+
for (GrailsApplicationLifecycle lifecycle : lifecycleBeans) {
95+
lifecycle.doWithApplicationContext();
9696
}
9797
postProcessing.end();
9898

@@ -102,8 +102,8 @@ public void onApplicationEvent(ApplicationContextEvent event) {
102102
Map<String, Object> eventMap = new HashMap<>();
103103
eventMap.put("source", pluginManager);
104104
pluginManager.onStartup(eventMap);
105-
for (GrailsApplicationLifeCycle lifeCycle : lifeCycleBeans) {
106-
lifeCycle.onStartup(eventMap);
105+
for (GrailsApplicationLifecycle lifecycle : lifecycleBeans) {
106+
lifecycle.onStartup(eventMap);
107107
}
108108
startupStep.end();
109109
}
@@ -112,10 +112,10 @@ else if (event instanceof ContextClosedEvent) {
112112
Map<String, Object> eventMap = new HashMap<>();
113113
eventMap.put("source", pluginManager);
114114

115-
List<GrailsApplicationLifeCycle> reversedLifeCycleBeans = new ArrayList<>(lifeCycleBeans);
116-
Collections.reverse(reversedLifeCycleBeans);
117-
for (GrailsApplicationLifeCycle lifeCycle : reversedLifeCycleBeans) {
118-
lifeCycle.onShutdown(eventMap);
115+
List<GrailsApplicationLifecycle> reversedLifecycleBeans = new ArrayList<>(lifecycleBeans);
116+
Collections.reverse(reversedLifecycleBeans);
117+
for (GrailsApplicationLifecycle lifecycle : reversedLifecycleBeans) {
118+
lifecycle.onShutdown(eventMap);
119119
}
120120

121121
pluginManager.shutdown();

grace-boot/src/main/groovy/grails/boot/config/GrailsApplicationPostProcessor.java

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@
5555
import grails.config.Settings;
5656
import grails.core.DefaultGrailsApplication;
5757
import grails.core.GrailsApplication;
58-
import grails.core.GrailsApplicationLifeCycle;
58+
import grails.core.GrailsApplicationLifecycle;
5959
import grails.plugins.GrailsPlugin;
6060
import grails.plugins.GrailsPluginManager;
6161
import grails.spring.BeanBuilder;
@@ -101,7 +101,7 @@ public class GrailsApplicationPostProcessor
101101

102102
protected ApplicationContext applicationContext;
103103

104-
protected GrailsApplicationLifeCycle lifeCycle;
104+
protected GrailsApplicationLifecycle lifecycle;
105105

106106
protected Set<Class<?>> classes;
107107

@@ -116,8 +116,8 @@ public GrailsApplicationPostProcessor() {
116116
this.grailsApplicationEventListener = new GrailsApplicationEventListener();
117117
}
118118

119-
public void setGrailsApplicationLifeCycle(GrailsApplicationLifeCycle lifeCycle) {
120-
this.lifeCycle = lifeCycle;
119+
public void setGrailsApplicationLifecycle(GrailsApplicationLifecycle lifecycle) {
120+
this.lifecycle = lifecycle;
121121
}
122122

123123
public void setLoadExternalBeans(boolean loadExternalBeans) {
@@ -315,26 +315,26 @@ public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) t
315315
b.setVariable(GrailsApplication.APPLICATION_ID, this.grailsApplication);
316316
b.setVariable("application", this.grailsApplication);
317317
b.setVariable("manager", this.pluginManager);
318-
if (this.lifeCycle != null) {
319-
Closure<?> withSpring = this.lifeCycle.doWithSpring();
318+
if (this.lifecycle != null) {
319+
Closure<?> withSpring = this.lifecycle.doWithSpring();
320320
if (withSpring != null) {
321321
BeanBuilder bb = new BeanBuilder(null, springConfig, application.getClassLoader());
322-
bb.setBeanBuildResource(new DescriptiveResource(this.lifeCycle.getClass().getName()));
322+
bb.setBeanBuildResource(new DescriptiveResource(this.lifecycle.getClass().getName()));
323323
bb.setBinding(b);
324324
bb.beans(withSpring);
325325
}
326326
}
327327

328-
Collection<GrailsApplicationLifeCycle> lifeCycles = this.applicationContext.getBeansOfType(GrailsApplicationLifeCycle.class)
328+
Collection<GrailsApplicationLifecycle> lifecycles = this.applicationContext.getBeansOfType(GrailsApplicationLifecycle.class)
329329
.values()
330330
.stream()
331331
.sorted(OrderComparator.INSTANCE)
332332
.collect(Collectors.toList());
333-
for (GrailsApplicationLifeCycle lifeCycle : lifeCycles) {
334-
Closure<?> withSpring = lifeCycle.doWithSpring();
333+
for (GrailsApplicationLifecycle lifecycle : lifecycles) {
334+
Closure<?> withSpring = lifecycle.doWithSpring();
335335
if (withSpring != null) {
336336
BeanBuilder bb = new BeanBuilder(null, springConfig, application.getClassLoader());
337-
bb.setBeanBuildResource(new DescriptiveResource(lifeCycle.getClass().getName()));
337+
bb.setBeanBuildResource(new DescriptiveResource(lifecycle.getClass().getName()));
338338
bb.setBinding(b);
339339
bb.beans(withSpring);
340340
}

grace-boot/src/main/groovy/org/grails/boot/web/servlet/GrailsBootstrapClassRunner.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
import grails.artefact.ArtefactTypes;
3030
import grails.boot.web.servlet.GrailsBootstrapClass;
3131
import grails.core.GrailsApplication;
32-
import grails.core.GrailsApplicationLifeCycleAdapter;
32+
import grails.core.GrailsApplicationLifecycle;
3333
import grails.core.GrailsClass;
3434
import grails.core.support.GrailsApplicationAware;
3535
import grails.plugins.GrailsPluginManager;
@@ -41,8 +41,8 @@
4141
* @author Michael Yan
4242
* @since 2024.0.0
4343
*/
44-
public class GrailsBootstrapClassRunner extends GrailsApplicationLifeCycleAdapter
45-
implements GrailsApplicationAware, ServletContextAware, ApplicationContextAware, PluginManagerAware {
44+
public class GrailsBootstrapClassRunner
45+
implements GrailsApplicationLifecycle, GrailsApplicationAware, ServletContextAware, ApplicationContextAware, PluginManagerAware {
4646

4747
private static final Logger log = LoggerFactory.getLogger(GrailsBootstrapClassRunner.class);
4848

0 commit comments

Comments
 (0)