Определение бина может содержать много информации о конфигурации, включая аргументы конструктора, значения свойств и специфическую для контейнера информацию, такую как метод инициализации, имя статического фабричного метода и так далее. Дочернее определение бина наследует данные конфигурации от родительского определения. Дочернее определение может переопределять некоторые значения или добавлять другие по мере необходимости. Использование определений родительских и дочерних бинов может сэкономить много времени при типизации. По сути, это форма шаблонизации.

Если вы работаете с интерфейсом ApplicationContext программно, определения дочерних бинов представлены классом ChildBeanDefinition. Большинство пользователей не работают с ними на этом уровне. Вместо этого они конфигурируют определения бинов декларативно в классе, таком как ClassPathXmlApplicationContext. Если используются конфигурационные метаданные на основе XML, то можно указать определение дочернего бина с помощью атрибута parent, задав родительский бин в качестве значения этого атрибута. В следующем примере показано, как это сделать:

<bean id="inheritedTestBean" abstract="true"
        class="org.springframework.beans.TestBean">
    <property name="name" value="parent"/>
    <property name="age" value="1"/>
</bean>
<bean id="inheritsWithDifferentClass"
        class="org.springframework.beans.DerivedTestBean"
        parent="inheritedTestBean" init-method="initialize">  
    <property name="name" value="override"/>
    <!-- значение свойства age, равное 1, будет унаследовано от родителя -->
</bean>
  1. Обратите внимание на атрибут parent.

Дочернее определение бина использует класс бина из родительского определения, если он не указан, но может и переопределять его. В последнем случае дочерний класс бина должен быть совместим с родительским (то есть принимать значения свойств родительского класса).

Определение дочернего бина наследует область видимости, значения аргументов конструктора, значения свойств и переопределения методов от родительского, с возможностью добавления новых значений. Любые заданные вами настройки области видимости, метода инициализации, метода уничтожения или статического фабричного метода переопределяют соответствующие родительские настройки.

Остальные параметры всегда берутся из дочернего определения: depends on, autowire mode, dependency check, singleton и lazy init.

В предыдущем примере определение родительского бина явно помечено как абстрактное с помощью атрибута abstract. Если в родительском определении не указан класс, необходимо явно пометить родительское определение бина как abstract, как показано в следующем примере:

<bean id="inheritedTestBeanWithoutClass" abstract="true">
    <property name="name" value="parent"/>
    <property name="age" value="1"/>
</bean>
<bean id="inheritsWithClass" class="org.springframework.beans.DerivedTestBean"
        parent="inheritedTestBeanWithoutClass" init-method="initialize">
    <property name="name" value="override"/>
    <!-- свойство age будет наследовать значение 1 из определения родительского бина -->
</bean>

Экземпляр родительского бина не может быть создан сам по себе, поскольку он неполный, и он также явно помечен как abstract. Когда определение является abstract, его можно использовать только в качестве чисто шаблонного определения бина, которое служит родительским определением для дочерних определений. Попытка использовать такой abstract родительский бин самостоятельно, ссылаясь на него как на свойство ref другого бина или выполняя явный вызов getBean() с идентификатором родительского бина, приводит к ошибке. Аналогично, внутренний метод preInstantiateSingletons() контейнера игнорирует определения бинов, которые определены как абстрактные.

ApplicationContext по умолчанию предварительно создает экземпляры всех объектов-одиночек. Поэтому важно учитывать (по крайней мере, в случае бинов-одиночек), что если у вас есть определение (родительского) бина, которое вы собираетесь использовать только в качестве шаблона, и это определение задает класс, вам нужно убедиться, что вы установили атрибут abstract в true, иначе контекст приложения фактически (попытается) пересоздать экземпляр abstract бина.