Browse Source

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
pull/29310/head
Stephane Nicoll 2 years ago
parent
commit
82a0154bd1
  1. 30
      spring-context/src/main/java/org/springframework/context/aot/AbstractAotProcessor.java
  2. 7
      spring-context/src/main/java/org/springframework/context/aot/ContextAotProcessor.java
  3. 25
      spring-context/src/test/java/org/springframework/context/aot/AotProcessorTests.java
  4. 6
      spring-test/src/main/java/org/springframework/test/context/aot/TestAotProcessor.java

30
spring-context/src/main/java/org/springframework/context/aot/AbstractAotProcessor.java

@ -30,20 +30,28 @@ import org.springframework.util.FileSystemUtils; @@ -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 { @@ -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.
*/

7
spring-context/src/main/java/org/springframework/context/aot/ContextAotProcessor.java

@ -46,7 +46,7 @@ import org.springframework.util.CollectionUtils; @@ -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 { @@ -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 { @@ -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);

25
spring-context/src/test/java/org/springframework/context/aot/AotProcessorTests.java

@ -27,13 +27,26 @@ import static org.assertj.core.api.Assertions.assertThat; @@ -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 { @@ -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();
}
}

6
spring-test/src/main/java/org/springframework/test/context/aot/TestAotProcessor.java

@ -36,7 +36,7 @@ import org.springframework.context.aot.AbstractAotProcessor; @@ -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 { @@ -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;
}
/**

Loading…
Cancel
Save