Skip to content

Commit 65f14fd

Browse files
Enable AOT repositories by default.
1 parent add1d08 commit 65f14fd

File tree

2 files changed

+124
-1
lines changed

2 files changed

+124
-1
lines changed

src/main/java/org/springframework/data/aot/AotContext.java

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,12 @@
1818
import java.lang.annotation.Annotation;
1919
import java.util.Collection;
2020
import java.util.List;
21+
import java.util.Locale;
2122
import java.util.Optional;
2223
import java.util.Set;
2324
import java.util.function.Consumer;
2425

2526
import org.jspecify.annotations.Nullable;
26-
2727
import org.springframework.beans.factory.BeanFactory;
2828
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
2929
import org.springframework.beans.factory.config.BeanDefinition;
@@ -35,6 +35,7 @@
3535
import org.springframework.core.env.StandardEnvironment;
3636
import org.springframework.data.util.TypeScanner;
3737
import org.springframework.util.Assert;
38+
import org.springframework.util.StringUtils;
3839

3940
/**
4041
* The context in which the AOT processing happens. Grants access to the {@link ConfigurableListableBeanFactory
@@ -84,6 +85,37 @@ static AotContext from(BeanFactory beanFactory, Environment environment) {
8485
return new DefaultAotContext(beanFactory, environment);
8586
}
8687

88+
/**
89+
* Checks if repository code generation is enabled for a given module by checking environment variables for general
90+
* enablement ({@link #GENERATED_REPOSITORIES_ENABLED}) and store specific ones following the pattern
91+
* {@literal spring.aot.repositories.<module-name>.enabled}.
92+
* <p>
93+
* {@link #GENERATED_REPOSITORIES_ENABLED} acts as a kill switch, if disabled, store specific flags have no effect.
94+
* <p>
95+
* Missing properties are interpreted as {@literal true}.
96+
*
97+
* @param moduleName The name of the module. Can be {@literal null} or {@literal empty}, in which case it will only
98+
* check the general {@link #GENERATED_REPOSITORIES_ENABLED} flag.
99+
* @return indicator if repository code generation is enabled.
100+
* @since 5.0
101+
*/
102+
default boolean isGeneratedRepositoriesEnabled(@Nullable String moduleName) {
103+
104+
Environment environment = getEnvironment();
105+
Boolean codeGenerationEnabled = environment.getProperty(GENERATED_REPOSITORIES_ENABLED, Boolean.class, true);
106+
if (!codeGenerationEnabled) {
107+
return false;
108+
}
109+
110+
if (!StringUtils.hasText(moduleName)) {
111+
return true;
112+
}
113+
114+
String modulePropertyName = GENERATED_REPOSITORIES_ENABLED.replace("enabled",
115+
"%s.enabled".formatted(moduleName.toLowerCase(Locale.US)));
116+
return environment.getProperty(modulePropertyName, Boolean.class, true);
117+
}
118+
87119
/**
88120
* Returns a reference to the {@link ConfigurableListableBeanFactory} backing this {@link AotContext}.
89121
*
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
/*
2+
* Copyright 2025 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.data.aot;
17+
18+
import org.assertj.core.api.Assertions;
19+
import org.junit.jupiter.params.ParameterizedTest;
20+
import org.junit.jupiter.params.provider.CsvSource;
21+
import org.mockito.Mockito;
22+
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
23+
import org.springframework.core.env.Environment;
24+
import org.springframework.mock.env.MockEnvironment;
25+
import org.springframework.util.StringUtils;
26+
27+
/**
28+
* Tests for {@link AotContext}.
29+
*
30+
* @author Christoph Strobl
31+
*/
32+
class AotContextUnitTests {
33+
34+
@ParameterizedTest // GH-3322
35+
@CsvSource({ //
36+
"'spring.aot.repositories.enabled', '', '', '', true", //
37+
"'spring.aot.repositories.enabled', 'true', '', '', true", //
38+
"'spring.aot.repositories.enabled', 'false', '', '', false", //
39+
"'spring.aot.repositories.enabled', '', 'commons', 'true', true", //
40+
"'spring.aot.repositories.enabled', 'true', 'commons', 'true', true", //
41+
"'spring.aot.repositories.enabled', '', 'commons', 'false', false", //
42+
"'spring.aot.repositories.enabled', 'false', 'commons', 'true', false" //
43+
})
44+
void considersEnvironmentSettingsForGeneratedRepositories(String generalFlag, String generalValue, String storeName,
45+
String storeValue, boolean enabled) {
46+
47+
MockAotContext ctx = new MockAotContext();
48+
if (StringUtils.hasText(generalFlag) && StringUtils.hasText(generalValue)) {
49+
ctx.withProperty(generalFlag, generalValue);
50+
}
51+
if (StringUtils.hasText(storeName) && StringUtils.hasText(storeValue)) {
52+
ctx.withProperty("spring.aot.repositories.%s.enabled".formatted(storeName), storeValue);
53+
}
54+
55+
Assertions.assertThat(ctx.isGeneratedRepositoriesEnabled(storeName)).isEqualTo(enabled);
56+
}
57+
58+
class MockAotContext implements AotContext {
59+
60+
private final MockEnvironment environment;
61+
62+
public MockAotContext() {
63+
this.environment = new MockEnvironment();
64+
}
65+
66+
MockAotContext withProperty(String key, String value) {
67+
environment.setProperty(key, value);
68+
return this;
69+
}
70+
71+
@Override
72+
public ConfigurableListableBeanFactory getBeanFactory() {
73+
return Mockito.mock(ConfigurableListableBeanFactory.class);
74+
}
75+
76+
@Override
77+
public TypeIntrospector introspectType(String typeName) {
78+
return Mockito.mock(TypeIntrospector.class);
79+
}
80+
81+
@Override
82+
public IntrospectedBeanDefinition introspectBeanDefinition(String beanName) {
83+
return Mockito.mock(IntrospectedBeanDefinition.class);
84+
}
85+
86+
@Override
87+
public Environment getEnvironment() {
88+
return environment;
89+
}
90+
}
91+
}

0 commit comments

Comments
 (0)