Expose a system property when AOT processing is running
This commit exposes a "spring.aot.processing" system property when the AOT engine is running. This can be used by code that need to react differently when the application is being refreshed for AOT processing. Closes gh-29340
This commit is contained in:
@@ -30,20 +30,28 @@ import org.springframework.util.FileSystemUtils;
|
||||
/**
|
||||
* Abstract base class for filesystem-based ahead-of-time (AOT) processing.
|
||||
*
|
||||
* <p>Concrete implementations are typically used to kick off optimization of an
|
||||
* application or test suite in a build tool.
|
||||
* <p>Concrete implementations should override {@link #doProcess()} that kicks
|
||||
* off the optimization of the target, usually an application.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
* @author Andy Wilkinson
|
||||
* @author Phillip Webb
|
||||
* @author Sam Brannen
|
||||
* @since 6.0
|
||||
* @param <T> the type of the processing result
|
||||
* @see FileSystemGeneratedFiles
|
||||
* @see FileNativeConfigurationWriter
|
||||
* @see org.springframework.context.aot.ContextAotProcessor
|
||||
* @see org.springframework.test.context.aot.TestAotProcessor
|
||||
*/
|
||||
public abstract class AbstractAotProcessor {
|
||||
public abstract class AbstractAotProcessor<T> {
|
||||
|
||||
/**
|
||||
* The name of a system property that is made available when the processor
|
||||
* runs.
|
||||
* @see #doProcess()
|
||||
*/
|
||||
private static final String AOT_PROCESSING = "spring.aot.processing";
|
||||
|
||||
private final Settings settings;
|
||||
|
||||
@@ -64,6 +72,22 @@ public abstract class AbstractAotProcessor {
|
||||
return this.settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Run AOT processing.
|
||||
* @return the result of the processing.
|
||||
*/
|
||||
public final T process() {
|
||||
try {
|
||||
System.setProperty(AOT_PROCESSING, "true");
|
||||
return doProcess();
|
||||
}
|
||||
finally {
|
||||
System.clearProperty(AOT_PROCESSING);
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract T doProcess();
|
||||
|
||||
/**
|
||||
* Delete the source, resource, and class output directories.
|
||||
*/
|
||||
|
||||
@@ -46,7 +46,7 @@ import org.springframework.util.CollectionUtils;
|
||||
* @since 6.0
|
||||
* @see org.springframework.test.context.aot.TestAotProcessor
|
||||
*/
|
||||
public abstract class ContextAotProcessor extends AbstractAotProcessor {
|
||||
public abstract class ContextAotProcessor extends AbstractAotProcessor<ClassName> {
|
||||
|
||||
private final Class<?> applicationClass;
|
||||
|
||||
@@ -64,7 +64,7 @@ public abstract class ContextAotProcessor extends AbstractAotProcessor {
|
||||
|
||||
|
||||
/**
|
||||
* Get the the application entry point (typically a class with a {@code main()} method).
|
||||
* Get the application entry point (typically a class with a {@code main()} method).
|
||||
*/
|
||||
protected Class<?> getApplicationClass() {
|
||||
return this.applicationClass;
|
||||
@@ -77,7 +77,8 @@ public abstract class ContextAotProcessor extends AbstractAotProcessor {
|
||||
* @return the {@code ClassName} of the {@code ApplicationContextInitializer}
|
||||
* entry point
|
||||
*/
|
||||
public ClassName process() {
|
||||
@Override
|
||||
protected ClassName doProcess() {
|
||||
deleteExistingOutput();
|
||||
GenericApplicationContext applicationContext = prepareApplicationContext(getApplicationClass());
|
||||
return performAotProcessing(applicationContext);
|
||||
|
||||
@@ -27,13 +27,26 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
||||
|
||||
/**
|
||||
* Tests for {@link AbstractAotProcessor}, settings, and builder.
|
||||
* Tests for {@link AbstractAotProcessor}.
|
||||
*
|
||||
* @author Sam Brannen
|
||||
* @author Stephane Nicoll
|
||||
* @since 6.0
|
||||
*/
|
||||
class AotProcessorTests {
|
||||
|
||||
@Test
|
||||
void springAotProcessingIsAvailableInDoProcess(@TempDir Path tempDir) {
|
||||
Settings settings = createTestSettings(tempDir);
|
||||
assertThat(new AbstractAotProcessor<String>(settings) {
|
||||
@Override
|
||||
protected String doProcess() {
|
||||
assertThat(System.getProperty("spring.aot.processing")).isEqualTo("true");
|
||||
return "Hello";
|
||||
}
|
||||
}.process()).isEqualTo("Hello");
|
||||
}
|
||||
|
||||
@Test
|
||||
void builderRejectsMissingSourceOutput() {
|
||||
assertThatIllegalArgumentException()
|
||||
@@ -123,4 +136,14 @@ class AotProcessorTests {
|
||||
assertThat(settings.getArtifactId()).isEqualTo("my-artifact");
|
||||
}
|
||||
|
||||
private static Settings createTestSettings(Path tempDir) {
|
||||
return Settings.builder()
|
||||
.sourceOutput(tempDir)
|
||||
.resourceOutput(tempDir)
|
||||
.classOutput(tempDir)
|
||||
.groupId("my-group")
|
||||
.artifactId("my-artifact")
|
||||
.build();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ import org.springframework.context.aot.AbstractAotProcessor;
|
||||
* @see TestContextAotGenerator
|
||||
* @see org.springframework.context.aot.ContextAotProcessor
|
||||
*/
|
||||
public abstract class TestAotProcessor extends AbstractAotProcessor {
|
||||
public abstract class TestAotProcessor extends AbstractAotProcessor<Void> {
|
||||
|
||||
private final Set<Path> classpathRoots;
|
||||
|
||||
@@ -66,9 +66,11 @@ public abstract class TestAotProcessor extends AbstractAotProcessor {
|
||||
* {@linkplain #deleteExistingOutput() clearing output directories} first and
|
||||
* then {@linkplain #performAotProcessing() performing AOT processing}.
|
||||
*/
|
||||
public void process() {
|
||||
@Override
|
||||
protected Void doProcess() {
|
||||
deleteExistingOutput();
|
||||
performAotProcessing();
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user