Spring参考文档翻译05--IOC容器03

1.3. Bean Overview

bean概述 

A Spring IoC container manages one or more beans. These beans are created with the configuration metadata that you supply to the container (for example, in the form of XML <bean/> definitions).

SpringIOC容器管理了一个或多个bean。这些 bean 是使用您提供给容器的配置元数据创建的(例如,以 XML <bean/>定义的形式)。

Within the container itself, these bean definitions are represented as BeanDefinition objects, which contain (among other information) the following metadata:

在容器本身中,这些 bean 定义表示为BeanDefinition 对象,其中包含(以及其他信息)以下元数据:

  • A package-qualified class name: typically, the actual implementation class of the bean being defined.

    一个包限定的类名:通常是被定义的 bean 的实际实现类。

  • Bean behavioral configuration elements, which state how the bean should behave in the container (scope, lifecycle callbacks, and so forth).

    Bean 行为配置元素,它说明 bean 在容器中的行为方式(范围、生命周期回调等)。

  • References to other beans that are needed for the bean to do its work. These references are also called collaborators or dependencies.

    对 bean 完成工作所需的其他 bean 的引用。这些引用也称为协作者或依赖项。

  • Other configuration settings to set in the newly created object — for example, the size limit of the pool or the number of connections to use in a bean that manages a connection pool.

    要在新创建的对象中设置的其他配置设置——例如,池的大小限制或在管理连接池的 bean 中使用的连接数。

This metadata translates to a set of properties that make up each bean definition. The following table describes these properties:

此元数据转换为组成每个 bean 定义的一组属性。下表描述了这些属性:

PropertyExplained in…
ClassInstantiating Beans
实例化Bean
NameNaming Beans
名称命名Bean
ScopeBean Scopes
范围Bean的范围
Constructor argumentsDependency Injection
构造器参数依赖注入
PropertiesDependency Injection
属性依赖注入
Autowiring modeAutowiring Collaborators
自动装配模式自动装配协作者
Lazy initialization modeLazy-initialized Beans
惰性初始化模式延迟初始化的Bean
Initialization methodInitialization Callbacks
初始化方法初始化回调
Destruction methodDestruction Callbacks
销毁方法销毁回调

In addition to bean definitions that contain information on how to create a specific bean, the ApplicationContext implementations also permit the registration of existing objects that are created outside the container (by users). This is done by accessing the ApplicationContext’s BeanFactory through the getBeanFactory() method, which returns the BeanFactory DefaultListableBeanFactory implementation. DefaultListableBeanFactory supports this registration through the registerSingleton(..) and registerBeanDefinition(..) methods. However, typical applications work solely with beans defined through regular bean definition metadata.

除了包含有关如何创建特定 bean 的信息的 bean 定义之外,ApplicationContext实现还允许注册在容器外部(由用户)创建的现有对象。这是通过getBeanFactory()方法访问 ApplicationContext 的 BeanFactory 来完成的,该方法返回 BeanFactoryDefaultListableBeanFactory实现。通过和 方法DefaultListableBeanFactory 支持这种注册。但是,典型的应用程序仅使用通过常规 bean 定义元数据定义的 bean。registerSingleton(..)``registerBeanDefinition(..)

Bean metadata and manually supplied singleton instances need to be registered as early as possible, in order for the container to properly reason about them during autowiring and other introspection steps. While overriding existing metadata and existing singleton instances is supported to some degree, the registration of new beans at runtime (concurrently with live access to the factory) is not officially supported and may lead to concurrent access exceptions, inconsistent state in the bean container, or both.
Bean 元数据和手动提供的单例实例需要尽早注册,以便容器在自动装配和其他自省步骤中正确推理它们。虽然在某种程度上支持覆盖现有元数据和现有单例实例,但官方不支持在运行时注册新 bean(同时对工厂进行实时访问),并可能导致并发访问异常、bean 容器中的状态不一致或两个都。

1.3.1. Naming Beans

命名Bean

Every bean has one or more identifiers. These identifiers must be unique within the container that hosts the bean. A bean usually has only one identifier. However, if it requires more than one, the extra ones can be considered aliases.

每个 bean 都有一个或多个标识符。这些标识符在承载 bean 的容器中必须是唯一的。一个 bean 通常只有一个标识符。但是,如果它需要多个,则可以将多余的视为别名。

In XML-based configuration metadata, you use the id attribute, the name attribute, or both to specify the bean identifiers. The id attribute lets you specify exactly one id. Conventionally, these names are alphanumeric ('myBean', 'someService', etc.), but they can contain special characters as well. If you want to introduce other aliases for the bean, you can also specify them in the name attribute, separated by a comma (,), semicolon (;), or white space. As a historical note, in versions prior to Spring 3.1, the id attribute was defined as an xsd:ID type, which constrained possible characters. As of 3.1, it is defined as an xsd:string type. Note that bean id uniqueness is still enforced by the container, though no longer by XML parsers.

在基于 XML 的配置元数据中,您可以使用id属性、name属性或两者来指定 bean 标识符。该id属性可让您准确指定一个 id。按照惯例,这些名称是字母数字的(“myBean”、“someService”等),但它们也可以包含特殊字符。如果要为 bean 引入其他别名,也可以在name 属性中指定,用逗号 ( ,)、分号 ( ;) 或空格分隔。作为历史记录,在 Spring 3.1 之前的版本中,id属性被定义为一种xsd:ID类型,它限制了可能的字符。从 3.1 开始,它被定义为一种xsd:string类型。请注意,id容器仍然强制执行 bean 唯一性,但不再由 XML 解析器强制执行。   

You are not required to supply a name or an id for a bean. If you do not supply a name or id explicitly, the container generates a unique name for that bean. However, if you want to refer to that bean by name, through the use of the ref element or a Service Locator style lookup, you must provide a name. Motivations for not supplying a name are related to using inner beans and autowiring collaborators.

您不需要为 bean 提供 一个name或 一个 id。如果您不显式提供 nameid,则容器会为该 bean 生成一个唯一名称。但是,如果您想通过名称引用该 bean,通过使用ref元素或服务定位器样式查找,您必须提供名称。不提供名称的动机与使用内部 bean自动装配合作者有关。

Bean Naming Conventions

Bean命名约定

The convention is to use the standard Java convention for instance field names when naming beans. That is, bean names start with a lowercase letter and are camel-cased from there. Examples of such names include accountManager, accountService, userDao, loginController, and so forth.

约定是在命名 bean 时对实例字段名称使用标准 Java 约定。也就是说,bean 名称以小写字母开头,并且从那里开始是驼峰式的。此类名称的示例包括accountManageraccountServiceuserDaologinController等。

Naming beans consistently makes your configuration easier to read and understand. Also, if you use Spring AOP, it helps a lot when applying advice to a set of beans related by name.

一致地命名 bean 使您的配置更易于阅读和理解。此外,如果您使用 Spring AOP,则在将建议应用于一组按名称相关的 bean 时会很有帮助。

With component scanning in the classpath, Spring generates bean names for unnamed components, following the rules described earlier: essentially, taking the simple class name and turning its initial character to lower-case. However, in the (unusual) special case when there is more than one character and both the first and second characters are upper case, the original casing gets preserved. These are the same rules as defined by java.beans.Introspector.decapitalize (which Spring uses here).
通过类路径中的组件扫描,Spring 为未命名的组件生成 bean 名称,遵循前面描述的规则:本质上,采用简单的类名称并将其初始字符转换为小写。但是,在(不寻常的)特殊情况下,当有多个字符并且第一个和第二个字符都是大写时,会保留原始大小写。java.beans.Introspector.decapitalize这些与(Spring 在此处使用的) 定义的规则相同。

Aliasing a Bean outside the Bean Definition

在 Bean 定义之外为 Bean 起别名

In a bean definition itself, you can supply more than one name for the bean, by using a combination of up to one name specified by the id attribute and any number of other names in the name attribute. These names can be equivalent aliases to the same bean and are useful for some situations, such as letting each component in an application refer to a common dependency by using a bean name that is specific to that component itself.

在 bean 定义本身中,您可以为 bean 提供多个名称,方法是使用属性指定的最多一个名称id和属性中任意数量的其他名称的组合name。这些名称可以是同一个 bean 的等效别名,并且在某些情况下很有用,例如让应用程序中的每个组件通过使用特定于该组件本身的 bean 名称来引用公共依赖项。

Specifying all aliases where the bean is actually defined is not always adequate, however. It is sometimes desirable to introduce an alias for a bean that is defined elsewhere. This is commonly the case in large systems where configuration is split amongst each subsystem, with each subsystem having its own set of object definitions. In XML-based configuration metadata, you can use the <alias/> element to accomplish this. The following example shows how to do so:

但是,指定实际定义 bean 的所有别名并不总是足够的。有时需要为在别处定义的 bean 引入别名。这在大型系统中很常见,其中配置在每个子系统之间进行拆分,每个子系统都有自己的一组对象定义。在基于 XML 的配置元数据中,您可以使用该<alias/>元素来完成此操作。以下示例显示了如何执行此操作:

<alias name="fromName" alias="toName"/>

In this case, a bean (in the same container) named fromName may also, after the use of this alias definition, be referred to as toName.

在这种情况下,命名的 bean(在同一容器中)fromName也可以在使用此别名定义后称为toName.

For example, the configuration metadata for subsystem A may refer to a DataSource by the name of subsystemA-dataSource. The configuration metadata for subsystem B may refer to a DataSource by the name of subsystemB-dataSource. When composing the main application that uses both these subsystems, the main application refers to the DataSource by the name of myApp-dataSource. To have all three names refer to the same object, you can add the following alias definitions to the configuration metadata:

例如,子系统 A 的配置元数据可能引用名为 的 DataSource subsystemA-dataSource。子系统 B 的配置元数据可能会引用名称为 的 DataSource subsystemB-dataSource。在编写同时使用这两个子系统的主应用程序时,主应用程序通过名称来引用 DataSource myApp-dataSource。要让所有三个名称都引用同一个对象,您可以将以下别名定义添加到配置元数据中:

<alias name="myApp-dataSource" alias="subsystemA-dataSource"/>
<alias name="myApp-dataSource" alias="subsystemB-dataSource"/>

Now each component and the main application can refer to the dataSource through a name that is unique and guaranteed not to clash with any other definition (effectively creating a namespace), yet they refer to the same bean.

现在每个组件和主应用程序都可以通过一个唯一的名称来引用数据源,并保证不会与任何其他定义冲突(有效地创建一个命名空间),但它们引用的是同一个 bean。

Java-configuration

java 配置

If you use Javaconfiguration, the @Bean annotation can be used to provide aliases. See Using the @Bean Annotation for details.

如果您使用 Javaconfiguration,则@Bean可以使用注解来提供别名。有关详细信息,请参阅使用@Bean注释

1.3.2. Instantiating Beans

实例化Bean

A bean definition is essentially a recipe for creating one or more objects. The container looks at the recipe for a named bean when asked and uses the configuration metadata encapsulated by that bean definition to create (or acquire) an actual object.

bean 定义本质上是创建一个或多个对象的方法。当被询问时,容器会查看命名 bean 的配方,并使用该 bean 定义封装的配置元数据来创建(或获取)实际对象。

If you use XML-based configuration metadata, you specify the type (or class) of object that is to be instantiated in the class attribute of the <bean/> element. This class attribute (which, internally, is a Class property on a BeanDefinition instance) is usually mandatory. (For exceptions, see Instantiation by Using an Instance Factory Method and Bean Definition Inheritance.) You can use the Class property in one of two ways:

如果您使用基于 XML 的配置元数据,您可以在元素的class属性中指定要实例化的对象的类型(或类) 。<bean/>class属性(在内部是实例的Class属性BeanDefinition )通常是必需的。(有关例外情况,请参阅 使用实例工厂方法Bean 定义继承进行实例化。)您可以通过以下Class两种方式之一使用该属性:

  • Typically, to specify the bean class to be constructed in the case where the container itself directly creates the bean by calling its constructor reflectively, somewhat equivalent to Java code with the new operator.

    通常,在容器本身通过反射调用其构造函数直接创建 bean 的情况下,指定要构造的 bean 类,有点等价于 Java 代码中的new运算符。

  • To specify the actual class containing the static factory method that is invoked to create the object, in the less common case where the container invokes a static factory method on a class to create the bean. The object type returned from the invocation of the static factory method may be the same class or another class entirely.

    static指定包含被调用以创建对象 的工厂方法的实际类,在不太常见的情况下,容器调用static类上的工厂方法来创建 bean。调用static工厂方法返回的对象类型可能是同一个类,也可能完全是另一个类。

Nested class names

嵌套类名

If you want to configure a bean definition for a nested class, you may use either the binary name or the source name of the nested class.

如果要为嵌套类配置 bean 定义,可以使用嵌套类的二进制名称或源名称。

For example, if you have a class called SomeThing in the com.example package, and this SomeThing class has a static nested class called OtherThing, they can be separated by a dollar sign ($) or a dot (.). So the value of the class attribute in a bean definition would be com.example.SomeThing$OtherThing or com.example.SomeThing.OtherThing.

例如,如果您SomeThingcom.example包中调用了一个类,并且SomeThing该类有一个static名为 的嵌套类OtherThing,则它们可以用美元符号 ( $) 或点 ( .) 分隔。所以classbean 定义中属性的值是com.example.SomeThing$OtherThingor com.example.SomeThing.OtherThing

Instantiation with a Constructor

使用构造器进行实例化

When you create a bean by the constructor approach, all normal classes are usable by and compatible with Spring. That is, the class being developed does not need to implement any specific interfaces or to be coded in a specific fashion. Simply specifying the bean class should suffice. However, depending on what type of IoC you use for that specific bean, you may need a default (empty) constructor.

当您通过构造方法创建 bean 时,所有普通类都可以被 Spring 使用并兼容。也就是说,正在开发的类不需要实现任何特定的接口或以特定的方式进行编码。只需指定 bean 类就足够了。但是,根据您用于该特定 bean 的 IoC 类型,您可能需要一个默认(空)构造函数。

The Spring IoC container can manage virtually any class you want it to manage. It is not limited to managing true JavaBeans. Most Spring users prefer actual JavaBeans with only a default (no-argument) constructor and appropriate setters and getters modeled after the properties in the container. You can also have more exotic non-bean-style classes in your container. If, for example, you need to use a legacy connection pool that absolutely does not adhere to the JavaBean specification, Spring can manage it as well.

Spring IoC 容器几乎可以管理您希望它管理的任何类。它不仅限于管理真正的 JavaBean。大多数 Spring 用户更喜欢只有一个默认(无参数)构造函数以及根据容器中的属性建模的适当的 setter 和 getter 的实际 JavaBeans。您还可以在容器中拥有更多奇特的非 bean 样式类。例如,如果您需要使用绝对不符合 JavaBean 规范的遗留连接池,那么 Spring 也可以管理它。

With XML-based configuration metadata you can specify your bean class as follows:

使用基于 XML 的配置元数据,您可以指定 bean 类,如下所示:

<bean id="exampleBean" class="examples.ExampleBean"/>
<bean name="anotherExample" class="examples.ExampleBeanTwo"/>

For details about the mechanism for supplying arguments to the constructor (if required) and setting object instance properties after the object is constructed, see Injecting Dependencies.

有关在构造对象后向构造函数提供参数(如果需要)和设置对象实例属性的机制的详细信息,请参阅 注入依赖项

Instantiation with a Static Factory Method

使用静态工厂方法进行实例化

When defining a bean that you create with a static factory method, use the class attribute to specify the class that contains the static factory method and an attribute named factory-method to specify the name of the factory method itself. You should be able to call this method (with optional arguments, as described later) and return a live object, which subsequently is treated as if it had been created through a constructor. One use for such a bean definition is to call static factories in legacy code.

在定义使用静态工厂方法创建的 bean 时,使用class 属性指定包含static工厂方法的类,使用命名属性factory-method指定工厂方法本身的名称。您应该能够调用此方法(使用可选参数,如后所述)并返回一个活动对象,该对象随后被视为是通过构造函数创建的。这种 bean 定义的一种用途是static在遗留代码中调用工厂。

The following bean definition specifies that the bean be created by calling a factory method. The definition does not specify the type (class) of the returned object, only the class containing the factory method. In this example, the createInstance() method must be a static method. The following example shows how to specify a factory method:

以下 bean 定义指定通过调用工厂方法创建 bean。定义没有指定返回对象的类型(类),只指定了包含工厂方法的类。在此示例中,该createInstance() 方法必须是静态方法。以下示例显示了如何指定工厂方法:

<bean id="clientService"
    class="examples.ClientService"
    factory-method="createInstance"/>

The following example shows a class that would work with the preceding bean definition:

下面的例子展示了一个可以与前面的 bean 定义一起工作的类:

public class ClientService {
    private static ClientService clientService = new ClientService();
    private ClientService() {}
​
    public static ClientService createInstance() {
        return clientService;
    }
}

For details about the mechanism for supplying (optional) arguments to the factory method and setting object instance properties after the object is returned from the factory, see Dependencies and Configuration in Detail.

有关从工厂返回对象后向工厂方法提供(可选)参数和设置对象实例属性的机制的详细信息,请参阅依赖关系和配置详述

Instantiation by Using an Instance Factory Method

使用实例工厂方法进行实例化

Similar to instantiation through a static factory method, instantiation with an instance factory method invokes a non-static method of an existing bean from the container to create a new bean. To use this mechanism, leave the class attribute empty and, in the factory-bean attribute, specify the name of a bean in the current (or parent or ancestor) container that contains the instance method that is to be invoked to create the object. Set the name of the factory method itself with the factory-method attribute. The following example shows how to configure such a bean:

与通过静态工厂方法进行实例化类似,使用实例工厂方法进行实例化会从容器中调用现有 bean 的非静态方法来创建新 bean。要使用此机制,请将class属性留空,并在factory-bean属性中指定当前(或父级或祖先)容器中包含要调用以创建对象的实例方法的 bean 的名称。factory-method使用属性设置工厂方法本身的名称。以下示例显示了如何配置这样的 bean:

<!-- the factory bean, which contains a method called createInstance() -->
<bean id="serviceLocator" class="examples.DefaultServiceLocator">
    <!-- inject any dependencies required by this locator bean -->
</bean>
​
<!-- the bean to be created via the factory bean -->
<bean id="clientService"
    factory-bean="serviceLocator"
    factory-method="createClientServiceInstance"/>

The following example shows the corresponding class:

以下示例显示了相应的类:

public class DefaultServiceLocator {
​
    private static ClientService clientService = new ClientServiceImpl();
​
    public ClientService createClientServiceInstance() {
        return clientService;
    }
}

One factory class can also hold more than one factory method, as the following example shows:

一个工厂类也可以包含多个工厂方法,如下例所示:

<bean id="serviceLocator" class="examples.DefaultServiceLocator">
    <!-- inject any dependencies required by this locator bean -->
</bean>
​
<bean id="clientService"
    factory-bean="serviceLocator"
    factory-method="createClientServiceInstance"/>
​
<bean id="accountService"
    factory-bean="serviceLocator"
    factory-method="createAccountServiceInstance"/>

The following example shows the corresponding class:

以下示例显示了相应的类:

public class DefaultServiceLocator {
    private static ClientService clientService = new ClientServiceImpl();
    private static AccountService accountService = new AccountServiceImpl();
    public ClientService createClientServiceInstance() {
        return clientService;
    }
​
    public AccountService createAccountServiceInstance() {
        return accountService;
    }
}

This approach shows that the factory bean itself can be managed and configured through dependency injection (DI). See Dependencies and Configuration in Detail.

这种方法表明,工厂 bean 本身可以通过依赖注入 (DI) 进行管理和配置。请参阅依赖项和配置详细信息

In Spring documentation, "factory bean" refers to a bean that is configured in the Spring container and that creates objects through an instance or static factory method. By contrast, FactoryBean (notice the capitalization) refers to a Spring-specific FactoryBean implementation class.
在 Spring 文档中,“工厂 bean”是指在 Spring 容器中配置并通过 实例静态工厂方法创建对象的 bean。相比之下, FactoryBean(注意大写)指的是特定于 Spring 的 FactoryBean实现类。

Determining a Bean’s Runtime Type

确定Bean的运行时类型

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).

确定特定 bean 的运行时类型并非易事。bean 元数据定义中的指定类只是一个初始类引用,可能与声明的工厂方法结合,或者是FactoryBean可能导致 bean 的不同运行时类型的类,或者在实例的情况下根本没有设置 -级别工厂方法(而是通过指定的factory-bean名称解析)。此外,AOP 代理可以用基于接口的代理包装一个 bean 实例,并限制目标 bean 的实际类型(仅其实现的接口)的暴露。

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.

查找特定 bean 的实际运行时类型的推荐方法是BeanFactory.getType调用指定的 bean 名称。这将所有上述情况考虑在内,并返回BeanFactory.getBean调用将为相同 bean 名称返回的对象类型。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值