diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanDefinition.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanDefinition.java index 0fccf96455..0fa9a6a551 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanDefinition.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanDefinition.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2020 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -403,16 +403,29 @@ public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccess /** * Specify the class for this bean. + * @see #setBeanClassName(String) */ public void setBeanClass(@Nullable Class beanClass) { this.beanClass = beanClass; } /** - * Return the class of the wrapped bean (assuming it is resolved already). - * @return the bean class (never {@code null}) + * Return the specified class of the bean definition (assuming it is resolved already). + *

NOTE: This is an initial class reference as declared in the bean metadata + * definition, potentially combined with a declared factory method or a + * {@link org.springframework.beans.factory.FactoryBean} which may lead to a different + * runtime type of the bean, or not being set at all in case of an instance-level + * factory method (which is resolved via {@link #getFactoryBeanName()} instead). + * Do not use this for runtime type introspection of arbitrary bean definitions. + * The recommended way to find out about the actual runtime type of a particular bean + * is a {@link org.springframework.beans.factory.BeanFactory#getType} call for the + * specified bean name; this takes all of the above cases into account and returns the + * type of object that a {@link org.springframework.beans.factory.BeanFactory#getBean} + * call is going to return for the same bean name. + * @return the resolved bean class (never {@code null}) * @throws IllegalStateException if the bean definition does not define a bean class, * or a specified bean class name has not been resolved into an actual Class yet + * @see #getBeanClassName() * @see #hasBeanClass() * @see #setBeanClass(Class) * @see #resolveBeanClass(ClassLoader) diff --git a/src/docs/asciidoc/core/core-beans.adoc b/src/docs/asciidoc/core/core-beans.adoc index d1dea79ddc..7ab620ef54 100644 --- a/src/docs/asciidoc/core/core-beans.adoc +++ b/src/docs/asciidoc/core/core-beans.adoc @@ -346,8 +346,8 @@ bean definition files through an `importBeans` directive. === Using the Container The `ApplicationContext` is the interface for an advanced factory capable of maintaining -a registry of different beans and their dependencies. By using the method `T getBean(String -name, Class requiredType)`, you can retrieve instances of your beans. +a registry of different beans and their dependencies. By using the method +`T getBean(String name, Class requiredType)`, you can retrieve instances of your beans. The `ApplicationContext` lets you read bean definitions and access them, as the following example shows: @@ -849,12 +849,29 @@ This approach shows that the factory bean itself can be managed and configured t dependency injection (DI). See <>. -NOTE: In Spring documentation, "`factory bean`" refers to a bean that is configured in the -Spring container and that creates objects through an +NOTE: In Spring documentation, "`factory bean`" refers to a bean that is configured in +the Spring container and that creates objects through an <> or <> factory method. By contrast, `FactoryBean` (notice the capitalization) refers to a Spring-specific -<>. +<> implementation class. + + +[[beans-factory-type-determination]] +==== Determining a Bean's Runtime Type + +The runtime type of a specific bean is non-trivial to determine. A specified class in +the bean metadata definition is just an initial class reference, potentially combined +with a declared factory method or being a `FactoryBean` class which may lead to a +different runtime type of the bean, or not being set at all in case of an instance-level +factory method (which is resolved via the specified `factory-bean` name instead). +Additionally, AOP proxying may wrap a bean instance with an interface-based proxy with +limited exposure of the target bean's actual type (just its implemented interfaces). + +The recommended way to find out about the actual runtime type of a particular bean is +a `BeanFactory.getType` call for the specified bean name. This takes all of the above +cases into account and returns the type of object that a `BeanFactory.getBean` call is +going to return for the same bean name. @@ -874,9 +891,9 @@ application where objects collaborate to achieve a goal. === Dependency Injection Dependency injection (DI) is a process whereby objects define their dependencies -(that is, the other objects with which they work) only through constructor arguments, arguments -to a factory method, or properties that are set on the object instance after it is -constructed or returned from a factory method. The container then injects those +(that is, the other objects with which they work) only through constructor arguments, +arguments to a factory method, or properties that are set on the object instance after +it is constructed or returned from a factory method. The container then injects those dependencies when it creates the bean. This process is fundamentally the inverse (hence the name, Inversion of Control) of the bean itself controlling the instantiation or location of its dependencies on its own by using direct construction of classes or