Home / Class/ SpringApplicationAotProcessor Class — spring-boot Architecture

SpringApplicationAotProcessor Class — spring-boot Architecture

Architecture documentation for the SpringApplicationAotProcessor class in SpringApplicationAotProcessor.java from the spring-boot codebase.

Entity Profile

Relationship Graph

Source Code

core/spring-boot/src/main/java/org/springframework/boot/SpringApplicationAotProcessor.java lines 43–141

public class SpringApplicationAotProcessor extends ContextAotProcessor {

	private final String[] applicationArgs;

	/**
	 * Create a new processor for the specified application and settings.
	 * @param application the application main class
	 * @param settings the general AOT processor settings
	 * @param applicationArgs the arguments to provide to the main method
	 */
	public SpringApplicationAotProcessor(Class<?> application, Settings settings, String[] applicationArgs) {
		super(application, settings);
		this.applicationArgs = applicationArgs;
	}

	@Override
	protected GenericApplicationContext prepareApplicationContext(Class<?> application) {
		return new AotProcessorHook(application).run(() -> {
			Method mainMethod = getMainMethod(application);
			mainMethod.setAccessible(true);
			if (mainMethod.getParameterCount() == 0) {
				ReflectionUtils.invokeMethod(mainMethod, null);
			}
			else {
				ReflectionUtils.invokeMethod(mainMethod, null, new Object[] { this.applicationArgs });
			}
			return Void.class;
		});
	}

	private static Method getMainMethod(Class<?> application) throws Exception {
		try {
			return application.getDeclaredMethod("main", String[].class);
		}
		catch (NoSuchMethodException ex) {
			return application.getDeclaredMethod("main");
		}
	}

	public static void main(String[] args) throws Exception {
		int requiredArgs = 6;
		Assert.state(args.length >= requiredArgs, () -> "Usage: " + SpringApplicationAotProcessor.class.getName()
				+ " <applicationMainClass> <sourceOutput> <resourceOutput> <classOutput> <groupId> <artifactId> <originalArgs...>");
		Class<?> application = Class.forName(args[0]);
		Settings settings = Settings.builder()
			.sourceOutput(Paths.get(args[1]))
			.resourceOutput(Paths.get(args[2]))
			.classOutput(Paths.get(args[3]))
			.groupId((StringUtils.hasText(args[4])) ? args[4] : "unspecified")
			.artifactId(args[5])
			.build();
		String[] applicationArgs = (args.length > requiredArgs) ? Arrays.copyOfRange(args, requiredArgs, args.length)
				: new String[0];
		new SpringApplicationAotProcessor(application, settings, applicationArgs).process();
	}

	/**
	 * {@link SpringApplicationHook} used to capture the {@link ApplicationContext} and
	 * trigger early exit of main method.
	 */
	private static final class AotProcessorHook implements SpringApplicationHook {

		private final Class<?> application;

		private AotProcessorHook(Class<?> application) {
			this.application = application;
		}

		@Override
		public SpringApplicationRunListener getRunListener(SpringApplication application) {
			return new SpringApplicationRunListener() {

				@Override
				public void contextLoaded(ConfigurableApplicationContext context) {
					throw new AbandonedRunException(context);
				}

			};
		}

		private <T> GenericApplicationContext run(ThrowingSupplier<T> action) {
			try {
				SpringApplication.withHook(this, action);
			}
			catch (AbandonedRunException ex) {
				ApplicationContext context = ex.getApplicationContext();
				Assert.state(context instanceof GenericApplicationContext,
						() -> "AOT processing requires a GenericApplicationContext but got a "
								+ ((context != null) ? context.getClass().getName() : "null"));
				return (GenericApplicationContext) context;
			}
			throw new IllegalStateException(
					"No application context available after calling main method of '%s'. Does it run a SpringApplication?"
						.formatted(this.application.getName()));
		}

	}

}

Domain

Analyze Your Own Codebase

Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.

Try Supermodel Free