Handle init callbacks #1059
Handle init callbacks #1059
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the PR. I've made a few comments. Looking at it a bit closed, I've realized what I've postponed should really happen now (injection of properties).
If we merge this, we'd call post construct before the properties are actually injected :(
@@ -47,12 +48,15 @@ | |||
|
|||
private final List<PropertyDescriptor> properties; | |||
|
|||
private final List<InitializationCallback> initializationCallbacks; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Having looked at the end result, I think this should rather be a MemberDescriptor<Method>
. This way we can move the code generation to the writer and the reflection configuration can be provided based on the descriptor.
/** | ||
* Wraps the code that's necessary to invoce initialization (post construct) methods if any. | ||
*/ | ||
public static class InitializationCallback { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As a result this could go away.
|
||
List<InitializationCallback> detectInstanceCallbacks(BeanDefinition beanDefinition) { | ||
|
||
if(!(beanDefinition instanceof RootBeanDefinition)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about getInitMethodName
? The idea is to honor all init method we know about. It should be this, and then any externally managed, if any.
|
||
private static final Field EXTERNALLY_MANAGED_INIT_METHODS; | ||
|
||
static { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure the optimization is worth it. We could have a method that would give us back the list based on a bean definition and hide all that reflection hackery there.
|
||
List<InitializationCallback> callbacks = new ArrayList<>(); | ||
Class<?> targetType = beanDefinition.getResolvableType().toClass(); | ||
for (Object initMethodName : (Iterable<? extends Object>) field) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should rather put everything in a LinkedHashSet
and iterate over it, to avoid cases where something is both detected by an initMethodName, and also annotated.
return callbacks; | ||
} | ||
|
||
private InitializationCallback getInitMethodCallback(Method initMethod) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This code can move to DefaultBeanInstanceSupplierWriter
.
@@ -44,16 +50,12 @@ | |||
import org.springframework.nativex.type.TypeSystem; | |||
import org.springframework.util.ClassUtils; | |||
|
|||
import static org.springframework.context.bootstrap.generator.infrastructure.nativex.NativeConfigurationRegistry.InitializationConfiguration; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know we don't have a consistent code style at the moment but can you please re-read the commit to avoid such unrelated changes?
@@ -62,6 +64,7 @@ | |||
@Override | |||
public void process(BeanInstanceDescriptor descriptor, NativeConfigurationRegistry registry) { | |||
findAndRegisterRelevantNativeHints(descriptor.getUserBeanClass(), registry); | |||
registerReflectionForInitializtionMethodsIfNecessary(descriptor, registry); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not the right place for this. This should go in DefaultBeanNativeConfigurationProcessor
.
* | ||
* @author Christoph Strobl | ||
*/ | ||
class InitializationCallbacksSupplierTests { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need more tests here, in particular with initMethodName
.
With the help of @jhoeller, we'll be able to reduce reflection access once spring-projects/spring-framework#27449 is done. |
This commit introduces support for detecting and calling bean initialization (post construct) methods. Public, protected and package private init methods will be called directly, however private ones require reflection and register addition reflection configuration.
Update comments, tests, etc.
513a10d
to
031cc71
Compare
I removed the version assigned since #1048 also covers it. |
I am going to review and merge this hopefully by M1. The other one is (partially) superseded by this one anyway. |
This commit introduces support for detecting and calling bean initialization (post construct) methods. See gh-1059
Rather than invoking the initialization callback as part of the instance supplier, we should rather post-process the bean so that we can provide the same ordering as the regular runtime. See gh-1059
This commit rework the original proposal by writing the init and destroy methods and using them to instantiate a dedicated bean post processor that is similar to the original one used at runtime. Both method names defined on the bean definition itself as well as externally managed ones are supported. If the bean name is '(inferred)' similar logic is applied at build time. Closes gh-1048 See gh-1059
* pr/1059: Invoke init and destroy callbacks Polish "Handle bean initialization methods" Handle bean initialization methods Closes gh-1059
Merged by 1f96ae9 |
This commit introduces support for detecting and calling bean initialization (post construct) methods. See gh-1059
Rather than invoking the initialization callback as part of the instance supplier, we should rather post-process the bean so that we can provide the same ordering as the regular runtime. See gh-1059
This commit rework the original proposal by writing the init and destroy methods and using them to instantiate a dedicated bean post processor that is similar to the original one used at runtime. Both method names defined on the bean definition itself as well as externally managed ones are supported. If the bean name is '(inferred)' similar logic is applied at build time. Closes gh-1048 See gh-1059
This PR introduces support for detecting and calling bean initialization (post construct) methods.
Public, protected and package private init methods will be called directly, however private ones require addition reflection configuration.