Skip to content

Commit 2b06d45

Browse files
committed
Add Spring Framework AOT support.
1 parent f7b07ed commit 2b06d45

File tree

7 files changed

+227
-9
lines changed

7 files changed

+227
-9
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*
2+
* Copyright 2011-2022 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.neo4j.aot;
17+
18+
import org.springframework.data.neo4j.core.convert.Neo4jSimpleTypes;
19+
20+
import java.util.function.Predicate;
21+
22+
/**
23+
* @author Gerrit Meier
24+
* @since 7.0.0
25+
*/
26+
public class Neo4jAotPredicates {
27+
static final Predicate<Class<?>> IS_SIMPLE_TYPE = Neo4jSimpleTypes.HOLDER::isSimpleType;
28+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
/*
2+
* Copyright 2011-2022 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.neo4j.aot;
17+
18+
import org.springframework.data.domain.ManagedTypes;
19+
20+
import java.util.Arrays;
21+
import java.util.function.Consumer;
22+
23+
/**
24+
* @author Gerrit Meier
25+
* @since 7.0.0
26+
*/
27+
public final class Neo4jManagedTypes implements ManagedTypes {
28+
29+
private final ManagedTypes delegate;
30+
31+
private Neo4jManagedTypes(ManagedTypes types) {
32+
this.delegate = types;
33+
}
34+
35+
/**
36+
* Wraps an existing {@link ManagedTypes} object with {@link Neo4jManagedTypes}.
37+
*/
38+
public static Neo4jManagedTypes from(ManagedTypes managedTypes) {
39+
return new Neo4jManagedTypes(managedTypes);
40+
}
41+
42+
/**
43+
* Factory method used to construct {@link Neo4jManagedTypes} from the given array of {@link Class types}.
44+
*
45+
* @param types array of {@link Class types} used to initialize the {@link ManagedTypes}; must not be {@literal null}.
46+
* @return new instance of {@link Neo4jManagedTypes} initialized from {@link Class types}.
47+
*/
48+
public static Neo4jManagedTypes from(Class<?>... types) {
49+
return fromIterable(Arrays.asList(types));
50+
}
51+
52+
/**
53+
* Factory method used to construct {@link Neo4jManagedTypes} from the given, required {@link Iterable} of
54+
* {@link Class types}.
55+
*
56+
* @param types {@link Iterable} of {@link Class types} used to initialize the {@link ManagedTypes}; must not be
57+
* {@literal null}.
58+
* @return new instance of {@link Neo4jManagedTypes} initialized the given, required {@link Iterable} of {@link Class
59+
* types}.
60+
*/
61+
public static Neo4jManagedTypes fromIterable(Iterable<? extends Class<?>> types) {
62+
return from(ManagedTypes.fromIterable(types));
63+
}
64+
65+
/**
66+
* Factory method to return an empty {@link Neo4jManagedTypes} object.
67+
*
68+
* @return an empty {@link Neo4jManagedTypes} object.
69+
*/
70+
public static Neo4jManagedTypes empty() {
71+
return from(ManagedTypes.empty());
72+
}
73+
74+
@Override
75+
public void forEach(Consumer<Class<?>> action) {
76+
delegate.forEach(action);
77+
}
78+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/*
2+
* Copyright 2011-2022 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.neo4j.aot;
17+
18+
import org.springframework.aot.generate.GenerationContext;
19+
import org.springframework.core.ResolvableType;
20+
import org.springframework.data.aot.ManagedTypesBeanRegistrationAotProcessor;
21+
import org.springframework.data.domain.ManagedTypes;
22+
import org.springframework.lang.Nullable;
23+
import org.springframework.util.ClassUtils;
24+
25+
/**
26+
* @author Gerrit Meier
27+
* @since 7.0.0
28+
*/
29+
public class Neo4jManagedTypesBeanRegistrationAotProcessor extends ManagedTypesBeanRegistrationAotProcessor {
30+
31+
public Neo4jManagedTypesBeanRegistrationAotProcessor() {
32+
setModuleIdentifier("neo4j");
33+
}
34+
35+
@Override
36+
protected boolean isMatch(@Nullable Class<?> beanType, @Nullable String beanName) {
37+
return isNeo4jManagedTypes(beanType) || super.isMatch(beanType, beanName);
38+
}
39+
40+
protected boolean isNeo4jManagedTypes(@Nullable Class<?> beanType) {
41+
return beanType != null && ClassUtils.isAssignable(ManagedTypes.class, beanType);
42+
}
43+
44+
@Override
45+
protected void contributeType(ResolvableType type, GenerationContext generationContext) {
46+
47+
if (Neo4jAotPredicates.IS_SIMPLE_TYPE.test(type.toClass())) {
48+
return;
49+
}
50+
51+
super.contributeType(type, generationContext);
52+
}
53+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/*
2+
* Copyright 2011-2022 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.neo4j.aot;
17+
18+
import org.springframework.aot.hint.MemberCategory;
19+
import org.springframework.aot.hint.RuntimeHints;
20+
import org.springframework.aot.hint.RuntimeHintsRegistrar;
21+
import org.springframework.aot.hint.TypeReference;
22+
import org.springframework.data.neo4j.core.mapping.callback.AfterConvertCallback;
23+
import org.springframework.data.neo4j.core.mapping.callback.BeforeBindCallback;
24+
import org.springframework.data.neo4j.core.schema.GeneratedValue;
25+
import org.springframework.data.neo4j.core.support.UUIDStringGenerator;
26+
import org.springframework.data.neo4j.repository.query.SimpleQueryByExampleExecutor;
27+
import org.springframework.data.neo4j.repository.support.SimpleNeo4jRepository;
28+
import org.springframework.lang.Nullable;
29+
30+
import java.util.Arrays;
31+
32+
/**
33+
* @author Gerrit Meier
34+
* @since 7.0.0
35+
*/
36+
public class Neo4jRuntimeHints implements RuntimeHintsRegistrar {
37+
38+
@Override
39+
public void registerHints(RuntimeHints hints, @Nullable ClassLoader classLoader) {
40+
41+
hints.reflection().registerTypes(
42+
Arrays.asList(
43+
TypeReference.of(SimpleNeo4jRepository.class),
44+
TypeReference.of(SimpleQueryByExampleExecutor.class),
45+
TypeReference.of(BeforeBindCallback.class),
46+
TypeReference.of(AfterConvertCallback.class),
47+
// todo "temporary" fix, should get resolved when defined in @GeneratedValue
48+
TypeReference.of(UUIDStringGenerator.class),
49+
TypeReference.of(GeneratedValue.InternalIdGenerator.class),
50+
TypeReference.of(GeneratedValue.UUIDGenerator.class)
51+
),
52+
builder -> builder.withMembers(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS,
53+
MemberCategory.INVOKE_PUBLIC_METHODS));
54+
}
55+
}

src/main/java/org/springframework/data/neo4j/config/Neo4jAuditingRegistrar.java

+8-9
Original file line numberDiff line numberDiff line change
@@ -15,19 +15,18 @@
1515
*/
1616
package org.springframework.data.neo4j.config;
1717

18-
import java.lang.annotation.Annotation;
19-
2018
import org.springframework.beans.factory.config.BeanDefinition;
2119
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
2220
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
2321
import org.springframework.data.auditing.IsNewAwareAuditingHandler;
2422
import org.springframework.data.auditing.config.AuditingBeanDefinitionRegistrarSupport;
2523
import org.springframework.data.auditing.config.AuditingConfiguration;
2624
import org.springframework.data.config.ParsingUtils;
27-
import org.springframework.data.mapping.context.PersistentEntities;
2825
import org.springframework.data.neo4j.core.mapping.callback.AuditingBeforeBindCallback;
2926
import org.springframework.util.Assert;
3027

28+
import java.lang.annotation.Annotation;
29+
3130
/**
3231
* @author Michael J. Simons
3332
* @soundtrack Iron Maiden - Killers
@@ -62,7 +61,7 @@ protected String getAuditingHandlerBeanName() {
6261
*/
6362
@Override
6463
protected void registerAuditListenerBeanDefinition(BeanDefinition auditingHandlerDefinition,
65-
BeanDefinitionRegistry registry) {
64+
BeanDefinitionRegistry registry) {
6665

6766
Assert.notNull(auditingHandlerDefinition, "BeanDefinition must not be null");
6867
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
@@ -86,11 +85,11 @@ protected BeanDefinitionBuilder getAuditHandlerBeanDefinitionBuilder(AuditingCon
8685

8786
BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(IsNewAwareAuditingHandler.class);
8887

89-
BeanDefinitionBuilder persistentEntities = BeanDefinitionBuilder.genericBeanDefinition(PersistentEntities.class)
90-
.setFactoryMethod("of");
91-
persistentEntities.addConstructorArgReference(MAPPING_CONTEXT_BEAN_NAME);
92-
93-
builder.addConstructorArgValue(persistentEntities.getBeanDefinition());
9488
return configureDefaultAuditHandlerAttributes(configuration, builder);
9589
}
90+
91+
@Override
92+
public void postProcess(BeanDefinitionBuilder builder, AuditingConfiguration configuration, BeanDefinitionRegistry registry) {
93+
builder.setFactoryMethod("from").addConstructorArgReference("neo4jMappingContext");
94+
}
9695
}

src/main/java/org/springframework/data/neo4j/repository/config/Neo4jRepositoryConfigurationExtension.java

+1
Original file line numberDiff line numberDiff line change
@@ -135,4 +135,5 @@ public void postProcess(BeanDefinitionBuilder builder, RepositoryConfigurationSo
135135
builder.addPropertyReference("neo4jMappingContext",
136136
source.getAttribute("neo4jMappingContextRef").orElse(DEFAULT_MAPPING_CONTEXT_BEAN_NAME));
137137
}
138+
138139
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
org.springframework.aot.hint.RuntimeHintsRegistrar=\
2+
org.springframework.data.neo4j.aot.Neo4jRuntimeHints
3+
org.springframework.beans.factory.aot.BeanRegistrationAotProcessor=\
4+
org.springframework.data.neo4j.aot.Neo4jManagedTypesBeanRegistrationAotProcessor

0 commit comments

Comments
 (0)