You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Access to thread-local values should be typically as fast as possible and avoid expensive operations, such as proxy bean creation or invoking a ClassLoader. The observed repetitive call to io.micronaut.core.reflect.ClassUtils.forName() on every access to a @ThreadLocal bean method seems unintentional to me.
I would have assumed accesses to @ThreadLocal annotated beans to perform comparably to classic java.lang.ThreadLocal. However, using a classic java.lang.ThreadLocal is significantly faster.
AbstractInitializableBeanDefinition.getScope() has a specific optimization for SINGLETON_SCOPE. Possibly similar is conceivable for @ThreadLocal. Or hopefully the generated $DateUtils$Definition$Intercepted.getStdDateFormat()
could avoid the whole getProxyTargetBean() chain entirely.
Actual Behaviour
Referring to below example code, every access to the injected @ThreadLocal annotated bean via dateUtils.getStdDateFormat();
attempts to
eventually load "io.micronaut.runtime.context.scope.ThreadLocal.class" from the ClassLoader.
Steps To Reproduce
Given a minimal bean
@io.micronaut.runtime.context.scope.ThreadLocal
public class DateUtils {
private final StdDateFormat stdDateFormat = new StdDateFormat();
public DateFormat getStdDateFormat() {
return stdDateFormat;
}
}
Expected Behavior
Access to thread-local values should be typically as fast as possible and avoid expensive operations, such as proxy bean creation or invoking a ClassLoader. The observed repetitive call to io.micronaut.core.reflect.ClassUtils.forName() on every access to a @ThreadLocal bean method seems unintentional to me.
I would have assumed accesses to @ThreadLocal annotated beans to perform comparably to classic java.lang.ThreadLocal. However, using a classic java.lang.ThreadLocal is significantly faster.
AbstractInitializableBeanDefinition.getScope() has a specific optimization for SINGLETON_SCOPE. Possibly similar is conceivable for @ThreadLocal. Or hopefully the generated $DateUtils$Definition$Intercepted.getStdDateFormat()
could avoid the whole getProxyTargetBean() chain entirely.
Actual Behaviour
Referring to below example code, every access to the injected @ThreadLocal annotated bean via
dateUtils.getStdDateFormat();
attempts to
Steps To Reproduce
Given a minimal bean
consumed via
sees the sequences of logs like
if debug logging is configured for io.micronaut.core.reflect.ClassUtils.
Note that the invocations are all on the same thread.
Stacktrace
with
name "io.micronaut.runtime.context.scope.ThreadLocal" (id=179)
classLoader ClassLoaders$AppClassLoader (id=103)
Environment Information
OpenJDK Runtime Environment Temurin-21.0.5+11 (build 21.0.5+11-LTS)
OpenJDK 64-Bit Server VM Temurin-21.0.5+11 (build 21.0.5+11-LTS, mixed mode, sharing)
Example Application
n/a
Version
4.6.3
The text was updated successfully, but these errors were encountered: