Basically, the BeanFactory is both a Warehouse and a Factory.
Spring references beans by the names given to them as part of their definitions, either as annotations or via a resource such as the ApplicationContext.xml file. When something asks for that bean, the Warehouse part is checked first. Warehouse is essential a Map where the bean name is the key and the bean instance is the value. If it's in-warehouse, then the bean instance is returned.
If not, the Factory part kicks in. The Factory attempts to manufacture (instantiate) an instance of the bean. If successful, the instance is stored in the Warehouse AND returned to the requester,
Of course, there are additional complexities. The easiest way to manufacture a Bean is to invoke the no-argument constructor for that Bean (as defined, see above). However, Spring is smart, so it can also invoke constructors with arguments, as long as a suitable definition has been given.
As a side note, this is for the default case, where beans are singleton instances. You can also define a bean as multi-instance, in which case, the Warehouse isn't consulted, but instead a fresh and independent instance is manufactured for each request.
Note also that by default, beans are created on-demand, not in advance.
Next step up is the wiring mechanism, which allows Spring Bean instances to be injected as properties into other Beans. Here, too, either annotations or external definitions will guide the process. The Autowiring option allows a simplified wiring based on the idea that the name of the bean to be injected matches the property name of the target bean.
That's the essence of Spring Core. It is, of course, much more sophisticated than that, as there are other ways to provision Spring with definitions besides scanning for annotations and processing and in fact you can define your own. You can also define your own custom BeanFactory.
And finally, in common with most dual-definition systems, an explicit definition file (applicationOptions.xml) will override class annotations. That allows a bean to have reasonable defaults, but to be re-usable in other environments without modifying
Java source code.