42875
Since Bean's InstanceSupplier cannot be used during the AOT process, I added BeanRegistrationAotProcessor to replace it.
If a container's field is inaccessible, the generated code will be:
@Generated
public class GraalmavenApplicationTests__TestContext001_BeanDefinitions {
/**
* Get the bean instance for 'importTestContainer.task.graalmaven.GraalmavenApplicationTests.mongoDbContainer'.
*/
private static MongoDBContainer getMongoDbContainerInstance() {
try {
Class<?> clazz = ClassUtils.forName("task.graalmaven.GraalmavenApplicationTests",
GraalmavenApplicationTests__TestContext001_BeanDefinitions.class.getClassLoader());
Field field = ReflectionUtils.findField(clazz, "mongoDbContainer");
Assert.notNull(field, "Field 'mongoDbContainer' is not found");
ReflectionUtils.makeAccessible(field);
Object container = ReflectionUtils.getField(field, null);
Assert.notNull(container, "Container field 'mongoDbContainer' must not have a null value");
return (MongoDBContainer) container;
} catch (ClassNotFoundException ex) {
throw new RuntimeException(ex);
}
}
/**
* Get the bean definition for 'mongoDbContainer'.
*/
public static BeanDefinition getMongoDbContainerBeanDefinition() {
RootBeanDefinition beanDefinition = new RootBeanDefinition(MongoDBContainer.class);
beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
beanDefinition.setInstanceSupplier(
GraalmavenApplicationTests__TestContext001_BeanDefinitions::getMongoDbContainerInstance);
return beanDefinition;
}
}
If a container's field is accessible, the generated code will be:
@Generated
public class GraalmavenApplicationTests__TestContext001_BeanDefinitions {
/**
* Get the bean definition for 'mongoDbContainer'.
*/
public static BeanDefinition getMongoDbContainerBeanDefinition() {
RootBeanDefinition beanDefinition = new RootBeanDefinition(MyContainer.class);
beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
beanDefinition.setInstanceSupplier(() -> GraalmavenApplicationTests.mongoDbContainer);
return beanDefinition;
}
}
An alternative way is FactoryBean instead of InstanceSupplier.
The target branch is 3.2.x
Comment From: nosan
Unfortunately, handling the bean instance supplier for container fields only addresses
half of the issue. The more problematic part involves handling @DynamicPropertySource
methods. These @DynamicPropertySource methods need to be generated and invoked within
the AOT environment. To achieve this, I introduced
DynamicPropertySourceBeanFactoryInitializationAotProcessor
Comment From: nosan
@philwebb Could I kindly ask you to do a quick review of this PR, and let me know if I'm in the right direction?
Comment From: philwebb
Sorry for the delay @nosan, I haven't had the chance to look in detail at this one yet.
Comment From: nosan
@philwebb No worries! I completely understand that you’ve been focusing on higher-priority tasks.