More investigations on this issue.
At runtime, the injected "ObjectFactory" (private ObjectFactory<MyBean> myBeanFactory) is an instance of DependencyObjectFactory.
It is injected in resolveDependency method of DefaultListableBeanFactory.
The constructor of DependencyObjectFactory takes a descriptor of the field (Field type (ObjectFactory<MyBean>), field name...) and the "beanName", which is actually the name of the bean in which the injection is made.
The constructor of DependencyObjectFactory extract the class that must be generated by the factory in the field descriptor using reflection:
ObjectFactory<MyBean> -> MyBean
Then the getObject method of DependencyObjectFactory is simply implemented as follow:
Code:
public Object getObject() throws BeansException {
return doResolveDependency(this.descriptor, this.type, this.beanName, null, null);
}
Nothing is cached. Each time getObject is called then doResolveDependency is called.
As MyBean is not an array, a map or anything, doResolveDependency is calling findAutowireCandidates.
Then findAutowireCandidates is calling BeanFactoryUtils.beanNamesForTypeIncludingAncestor s.
beanNamesForTypeIncludingAncestors find beans names that corresponds to the requested type.
MyBean class -> "myBean" string.
This is a very time consuming operation in our case (See profiler result in my previous message).
Then, with the result of beanNamesForTypeIncludingAncestors, findAutowireCandidates create a Map<String, Object>.
The string key contains the name of the bean.
The value is the an instance corresponding to the bean name.
The instance is created using getBean, so:
beanFactory.getBean("myBean").
This is why dedicated factories are really slower than using getBean with a bean name.
Dedicated factories are first finding the bean name from the type, which is slow.
Then they are calling the getBean method.
To be as fast as getbean(String), DependencyObjectFactory should call beanNamesForTypeIncludingAncestors only once and cache the result (The bean name) as a field of DependencyObjectFactory.
Then it would call getBean with this cached information.
But DependencyObjectFactory should be even faster than getBean.
It should cache more information about the bean that must be created (For example it could cache RootBeanDefinition and call createBean. But it may be deeper than that.).