mirror of
https://github.com/spring-projects/spring-boot.git
synced 2024-07-05 00:56:58 +08:00
[bs-73] Anonymous classes cannot be used in @Bean definitions in .groovy scripts
* Added a test for each of the classes loaded by the SpringApplication * If it's an anonymous class or looks like a Groovy closure we ignore it * The CLI sample job.groovy also modified to take advantage [Fixes #48718891]
This commit is contained in:
parent
737886e4da
commit
a2d328ae3a
2
pom.xml
2
pom.xml
@ -252,7 +252,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.codehaus.groovy</groupId>
|
<groupId>org.codehaus.groovy</groupId>
|
||||||
<artifactId>groovy</artifactId>
|
<artifactId>groovy</artifactId>
|
||||||
<version>2.1.2</version>
|
<version>2.1.3</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.eclipse.jetty</groupId>
|
<groupId>org.eclipse.jetty</groupId>
|
||||||
|
@ -14,7 +14,12 @@ class JobConfig {
|
|||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
protected Tasklet tasklet() {
|
protected Tasklet tasklet() {
|
||||||
return new SampleTasklet()
|
return new Tasklet() {
|
||||||
|
@Override
|
||||||
|
RepeatStatus execute(StepContribution contribution, ChunkContext context) {
|
||||||
|
return RepeatStatus.FINISHED
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@ -28,13 +33,6 @@ class JobConfig {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class SampleTasklet implements Tasklet {
|
|
||||||
@Override
|
|
||||||
RepeatStatus execute(StepContribution contribution, ChunkContext context) {
|
|
||||||
return RepeatStatus.FINISHED
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
import org.springframework.util.StringUtils
|
import org.springframework.util.StringUtils
|
||||||
import groovy.util.logging.Log
|
import groovy.util.logging.Log
|
||||||
|
|
||||||
|
@ -34,6 +34,10 @@ import org.apache.ivy.util.FileUtil;
|
|||||||
*/
|
*/
|
||||||
public class CleanCommand extends OptionParsingCommand {
|
public class CleanCommand extends OptionParsingCommand {
|
||||||
|
|
||||||
|
private static enum Layout {
|
||||||
|
IVY, MAVEN;
|
||||||
|
}
|
||||||
|
|
||||||
private OptionSpec<Void> allOption;
|
private OptionSpec<Void> allOption;
|
||||||
|
|
||||||
public CleanCommand() {
|
public CleanCommand() {
|
||||||
@ -55,28 +59,18 @@ public class CleanCommand extends OptionParsingCommand {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void run(OptionSet options) throws Exception {
|
protected void run(OptionSet options) throws Exception {
|
||||||
|
clean(options, getGrapesHome(options), Layout.IVY);
|
||||||
|
clean(options, getMavenHome(options), Layout.MAVEN);
|
||||||
|
}
|
||||||
|
|
||||||
String dir = System.getenv("GROOVY_HOME");
|
private void clean(OptionSet options, File root, Layout layout) {
|
||||||
String userdir = System.getProperty("user.home");
|
|
||||||
|
|
||||||
File home;
|
if (root == null || !root.exists()) {
|
||||||
if (dir == null || !new File(dir).exists()) {
|
|
||||||
dir = userdir;
|
|
||||||
home = new File(dir, ".groovy");
|
|
||||||
} else {
|
|
||||||
home = new File(dir);
|
|
||||||
}
|
|
||||||
if (dir == null || !new File(dir).exists()) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!home.exists()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
File grapes = new File(home, "grapes");
|
|
||||||
ArrayList<String> specs = new ArrayList<String>(options.nonOptionArguments());
|
ArrayList<String> specs = new ArrayList<String>(options.nonOptionArguments());
|
||||||
if (!specs.contains("org.springframework.bootstrap")) {
|
if (!specs.contains("org.springframework.bootstrap") && layout == Layout.IVY) {
|
||||||
specs.add(0, "org.springframework.bootstrap");
|
specs.add(0, "org.springframework.bootstrap");
|
||||||
}
|
}
|
||||||
for (String spec : specs) {
|
for (String spec : specs) {
|
||||||
@ -86,8 +80,7 @@ public class CleanCommand extends OptionParsingCommand {
|
|||||||
group = spec.substring(0, spec.indexOf(":"));
|
group = spec.substring(0, spec.indexOf(":"));
|
||||||
module = spec.substring(spec.indexOf(":") + 1);
|
module = spec.substring(spec.indexOf(":") + 1);
|
||||||
}
|
}
|
||||||
File file = module == null ? new File(grapes, group) : new File(new File(
|
File file = getModulePath(root, group, module, layout);
|
||||||
grapes, group), module);
|
|
||||||
if (file.exists()) {
|
if (file.exists()) {
|
||||||
if (options.has(this.allOption)
|
if (options.has(this.allOption)
|
||||||
|| group.equals("org.springframework.bootstrap")) {
|
|| group.equals("org.springframework.bootstrap")) {
|
||||||
@ -102,7 +95,52 @@ public class CleanCommand extends OptionParsingCommand {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private File getModulePath(File root, String group, String module, Layout layout) {
|
||||||
|
File parent = root;
|
||||||
|
if (layout == Layout.IVY) {
|
||||||
|
parent = new File(parent, group);
|
||||||
|
} else {
|
||||||
|
for (String path : group.split("\\.")) {
|
||||||
|
parent = new File(parent, path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (module == null) {
|
||||||
|
return parent;
|
||||||
|
}
|
||||||
|
return new File(parent, module);
|
||||||
|
}
|
||||||
|
|
||||||
|
private File getGrapesHome(OptionSet options) {
|
||||||
|
|
||||||
|
String dir = System.getenv("GROOVY_HOME");
|
||||||
|
String userdir = System.getProperty("user.home");
|
||||||
|
|
||||||
|
File home;
|
||||||
|
if (dir == null || !new File(dir).exists()) {
|
||||||
|
dir = userdir;
|
||||||
|
home = new File(dir, ".groovy");
|
||||||
|
} else {
|
||||||
|
home = new File(dir);
|
||||||
|
}
|
||||||
|
if (dir == null || !new File(dir).exists()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
File grapes = new File(home, "grapes");
|
||||||
|
return grapes;
|
||||||
|
}
|
||||||
|
|
||||||
|
private File getMavenHome(OptionSet options) {
|
||||||
|
String dir = System.getProperty("user.home");
|
||||||
|
|
||||||
|
if (dir == null || !new File(dir).exists()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
File home = new File(dir);
|
||||||
|
File grapes = new File(new File(home, ".m2"), "repository");
|
||||||
|
return grapes;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -71,4 +71,4 @@ if $cygwin; then
|
|||||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||||
fi
|
fi
|
||||||
|
|
||||||
${JAVA_HOME}/bin/java -cp "$CLASSPATH" org.springframework.bootstrap.cli.SpringBootstrapCli $*
|
${JAVA_HOME}/bin/java ${JAVA_OPTS} -cp "$CLASSPATH" org.springframework.bootstrap.cli.SpringBootstrapCli $*
|
@ -116,8 +116,12 @@ class BeanDefinitionLoader {
|
|||||||
private int load(Object source) {
|
private int load(Object source) {
|
||||||
Assert.notNull(source, "Source must not be null");
|
Assert.notNull(source, "Source must not be null");
|
||||||
if (source instanceof Class<?>) {
|
if (source instanceof Class<?>) {
|
||||||
this.annotatedReader.register((Class<?>) source);
|
Class<?> type = (Class<?>) source;
|
||||||
return 1;
|
if (isComponent(type)) {
|
||||||
|
this.annotatedReader.register(type);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (source instanceof Resource) {
|
if (source instanceof Resource) {
|
||||||
@ -149,6 +153,15 @@ class BeanDefinitionLoader {
|
|||||||
throw new IllegalArgumentException("Invalid source '" + source + "'");
|
throw new IllegalArgumentException("Invalid source '" + source + "'");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isComponent(Class<?> type) {
|
||||||
|
// Nested anonymous classes are not eligible for registration, nor are groovy
|
||||||
|
// closures
|
||||||
|
if (type.isAnonymousClass() || type.getName().contains("$_closure")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Simple {@link TypeFilter} used to ensure that specified {@link Class} sources are
|
* Simple {@link TypeFilter} used to ensure that specified {@link Class} sources are
|
||||||
* not accidentally re-added during scanning.
|
* not accidentally re-added during scanning.
|
||||||
|
@ -297,11 +297,11 @@ public class SpringApplication {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (context instanceof AbstractApplicationContext) {
|
if (context instanceof AbstractApplicationContext && this.environment != null) {
|
||||||
((AbstractApplicationContext) context).setEnvironment(this.environment);
|
((AbstractApplicationContext) context).setEnvironment(this.environment);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (context instanceof GenericApplicationContext) {
|
if (context instanceof GenericApplicationContext && this.resourceLoader != null) {
|
||||||
((GenericApplicationContext) context).setResourceLoader(this.resourceLoader);
|
((GenericApplicationContext) context).setResourceLoader(this.resourceLoader);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user