Skip to content
This repository was archived by the owner on Feb 23, 2023. It is now read-only.

Commit 384d8ca

Browse files
committed
Delete remaining special processing in ResourcesHandler
The remaining messy code in ResourcesHandler processSpringComponent has migrated into a more straightforward IndexedBeanHierarchyNativeConfigurationProcessor.
1 parent f8ca8e0 commit 384d8ca

File tree

9 files changed

+205
-721
lines changed

9 files changed

+205
-721
lines changed

samples/hibernate/src/main/java/app/main/SampleApplication.java

+6-5
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,22 @@
11
package app.main;
22

3+
import static org.springframework.web.servlet.function.RouterFunctions.route;
4+
import static org.springframework.web.servlet.function.ServerResponse.ok;
5+
36
import javax.persistence.EntityManager;
47
import javax.persistence.PersistenceContext;
58
import javax.transaction.Transactional;
69

7-
import app.main.Foo;
8-
910
import org.springframework.boot.CommandLineRunner;
1011
import org.springframework.boot.SpringApplication;
1112
import org.springframework.boot.autoconfigure.SpringBootApplication;
1213
import org.springframework.context.annotation.Bean;
14+
import org.springframework.nativex.hint.TypeHint;
15+
import org.springframework.nativex.hint.TypeAccess;
1316
import org.springframework.stereotype.Component;
1417
import org.springframework.web.servlet.function.RouterFunction;
1518

16-
import static org.springframework.web.servlet.function.RouterFunctions.route;
17-
import static org.springframework.web.servlet.function.ServerResponse.ok;
18-
19+
@TypeHint(types = Foo.class, access={TypeAccess.DECLARED_CONSTRUCTORS, TypeAccess.DECLARED_FIELDS, TypeAccess.PUBLIC_METHODS})
1920
@SpringBootApplication
2021
public class SampleApplication {
2122

spring-aot/src/main/java/org/springframework/aot/context/bootstrap/generator/infrastructure/nativex/NativeConfigurationUtils.java

+11
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,17 @@ public static Set<Class<?>> collectTypesInSignature(Method controllerMethod) {
6363
return collector;
6464
}
6565

66+
public static Set<Class<?>> collectTypesInSignature(Class<?> clazz) {
67+
Set<Class<?>> collector = new TreeSet<>((c1,c2) -> c1.getName().compareTo(c2.getName()));
68+
Type genericSuperclass = clazz.getGenericSuperclass();
69+
collectReferenceTypesUsed(genericSuperclass, collector);
70+
Type[] genericInterfaces = clazz.getGenericInterfaces();
71+
for (Type genericInterface: genericInterfaces) {
72+
collectReferenceTypesUsed(genericInterface, collector);
73+
}
74+
return collector;
75+
}
76+
6677
// TODO does this handle all relevant cases?
6778
public static void collectReferenceTypesUsed(Type type, Set<Class<?>> collector) {
6879
if (type instanceof GenericArrayType) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
/*
2+
* Copyright 2019-2021 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+
17+
package org.springframework.core;
18+
19+
import java.lang.reflect.Type;
20+
import java.util.HashSet;
21+
import java.util.Set;
22+
import java.util.TreeSet;
23+
24+
import org.apache.commons.logging.Log;
25+
import org.apache.commons.logging.LogFactory;
26+
import org.springframework.aot.context.bootstrap.generator.infrastructure.nativex.BeanFactoryNativeConfigurationProcessor;
27+
import org.springframework.aot.context.bootstrap.generator.infrastructure.nativex.NativeConfigurationRegistry;
28+
import org.springframework.aot.context.bootstrap.generator.infrastructure.nativex.NativeConfigurationUtils;
29+
import org.springframework.aot.support.BeanFactoryProcessor;
30+
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
31+
import org.springframework.boot.context.properties.ConfigurationProperties;
32+
import org.springframework.context.annotation.Configuration;
33+
import org.springframework.core.annotation.MergedAnnotations;
34+
import org.springframework.nativex.hint.TypeAccess;
35+
import org.springframework.stereotype.Component;
36+
import org.springframework.stereotype.Indexed;
37+
import org.springframework.validation.annotation.Validated;
38+
39+
/**
40+
* Register as much of the hierarchy of {@link Indexed} marked beans as is required.
41+
*
42+
* @author Andy Clement
43+
*/
44+
public class IndexedBeanHierarchyNativeConfigurationProcessor implements BeanFactoryNativeConfigurationProcessor {
45+
46+
private static Log logger = LogFactory.getLog(IndexedBeanHierarchyNativeConfigurationProcessor.class);
47+
48+
@Override
49+
public void process(ConfigurableListableBeanFactory beanFactory, NativeConfigurationRegistry registry) {
50+
new BeanFactoryProcessor(beanFactory).processBeansWithAnnotation(Indexed.class,
51+
(beanName, beanType) -> {
52+
MergedAnnotations mas = MergedAnnotations.from(beanType);
53+
if (mas.isPresent(ConfigurationProperties.class) && mas.isPresent(Validated.class)) {
54+
logger.debug("adding basic reflection configuration for @Validated @ConfigurationProperties bean "+beanType.getName());
55+
registry.reflection().forType(beanType).withAccess(TypeAccess.DECLARED_CONSTRUCTORS,TypeAccess.DECLARED_METHODS,TypeAccess.DECLARED_CLASSES,TypeAccess.DECLARED_FIELDS);
56+
} else if (mas.isPresent(Component.class) && !mas.isPresent(Configuration.class)) {
57+
// TODO there is no doubt further optimizations here and certain types of component will need subsets of this behaviour
58+
// (which could be pushed into the related NativeConfigurationProcessors - for example web components typically only
59+
// need reflective access to the methods that host web related annotations in the hierarchy)
60+
walkTypeAndRegisterReflection(beanType, registry, new HashSet<>());
61+
}
62+
});
63+
}
64+
65+
public void walkTypeAndRegisterReflection(Class<?> type, NativeConfigurationRegistry registry, Set<Class<?>> visited) {
66+
if (!visited.add(type)) {
67+
return;
68+
}
69+
registry.reflection().forType(type).withAccess(TypeAccess.DECLARED_METHODS);
70+
Set<Class<?>> collector = new TreeSet<>((c1,c2) -> c1.getName().compareTo(c2.getName()));
71+
Type genericSuperclass = type.getGenericSuperclass();
72+
NativeConfigurationUtils.collectReferenceTypesUsed(genericSuperclass, collector);
73+
Type[] genericInterfaces = type.getGenericInterfaces();
74+
for (Type genericInterface: genericInterfaces) {
75+
NativeConfigurationUtils.collectReferenceTypesUsed(genericInterface, collector);
76+
}
77+
for (Class<?> sigtype: collector) {
78+
walkTypeAndRegisterReflection(sigtype, registry, visited);
79+
}
80+
}
81+
82+
}

spring-aot/src/main/java/org/springframework/data/RepositoryDefinitionConfigurationProcessor.java

+2
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,8 @@ private void writeRepositoryInterfaceConfiguration(RepositoryConfiguration confi
269269
}
270270
// Kotlin repo
271271
if (configuration.isKotlinRepository()) {
272+
registry.reflection().forType(CoroutineCrudRepository.class).withAccess(TypeAccess.PUBLIC_METHODS);
273+
registry.reflection().forType(Repository.class).withAccess(TypeAccess.PUBLIC_METHODS);
272274
registry.reflection().forType(Iterable.class).withAccess(TypeAccess.QUERY_PUBLIC_METHODS);
273275
safelyRegister("kotlinx.coroutines.flow.Flow", TypeAccess.QUERY_PUBLIC_METHODS);
274276
safelyRegister("kotlin.collections.Iterable", TypeAccess.QUERY_PUBLIC_METHODS);

spring-aot/src/main/java/org/springframework/nativex/support/RequestedConfigurationManager.java

-234
This file was deleted.

0 commit comments

Comments
 (0)