diff --git a/spring-context/src/main/java/org/springframework/scripting/groovy/GroovyScriptFactory.java b/spring-context/src/main/java/org/springframework/scripting/groovy/GroovyScriptFactory.java index c0b1a5033d..cbade53fbb 100644 --- a/spring-context/src/main/java/org/springframework/scripting/groovy/GroovyScriptFactory.java +++ b/spring-context/src/main/java/org/springframework/scripting/groovy/GroovyScriptFactory.java @@ -24,6 +24,8 @@ import groovy.lang.GroovyObject; import groovy.lang.MetaClass; import groovy.lang.Script; import org.codehaus.groovy.control.CompilationFailedException; +import org.codehaus.groovy.control.CompilerConfiguration; +import org.codehaus.groovy.control.customizers.CompilationCustomizer; import org.springframework.beans.factory.BeanClassLoaderAware; import org.springframework.beans.factory.BeanFactory; @@ -57,7 +59,9 @@ public class GroovyScriptFactory implements ScriptFactory, BeanFactoryAware, Bea private final String scriptSourceLocator; - private final GroovyObjectCustomizer groovyObjectCustomizer; + private GroovyObjectCustomizer groovyObjectCustomizer; + + private CompilerConfiguration compilerConfiguration; private GroovyClassLoader groovyClassLoader; @@ -80,27 +84,46 @@ public class GroovyScriptFactory implements ScriptFactory, BeanFactoryAware, Bea * Interpreted by the post-processor that actually creates the script. */ public GroovyScriptFactory(String scriptSourceLocator) { - this(scriptSourceLocator, null); + Assert.hasText(scriptSourceLocator, "'scriptSourceLocator' must not be empty"); + this.scriptSourceLocator = scriptSourceLocator; } /** * Create a new GroovyScriptFactory for the given script source, * specifying a strategy interface that can create a custom MetaClass * to supply missing methods and otherwise change the behavior of the object. - *
We don't need to specify script interfaces here, since
- * a Groovy script defines its Java interfaces itself.
* @param scriptSourceLocator a locator that points to the source of the script.
* Interpreted by the post-processor that actually creates the script.
* @param groovyObjectCustomizer a customizer that can set a custom metaclass
* or make other changes to the GroovyObject created by this factory
* (may be {@code null})
+ * @see GroovyObjectCustomizer#customize
*/
public GroovyScriptFactory(String scriptSourceLocator, GroovyObjectCustomizer groovyObjectCustomizer) {
- Assert.hasText(scriptSourceLocator, "'scriptSourceLocator' must not be empty");
- this.scriptSourceLocator = scriptSourceLocator;
+ this(scriptSourceLocator);
this.groovyObjectCustomizer = groovyObjectCustomizer;
}
+ /**
+ * Create a new GroovyScriptFactory for the given script source,
+ * specifying a strategy interface that can customize Groovy's compilation
+ * process within the underlying GroovyClassLoader.
+ * @param scriptSourceLocator a locator that points to the source of the script.
+ * Interpreted by the post-processor that actually creates the script.
+ * @param compilationCustomizer a customizer to be applied to the GroovyClassLoader
+ * compiler configuration (may be {@code null})
+ * @since 4.3.3
+ * @see CompilerConfiguration#addCompilationCustomizers
+ * @see org.codehaus.groovy.control.customizers.ImportCustomizer
+ */
+ public GroovyScriptFactory(String scriptSourceLocator, CompilationCustomizer compilationCustomizer) {
+ this(scriptSourceLocator);
+ if (compilationCustomizer != null) {
+ this.compilerConfiguration = new CompilerConfiguration();
+ this.compilerConfiguration.addCompilationCustomizers(compilationCustomizer);
+ }
+ }
+
@Override
public void setBeanFactory(BeanFactory beanFactory) {
@@ -111,7 +134,7 @@ public class GroovyScriptFactory implements ScriptFactory, BeanFactoryAware, Bea
@Override
public void setBeanClassLoader(ClassLoader classLoader) {
- this.groovyClassLoader = new GroovyClassLoader(classLoader);
+ this.groovyClassLoader = buildGroovyClassLoader(classLoader);
}
/**
@@ -120,12 +143,22 @@ public class GroovyScriptFactory implements ScriptFactory, BeanFactoryAware, Bea
public GroovyClassLoader getGroovyClassLoader() {
synchronized (this.scriptClassMonitor) {
if (this.groovyClassLoader == null) {
- this.groovyClassLoader = new GroovyClassLoader(ClassUtils.getDefaultClassLoader());
+ this.groovyClassLoader = buildGroovyClassLoader(ClassUtils.getDefaultClassLoader());
}
return this.groovyClassLoader;
}
}
+ /**
+ * Build a {@link GroovyClassLoader} for the given {@code ClassLoader}.
+ * @param classLoader the ClassLoader to build a GroovyClassLoader for
+ * @since 4.3.3
+ */
+ protected GroovyClassLoader buildGroovyClassLoader(ClassLoader classLoader) {
+ return (this.compilerConfiguration != null ?
+ new GroovyClassLoader(classLoader, this.compilerConfiguration) : new GroovyClassLoader(classLoader));
+ }
+
@Override
public String getScriptSourceLocator() {
diff --git a/spring-context/src/test/java/org/springframework/scripting/groovy/MyImportCustomizer.java b/spring-context/src/test/java/org/springframework/scripting/groovy/MyImportCustomizer.java
new file mode 100644
index 0000000000..24160f5083
--- /dev/null
+++ b/spring-context/src/test/java/org/springframework/scripting/groovy/MyImportCustomizer.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2002-2016 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.scripting.groovy;
+
+import org.codehaus.groovy.control.customizers.ImportCustomizer;
+
+/**
+ * @author Juergen Hoeller
+ */
+public class MyImportCustomizer extends ImportCustomizer {
+
+ public MyImportCustomizer() {
+ addStarImports("org.springframework.scripting.groovy");
+ }
+
+}
diff --git a/spring-context/src/test/resources/org/springframework/scripting/groovy/groovy-with-xsd.xml b/spring-context/src/test/resources/org/springframework/scripting/groovy/groovy-with-xsd.xml
index a573d6a2e0..648464ccec 100644
--- a/spring-context/src/test/resources/org/springframework/scripting/groovy/groovy-with-xsd.xml
+++ b/spring-context/src/test/resources/org/springframework/scripting/groovy/groovy-with-xsd.xml
@@ -2,7 +2,7 @@