17
17
package org .springframework .scripting .groovy ;
18
18
19
19
import java .io .IOException ;
20
+ import java .lang .reflect .InvocationTargetException ;
20
21
21
22
import groovy .lang .GroovyClassLoader ;
22
23
import groovy .lang .GroovyObject ;
23
24
import groovy .lang .MetaClass ;
24
25
import groovy .lang .Script ;
25
26
import org .codehaus .groovy .control .CompilationFailedException ;
27
+ import org .codehaus .groovy .control .CompilerConfiguration ;
28
+ import org .codehaus .groovy .control .customizers .CompilationCustomizer ;
26
29
27
30
import org .springframework .beans .factory .BeanClassLoaderAware ;
28
31
import org .springframework .beans .factory .BeanFactory ;
33
36
import org .springframework .scripting .ScriptSource ;
34
37
import org .springframework .util .Assert ;
35
38
import org .springframework .util .ClassUtils ;
39
+ import org .springframework .util .ObjectUtils ;
40
+ import org .springframework .util .ReflectionUtils ;
36
41
37
42
/**
38
43
* {@link org.springframework.scripting.ScriptFactory} implementation
@@ -55,7 +60,9 @@ public class GroovyScriptFactory implements ScriptFactory, BeanFactoryAware, Bea
55
60
56
61
private final String scriptSourceLocator ;
57
62
58
- private final GroovyObjectCustomizer groovyObjectCustomizer ;
63
+ private GroovyObjectCustomizer groovyObjectCustomizer ;
64
+
65
+ private CompilerConfiguration compilerConfiguration ;
59
66
60
67
private GroovyClassLoader groovyClassLoader ;
61
68
@@ -78,27 +85,62 @@ public class GroovyScriptFactory implements ScriptFactory, BeanFactoryAware, Bea
78
85
* Interpreted by the post-processor that actually creates the script.
79
86
*/
80
87
public GroovyScriptFactory (String scriptSourceLocator ) {
81
- this (scriptSourceLocator , null );
88
+ Assert .hasText (scriptSourceLocator , "'scriptSourceLocator' must not be empty" );
89
+ this .scriptSourceLocator = scriptSourceLocator ;
82
90
}
83
91
84
92
/**
85
93
* Create a new GroovyScriptFactory for the given script source,
86
94
* specifying a strategy interface that can create a custom MetaClass
87
95
* to supply missing methods and otherwise change the behavior of the object.
88
- * <p>We don't need to specify script interfaces here, since
89
- * a Groovy script defines its Java interfaces itself.
90
96
* @param scriptSourceLocator a locator that points to the source of the script.
91
97
* Interpreted by the post-processor that actually creates the script.
92
98
* @param groovyObjectCustomizer a customizer that can set a custom metaclass
93
99
* or make other changes to the GroovyObject created by this factory
94
100
* (may be {@code null})
101
+ * @see GroovyObjectCustomizer#customize
95
102
*/
96
103
public GroovyScriptFactory (String scriptSourceLocator , GroovyObjectCustomizer groovyObjectCustomizer ) {
97
- Assert .hasText (scriptSourceLocator , "'scriptSourceLocator' must not be empty" );
98
- this .scriptSourceLocator = scriptSourceLocator ;
104
+ this (scriptSourceLocator );
99
105
this .groovyObjectCustomizer = groovyObjectCustomizer ;
100
106
}
101
107
108
+ /**
109
+ * Create a new GroovyScriptFactory for the given script source,
110
+ * specifying a strategy interface that can create a custom MetaClass
111
+ * to supply missing methods and otherwise change the behavior of the object.
112
+ * @param scriptSourceLocator a locator that points to the source of the script.
113
+ * Interpreted by the post-processor that actually creates the script.
114
+ * @param compilerConfiguration a custom compiler configuration to be applied
115
+ * to the GroovyClassLoader (may be {@code null})
116
+ * @since 4.3.3
117
+ * @see GroovyClassLoader#GroovyClassLoader(ClassLoader, CompilerConfiguration)
118
+ */
119
+ public GroovyScriptFactory (String scriptSourceLocator , CompilerConfiguration compilerConfiguration ) {
120
+ this (scriptSourceLocator );
121
+ this .compilerConfiguration = compilerConfiguration ;
122
+ }
123
+
124
+ /**
125
+ * Create a new GroovyScriptFactory for the given script source,
126
+ * specifying a strategy interface that can customize Groovy's compilation
127
+ * process within the underlying GroovyClassLoader.
128
+ * @param scriptSourceLocator a locator that points to the source of the script.
129
+ * Interpreted by the post-processor that actually creates the script.
130
+ * @param compilationCustomizers one or more customizers to be applied to the
131
+ * GroovyClassLoader compiler configuration
132
+ * @since 4.3.3
133
+ * @see CompilerConfiguration#addCompilationCustomizers
134
+ * @see org.codehaus.groovy.control.customizers.ImportCustomizer
135
+ */
136
+ public GroovyScriptFactory (String scriptSourceLocator , CompilationCustomizer ... compilationCustomizers ) {
137
+ this (scriptSourceLocator );
138
+ if (!ObjectUtils .isEmpty (compilationCustomizers )) {
139
+ this .compilerConfiguration = new CompilerConfiguration ();
140
+ this .compilerConfiguration .addCompilationCustomizers (compilationCustomizers );
141
+ }
142
+ }
143
+
102
144
103
145
@ Override
104
146
public void setBeanFactory (BeanFactory beanFactory ) {
@@ -109,7 +151,7 @@ public void setBeanFactory(BeanFactory beanFactory) {
109
151
110
152
@ Override
111
153
public void setBeanClassLoader (ClassLoader classLoader ) {
112
- this .groovyClassLoader = new GroovyClassLoader (classLoader );
154
+ this .groovyClassLoader = buildGroovyClassLoader (classLoader );
113
155
}
114
156
115
157
/**
@@ -118,12 +160,22 @@ public void setBeanClassLoader(ClassLoader classLoader) {
118
160
public GroovyClassLoader getGroovyClassLoader () {
119
161
synchronized (this .scriptClassMonitor ) {
120
162
if (this .groovyClassLoader == null ) {
121
- this .groovyClassLoader = new GroovyClassLoader (ClassUtils .getDefaultClassLoader ());
163
+ this .groovyClassLoader = buildGroovyClassLoader (ClassUtils .getDefaultClassLoader ());
122
164
}
123
165
return this .groovyClassLoader ;
124
166
}
125
167
}
126
168
169
+ /**
170
+ * Build a {@link GroovyClassLoader} for the given {@code ClassLoader}.
171
+ * @param classLoader the ClassLoader to build a GroovyClassLoader for
172
+ * @since 4.3.3
173
+ */
174
+ protected GroovyClassLoader buildGroovyClassLoader (ClassLoader classLoader ) {
175
+ return (this .compilerConfiguration != null ?
176
+ new GroovyClassLoader (classLoader , this .compilerConfiguration ) : new GroovyClassLoader (classLoader ));
177
+ }
178
+
127
179
128
180
@ Override
129
181
public String getScriptSourceLocator () {
0 commit comments