天天看点

1.4.1.3.Dependency Resolution Process(依赖解析过程) Spring Framework Documentation (5.3.10)

 Spring Framework Documentation (5.3.10)

Core IoC Container, Events, Resources, i18n, Validation, Data Binding, Type Conversion, SpEL, AOP.

   Core Technologies

1. The IoC Container

1.1. Introduction to the Spring IoC Container and Beans(Spring IoC容器和bean简介)

1.2. Container Overview (容器概览)

1.3. Bean Overview (Bean概览)

1.4. Dependencies(依赖)

1.4.1. Dependency Injection(依赖注入)

1.4.1.1. Constructor-based Dependency Injection(基于构造函数的依赖注入) (Part I)

1.4.1.1. Constructor-based Dependency Injection(基于构造函数的依赖注入) (Part II)

1.4.1.2.Setter-based Dependency Injection(基于Setter的依赖注入)

1.4.1.3.Dependency Resolution Process(依赖解析过程)  

1.4.1.4. Examples of Dependency Injection(依赖注入示例)

1.4.2. Dependencies and Configuration in Detail(依赖与配置详细介绍)

1.4.3. Using depends-on(使用depends-on)

1.4.4. Lazy-initialized Beans(延迟初始化Bean)

1.4.5. Autowiring Collaborators(自动装配协作者)

1.4.6. Method Injection(方法注入)

1.4.6.1. Lookup Method Injection(查找方法注入)

1.4.6.2. Arbitrary Method Replacement(任意方法替换)

1.5. Bean Scopes(Bean作用域)

关于Spring Framework Documentation (5.3.10)  核心技术的更多内容,请点击:

  Core Technologies

1.4.1.3.Dependency Resolution Process(依赖解析过程)

The container performs bean dependency resolution as follows:

容器执行bean依赖解析(bean dependency resolution),如下所示:

  • The 

    ApplicationContext

     is created and initialized with configuration metadata that describes all the beans. Configuration metadata can be specified by XML, Java code, or annotations.
  • For each bean, its dependencies are expressed in the form of properties, constructor arguments, or arguments to the static-factory method (if you use that instead of a normal constructor). These dependencies are provided to the bean, when the bean is actually created.
  • Each property or constructor argument is an actual definition of the value to set, or a reference to another bean in the container.
  • Each property or constructor argument that is a value is converted from its specified format to the actual type of that property or constructor argument. By default, Spring can convert a value supplied in string format to all built-in types, such as 

    int

    long

    String

    boolean

    , and so forth.
  • 通过描述所有bean的配置元数据创建和初始化

    ApplicationContext

     。配置元数据可以由XML、Java代码或注解指定。
  • 对于每个bean,其依赖关系都以属性、构造函数参数或静态工厂方法的参数的形式表示(如果您使用静态工厂方法而不是普通构造函数)。这些依赖关系在bean实际创建时提供给bean。
  • 每个属性或构造函数参数都是要设置的实际值定义,或者是对容器中另一个bean的引用。
  • 作为值的每个属性或构造函数参数将从其指定格式转换为该属性或构造函数参数的实际类型。默认情况下,Spring可以将以字符串格式提供的值转换为所有内置类型,例如int、long、string、

    boolean

    等。

The Spring container validates the configuration of each bean as the container is created. However, the bean properties themselves are not set until the bean is actually created. Beans that are singleton-scoped and set to be pre-instantiated (the default) are created when the container is created. Scopes are defined in Bean Scopes. Otherwise, the bean is created only when it is requested. Creation of a bean potentially causes a graph of beans to be created, as the bean’s dependencies and its dependencies' dependencies (and so on) are created and assigned. Note that resolution mismatches among those dependencies may show up late — that is, on first creation of the affected bean.

Spring容器在容器创建时验证每个bean的配置。但是,在实际创建bean之前,不会设置bean属性本身。创建容器时,将创建单例作用域(singleton-scoped)并设置为预实例化(pre-instantiated)(默认)的bean。作用域是在Bean作用域(Bean Scopes)中定义的。否则,仅当请求时才创建bean。创建bean可能会导致创建bean图,因为需要创建和分配bean的依赖项及其依赖项的依赖项(等等)。请注意,这些依赖项之间的不匹配解析(resolution mismatch)可能会延迟展示,也就是说,在第一次创建受影响的bean时。

Circular dependencies

If you use predominantly constructor injection, it is possible to create an unresolvable circular dependency scenario.

For example: Class A requires an instance of class B through constructor injection, and class B requires an instance of class A through constructor injection. If you configure beans for classes A and B to be injected into each other, the Spring IoC container detects this circular reference at runtime, and throws a 

BeanCurrentlyInCreationException

.

One possible solution is to edit the source code of some classes to be configured by setters rather than constructors. Alternatively, avoid constructor injection and use setter injection only. In other words, although it is not recommended, you can configure circular dependencies with setter injection.

Unlike the typical case (with no circular dependencies), a circular dependency between bean A and bean B forces one of the beans to be injected into the other prior to being fully initialized itself (a classic chicken-and-egg scenario).

循环依赖

如果主要使用构造函数注入,则有可能创建无法解析的循环依赖场景(circular dependency scenario)。

例如:类A通过构造函数注入需要类B的实例,类B通过构造函数注入需要类A的实例。如果为类A和类B配置bean以相互注入,Spring IoC容器将在运行时检测此循环引用,并抛出BeanCurrentlyInCreationException。

一种可能的解决方案是编辑某些类的源代码,由setter而不是构造函数进行配置。或者,避免构造函数注入,只使用setter注入。换句话说,虽然不推荐,可以使用setter注入来配置循环依赖项(circular dependencies)。

与典型情况(没有循环依赖)不同,bean A和bean B之间的循环依赖迫使一个bean在完全初始化之前注入另一个bean(典型的鸡和蛋场景)。

You can generally trust Spring to do the right thing. It detects configuration problems, such as references to non-existent beans and circular dependencies, at container load-time. Spring sets properties and resolves dependencies as late as possible, when the bean is actually created. This means that a Spring container that has loaded correctly can later generate an exception when you request an object if there is a problem creating that object or one of its dependencies — for example, the bean throws an exception as a result of a missing or invalid property. This potentially delayed visibility of some configuration issues is why 

ApplicationContext

 implementations by default pre-instantiate singleton beans. At the cost of some upfront time and memory to create these beans before they are actually needed, you discover configuration issues when the 

ApplicationContext

 is created, not later. You can still override this default behavior so that singleton beans initialize lazily, rather than being eagerly pre-instantiated.

您通常可以相信Spring会做正确的事情。它在容器加载时检测配置问题,例如对不存在的bean的引用和循环依赖等问题。Spring在bean实际创建时尽可能晚地设置属性、解析依赖。这意味着,如果创建对象或其依赖项时出现问题,则正确加载的Spring容器稍后可能在请求对象时产生异常, 例如,bean由于缺少属性或无效属性而抛出异常。这可能会延迟某些配置问题的可见性,这就是

ApplicationContext

 实现在默认情况下预先实例化(pre-instantiate)单例bean(singleton bean)的原因。在实际需要这些bean之前,您需要花费一些前期时间和内存来创建它们,但在创建

ApplicationContext

 时(而不是以后)会发现配置问题。您仍然可以覆盖此默认行为,以便单例bean可以延迟初始化,而不是急切地预实例化。

If no circular dependencies exist, when one or more collaborating beans are being injected into a dependent bean, each collaborating bean is totally configured prior to being injected into the dependent bean. This means that, if bean A has a dependency on bean B, the Spring IoC container completely configures bean B prior to invoking the setter method on bean A. In other words, the bean is instantiated (if it is not a pre-instantiated singleton), its dependencies are set, and the relevant lifecycle methods (such as a configured init method or the InitializingBean callback method) are invoked.

如果不存在循环依赖关系,那么当一个或多个协作bean被注入到依赖bean(dependent bean)中时,每个协作bean(collaborating bean)在被注入到依赖bean之前都会被完全配置。这意味着,如果bean A依赖于bean B,那么Spring IoC容器将在调用bean A上的setter方法之前完全配置bean B。换句话说,bean被实例化(如果它不是预实例化的单例),它的依赖项被设置,相关的生命周期方法(例如配置的init方法( configured init method)或InitializingBean回调方法(InitializingBean callback method))被调用。