diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/aot/AutowiredArgumentsCodeGenerator.java b/spring-beans/src/main/java/org/springframework/beans/factory/aot/AutowiredArgumentsCodeGenerator.java index 8a8f152cd7..0afc2419a8 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/aot/AutowiredArgumentsCodeGenerator.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/aot/AutowiredArgumentsCodeGenerator.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2022 the original author or authors. + * Copyright 2002-2024 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. @@ -60,21 +60,18 @@ public class AutowiredArgumentsCodeGenerator { return generateCode(parameterTypes, startIndex, "args"); } - public CodeBlock generateCode(Class[] parameterTypes, int startIndex, - String variableName) { - + public CodeBlock generateCode(Class[] parameterTypes, int startIndex, String variableName) { Assert.notNull(parameterTypes, "'parameterTypes' must not be null"); Assert.notNull(variableName, "'variableName' must not be null"); boolean ambiguous = isAmbiguous(); CodeBlock.Builder code = CodeBlock.builder(); for (int i = startIndex; i < parameterTypes.length; i++) { - code.add((i != startIndex) ? ", " : ""); + code.add(i > startIndex ? ", " : ""); if (!ambiguous) { code.add("$L.get($L)", variableName, i - startIndex); } else { - code.add("$L.get($L, $T.class)", variableName, i - startIndex, - parameterTypes[i]); + code.add("$L.get($L, $T.class)", variableName, i - startIndex, parameterTypes[i]); } } return code.build(); diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/aot/AutowiredFieldValueResolver.java b/spring-beans/src/main/java/org/springframework/beans/factory/aot/AutowiredFieldValueResolver.java index 1c5f68fe90..ca3a30e071 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/aot/AutowiredFieldValueResolver.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/aot/AutowiredFieldValueResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2023 the original author or authors. + * Copyright 2002-2024 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. @@ -58,16 +58,14 @@ public final class AutowiredFieldValueResolver extends AutowiredElementResolver private final boolean required; @Nullable - private final String shortcut; + private final String shortcutBeanName; - private AutowiredFieldValueResolver(String fieldName, boolean required, - @Nullable String shortcut) { - + private AutowiredFieldValueResolver(String fieldName, boolean required, @Nullable String shortcut) { Assert.hasText(fieldName, "'fieldName' must not be empty"); this.fieldName = fieldName; this.required = required; - this.shortcut = shortcut; + this.shortcutBeanName = shortcut; } @@ -97,7 +95,7 @@ public final class AutowiredFieldValueResolver extends AutowiredElementResolver * direct bean name injection shortcut. * @param beanName the bean name to use as a shortcut * @return a new {@link AutowiredFieldValueResolver} instance that uses the - * shortcuts + * given shortcut bean name */ public AutowiredFieldValueResolver withShortcut(String beanName) { return new AutowiredFieldValueResolver(this.fieldName, this.required, beanName); @@ -178,8 +176,8 @@ public final class AutowiredFieldValueResolver extends AutowiredElementResolver ConfigurableBeanFactory beanFactory = registeredBean.getBeanFactory(); DependencyDescriptor descriptor = new DependencyDescriptor(field, this.required); descriptor.setContainingClass(beanClass); - if (this.shortcut != null) { - descriptor = new ShortcutDependencyDescriptor(descriptor, this.shortcut); + if (this.shortcutBeanName != null) { + descriptor = new ShortcutDependencyDescriptor(descriptor, this.shortcutBeanName); } Set autowiredBeanNames = new LinkedHashSet<>(1); TypeConverter typeConverter = beanFactory.getTypeConverter(); diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/aot/AutowiredMethodArgumentsResolver.java b/spring-beans/src/main/java/org/springframework/beans/factory/aot/AutowiredMethodArgumentsResolver.java index e902bee884..e52930dc3d 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/aot/AutowiredMethodArgumentsResolver.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/aot/AutowiredMethodArgumentsResolver.java @@ -63,17 +63,17 @@ public final class AutowiredMethodArgumentsResolver extends AutowiredElementReso private final boolean required; @Nullable - private final String[] shortcuts; + private final String[] shortcutBeanNames; private AutowiredMethodArgumentsResolver(String methodName, Class[] parameterTypes, - boolean required, @Nullable String[] shortcuts) { + boolean required, @Nullable String[] shortcutBeanNames) { Assert.hasText(methodName, "'methodName' must not be empty"); this.methodName = methodName; this.parameterTypes = parameterTypes; this.required = required; - this.shortcuts = shortcuts; + this.shortcutBeanNames = shortcutBeanNames; } @@ -105,7 +105,7 @@ public final class AutowiredMethodArgumentsResolver extends AutowiredElementReso * @param beanNames the bean names to use as shortcuts (aligned with the * method parameters) * @return a new {@link AutowiredMethodArgumentsResolver} instance that uses - * the shortcuts + * the given shortcut bean names */ public AutowiredMethodArgumentsResolver withShortcut(String... beanNames) { return new AutowiredMethodArgumentsResolver(this.methodName, this.parameterTypes, this.required, beanNames); @@ -171,7 +171,7 @@ public final class AutowiredMethodArgumentsResolver extends AutowiredElementReso MethodParameter parameter = new MethodParameter(method, i); DependencyDescriptor descriptor = new DependencyDescriptor(parameter, this.required); descriptor.setContainingClass(beanClass); - String shortcut = (this.shortcuts != null ? this.shortcuts[i] : null); + String shortcut = (this.shortcutBeanNames != null ? this.shortcutBeanNames[i] : null); if (shortcut != null) { descriptor = new ShortcutDependencyDescriptor(descriptor, shortcut); } diff --git a/spring-context/src/test/java/org/springframework/context/aot/ApplicationContextAotGeneratorTests.java b/spring-context/src/test/java/org/springframework/context/aot/ApplicationContextAotGeneratorTests.java index 104d6b0761..01c2ea37b9 100644 --- a/spring-context/src/test/java/org/springframework/context/aot/ApplicationContextAotGeneratorTests.java +++ b/spring-context/src/test/java/org/springframework/context/aot/ApplicationContextAotGeneratorTests.java @@ -644,18 +644,21 @@ class ApplicationContextAotGeneratorTests { private static void testCompiledResult(GenericApplicationContext applicationContext, BiConsumer, Compiled> result) { + testCompiledResult(processAheadOfTime(applicationContext), result); } - @SuppressWarnings({ "rawtypes", "unchecked" }) + @SuppressWarnings("unchecked") private static void testCompiledResult(TestGenerationContext generationContext, BiConsumer, Compiled> result) { + TestCompiler.forSystem().with(generationContext).compile(compiled -> result.accept(compiled.getInstance(ApplicationContextInitializer.class), compiled)); } private static GenericApplicationContext toFreshApplicationContext( ApplicationContextInitializer initializer) { + GenericApplicationContext freshApplicationContext = createFreshApplicationContext(initializer); freshApplicationContext.refresh(); return freshApplicationContext; @@ -663,6 +666,7 @@ class ApplicationContextAotGeneratorTests { private static GenericApplicationContext createFreshApplicationContext( ApplicationContextInitializer initializer) { + GenericApplicationContext freshApplicationContext = new GenericApplicationContext(); initializer.initialize(freshApplicationContext); return freshApplicationContext; diff --git a/spring-core/src/main/java/org/springframework/aot/generate/ValueCodeGenerationException.java b/spring-core/src/main/java/org/springframework/aot/generate/ValueCodeGenerationException.java index 5aaa9ba513..dead0694e4 100644 --- a/spring-core/src/main/java/org/springframework/aot/generate/ValueCodeGenerationException.java +++ b/spring-core/src/main/java/org/springframework/aot/generate/ValueCodeGenerationException.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2023 the original author or authors. + * Copyright 2002-2024 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. @@ -30,6 +30,7 @@ public class ValueCodeGenerationException extends RuntimeException { @Nullable private final Object value; + protected ValueCodeGenerationException(String message, @Nullable Object value, @Nullable Throwable cause) { super(message, cause); this.value = value; @@ -49,9 +50,9 @@ public class ValueCodeGenerationException extends RuntimeException { return message.toString(); } + /** * Return the value that failed to be generated. - * @return the value */ @Nullable public Object getValue() { diff --git a/spring-core/src/main/java/org/springframework/aot/generate/ValueCodeGenerator.java b/spring-core/src/main/java/org/springframework/aot/generate/ValueCodeGenerator.java index 61008f5aa2..b30b1acff1 100644 --- a/spring-core/src/main/java/org/springframework/aot/generate/ValueCodeGenerator.java +++ b/spring-core/src/main/java/org/springframework/aot/generate/ValueCodeGenerator.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2023 the original author or authors. + * Copyright 2002-2024 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. @@ -33,20 +33,24 @@ import org.springframework.util.Assert; */ public final class ValueCodeGenerator { - private static final ValueCodeGenerator INSTANCE = new ValueCodeGenerator(ValueCodeGeneratorDelegates.INSTANCES, null); + private static final ValueCodeGenerator INSTANCE = + new ValueCodeGenerator(ValueCodeGeneratorDelegates.INSTANCES, null); private static final CodeBlock NULL_VALUE_CODE_BLOCK = CodeBlock.of("null"); + private final List delegates; @Nullable private final GeneratedMethods generatedMethods; + private ValueCodeGenerator(List delegates, @Nullable GeneratedMethods generatedMethods) { this.delegates = delegates; this.generatedMethods = generatedMethods; } + /** * Return an instance that provides support for {@linkplain * ValueCodeGeneratorDelegates#INSTANCES common value types}. @@ -75,6 +79,7 @@ public final class ValueCodeGenerator { return new ValueCodeGenerator(new ArrayList<>(delegates), null); } + public ValueCodeGenerator add(List additionalDelegates) { Assert.notEmpty(additionalDelegates, "AdditionalDelegates must not be empty"); List allDelegates = new ArrayList<>(this.delegates); @@ -117,7 +122,6 @@ public final class ValueCodeGenerator { } } - /** * Return the {@link GeneratedMethods} that represents the scope * in which code generated by this instance will be added, or @@ -129,6 +133,7 @@ public final class ValueCodeGenerator { return this.generatedMethods; } + /** * Strategy interface that can be used to implement code generation for a * particular value type. @@ -146,7 +151,6 @@ public final class ValueCodeGenerator { */ @Nullable CodeBlock generateCode(ValueCodeGenerator valueCodeGenerator, Object value); - } }