Spring 简明教程

Spring - Bean Definition Inheritance

一个 Bean 定义可以包含许多配置信息,包括构造函数参数、属性值,以及特定于容器的信息,比如初始化方法、静态工厂方法名,等等。

A bean definition can contain a lot of configuration information, including constructor arguments, property values, and container-specific information such as initialization method, static factory method name, and so on.

一个子 Bean 定义从父定义继承配置数据。子定义可以根据需要覆盖某些值,或添加其他值。

A child bean definition inherits configuration data from a parent definition. The child definition can override some values, or add others, as needed.

Spring Bean 定义继承与 Java 类继承无关,但继承概念是一样的。你可以将父 Bean 定义定义为模板,其他子 Bean 可以从中继承所需的配置。

Spring Bean definition inheritance has nothing to do with Java class inheritance but the inheritance concept is same. You can define a parent bean definition as a template and other child beans can inherit the required configuration from the parent bean.

使用基于 XML 的配置元数据时,可以通过使用 parent 属性来指示一个子 Bean 定义,指定父 Bean 作为该属性的值。

When you use XML-based configuration metadata, you indicate a child bean definition by using the parent attribute, specifying the parent bean as the value of this attribute.

Example

让我们准备一个可用的 Eclipse IDE,然后执行以下步骤来创建一个 Spring 应用程序−

Let us have a working Eclipse IDE in place and take the following steps to create a Spring application −

Steps

Description

1

Create a project with a name SpringExample and create a package com.tutorialspoint under the src folder in the created project.

2

Add required Spring libraries using Add External JARs option as explained in the Spring Hello World Example chapter.

3

Create Java classes HelloWorld, HelloIndia and MainApp under the com.tutorialspoint package.

4

Create Beans configuration file Beans.xml under the src folder.

5

The final step is to create the content of all the Java files and Bean Configuration file and run the application as explained below.

以下是配置文件 Beans.xml ,我们在其中定义了“helloWorld”Bean,它具有两个属性 message1 和 message2。接下来“helloIndia”Bean 已被定义为“helloWorld”Bean 的子项,方法是使用 parent 属性。该子 Bean 原样继承 message2 属性,并覆盖 message1 属性并引入一个新的 message3 属性。

Following is the configuration file Beans.xml where we defined "helloWorld" bean which has two properties message1 and message2. Next "helloIndia" bean has been defined as a child of "helloWorld" bean by using parent attribute. The child bean inherits message2 property as is, and overrides message1 property and introduces one more property message3.

<?xml version = "1.0" encoding = "UTF-8"?>

<beans xmlns = "http://www.springframework.org/schema/beans"
   xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation = "http://www.springframework.org/schema/beans
   http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

   <bean id = "helloWorld" class = "com.tutorialspoint.HelloWorld">
      <property name = "message1" value = "Hello World!"/>
      <property name = "message2" value = "Hello Second World!"/>
   </bean>

   <bean id ="helloIndia" class = "com.tutorialspoint.HelloIndia" parent = "helloWorld">
      <property name = "message1" value = "Hello India!"/>
      <property name = "message3" value = "Namaste India!"/>
   </bean>
</beans>

以下是 HelloWorld.java 文件的内容 −

Here is the content of HelloWorld.java file −

package com.tutorialspoint;

public class HelloWorld {
   private String message1;
   private String message2;

   public void setMessage1(String message){
      this.message1 = message;
   }
   public void setMessage2(String message){
      this.message2 = message;
   }
   public void getMessage1(){
      System.out.println("World Message1 : " + message1);
   }
   public void getMessage2(){
      System.out.println("World Message2 : " + message2);
   }
}

以下是 HelloIndia.java 文件的内容 −

Here is the content of HelloIndia.java file −

package com.tutorialspoint;

public class HelloIndia {
   private String message1;
   private String message2;
   private String message3;

   public void setMessage1(String message){
      this.message1 = message;
   }
   public void setMessage2(String message){
      this.message2 = message;
   }
   public void setMessage3(String message){
      this.message3 = message;
   }
   public void getMessage1(){
      System.out.println("India Message1 : " + message1);
   }
   public void getMessage2(){
      System.out.println("India Message2 : " + message2);
   }
   public void getMessage3(){
      System.out.println("India Message3 : " + message3);
   }
}

以下是 MainApp.java 文件的内容−

Following is the content of the MainApp.java file −

package com.tutorialspoint;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MainApp {
   public static void main(String[] args) {
      ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");

      HelloWorld objA = (HelloWorld) context.getBean("helloWorld");
      objA.getMessage1();
      objA.getMessage2();

      HelloIndia objB = (HelloIndia) context.getBean("helloIndia");
      objB.getMessage1();
      objB.getMessage2();
      objB.getMessage3();
   }
}

完成源文件和 Bean 配置文件创建后,我们运行该应用程序。如果您的应用程序一切正常,它将打印以下消息−

Once you are done creating the source and bean configuration files, let us run the application. If everything is fine with your application, it will print the following message −

World Message1 : Hello World!
World Message2 : Hello Second World!
India Message1 : Hello India!
India Message2 : Hello Second World!
India Message3 : Namaste India!

如果你在这里观察到,我们在创建“helloIndia”Bean 时没有传递 message2,但由于 Bean 定义继承,它已经传递了。

If you observed here, we did not pass message2 while creating "helloIndia" bean, but it got passed because of Bean Definition Inheritance.

Bean Definition Template

你可以创建一个 Bean 定义模板,它可以在其他子 Bean 定义中使用,无需付出太多努力。在定义 Bean 定义模板时,你应该不要指定 class 属性,而应该指定 abstract 属性,并且应该使用 true 值指定 abstract 属性,如下面的代码片段所示 −

You can create a Bean definition template, which can be used by other child bean definitions without putting much effort. While defining a Bean Definition Template, you should not specify the class attribute and should specify abstract attribute and should specify the abstract attribute with a value of true as shown in the following code snippet −

<?xml version = "1.0" encoding = "UTF-8"?>

<beans xmlns = "http://www.springframework.org/schema/beans"
   xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation = "http://www.springframework.org/schema/beans
   http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

   <bean id = "beanTeamplate" abstract = "true">
      <property name = "message1" value = "Hello World!"/>
      <property name = "message2" value = "Hello Second World!"/>
      <property name = "message3" value = "Namaste India!"/>
   </bean>

   <bean id = "helloIndia" class = "com.tutorialspoint.HelloIndia" parent = "beanTeamplate">
      <property name = "message1" value = "Hello India!"/>
      <property name = "message3" value = "Namaste India!"/>
   </bean>

</beans>

父 Bean,它本身无法实例化,因为它是不完整的,并且它还被明确标记为 abstract。当一个定义像这样抽象时,它只能作为一个纯模板 Bean 定义使用,它作为子定义的父定义。

The parent bean cannot be instantiated on its own because it is incomplete, and it is also explicitly marked as abstract. When a definition is abstract like this, it is usable only as a pure template bean definition that serves as a parent definition for child definitions.