Skip to content

Latest commit

 

History

History
191 lines (142 loc) · 17.1 KB

1.3 Bean Overview.md

File metadata and controls

191 lines (142 loc) · 17.1 KB

2.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 `` definitions).

一个springIoC容器管理着一个或多个bean对象,这些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 behavioral configuration elements, which state how the bean should behave in the container (scope, lifecycle callbacks, and so forth).(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对象时的其他配置,如连接池的最大数量)
Property Explained in…
Class Instantiating Beans
Name Naming Beans
Scope Bean Scopes
Constructor arguments Dependency Injection
Properties Dependency Injection
Autowiring mode Autowiring Collaborators
Lazy initialization mode Lazy-initialized Beans
Initialization method Initialization Callbacks
Destruction method Destruction 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.

这段话说我们可以通过ApplicationContext的getBeanFactory方法在容器之外创建对象,但是这种方法不被建议。//此处我找不到getBeanFactory这个方法。

Tip

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容器中的不一致状态,或者两者都是。

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

用id配置标识,这个需要使唯一的,同时你还可以使用name来配置bean的别名,并且可以配置多个,你可以用逗号分号和空格来分开多个别名。

<bean id="user" class="com.leishida.spring.User" name="u us,use;user2"/>

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属性,这样容器会为它自动分配唯一的id,但是你将无法引用它

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.

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.

遵循Java的命名规范,首字母小写,然后采用驼峰命名。

通过在类路径中扫描组件,Spring按照前面描述的规则为未命名的组件生成bean名称:本质上,使用简单的类名并将其初始字符转换为小写。但是,在(不寻常的)特殊情况下,如果有多个字符,并且第一个和第二个字符都是大写的,则保留原来的大小写。这些规则与java.beans.自省器.decapitalize (Spring在这里使用)定义的规则相同。

在bean定义外定义别名

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

2.3.2 Instantiating Beans 实例化Beans

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 `` 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:

你通常必须指定class属性(因为要创建对象肯定要知道它的全类名)

你可以通过以下两种方式之一使用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.直接通过反射创建
  • 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.通过静态工厂创建

Inner class names

If you want to configure a bean definition for a static nested class, you have to use the binary name of the nested class.

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, the value of the class attribute on a bean definition would be com.example.SomeThing$OtherThing.

Notice the use of the $ character in the name to separate the nested class name from the outer class name.

如果你想要配置一个静态内部类的bean,你需要这么写: packageName.OuterClassName$InnerClassName

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使用并与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用户更喜欢实际的javabean,它只有一个默认的(无参数的)构造函数,以及根据容器中的属性建模的适当的setter和getter方法。您还可以在容器中包含更多非bean风格的类。例如,如果您需要使用完全不符合JavaBean规范的遗留连接池,Spring也可以管理它。

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

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

有关构造器注入的细节,请移步注入依赖项[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属性指定包含静态工厂方法的类,使用factory-method属性指定工厂方法本身的名称。您应该能够调用这个方法(带有可选参数,如后面所述)并返回一个活动对象,该对象随后被视为是通过构造函数创建的。这种bean定义的一个用途是在遗留代码中调用静态工厂。

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()方法必须是一个静态方法。下面的例子展示了如何指定一个工厂方法:

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
    private String name;
    private int age;
}

public class UserFactory {

    public static User getUser(){
        return new User("工厂", 19);
    }
}
<bean id="user" class="com.leishida.spring.UserFactory" factory-method="getUser"/>
public void test(){
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        Object user = context.getBean("user");
        System.out.println(user);   //User(name=工厂, age=19)
    }

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:

public class InstanceUserFactory {
    private static User user = new User();

    public User createClientServiceInstance() {
        return user;
    }
}
<bean id="instanceUserFactory" class="com.leishida.spring.InstanceUserFactory"/>
<bean id="user1" factory-bean="instanceUserFactory" factory-method="createClientServiceInstance"/>
@org.junit.Test
    public void test2(){
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        Object user = context.getBean("user1");
        System.out.println(user);   //User(name=null, age=0)
    }

一个工厂类也可以有多个工厂方法

TIP

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 .

意思使在spring文档里,factoryBean是你在配置里自己配置的工厂bean对象,而FactoryBean则值得是Spring的FactoryBean