Spring Framework-1.1~1.3-IOC
1.1. IoC Container and Beans
IoC is also known as dependency injection (DI). It is a process whereby objects define their dependencies (that is, the other objects they work with) only through constructor arguments, arguments to a factory method, or properties that are set on the object instance after it is constructed or returned from a factory method. The container then injects those dependencies when it creates the bean. This process is fundamentally the inverse (hence the name, Inversion of Control) of the bean itself controlling the instantiation or location of its dependencies by using direct construction of classes or a mechanism such as the Service Locator pattern.
IoC也称为依赖注入(DI)。这是一个过程,对象仅通过构造函数参数、工厂方法的参数或从工厂方法构造或返回后在对象实例上设置的属性来定义其依赖关系(即,它们使用的其他对象)。容器然后在创建bean时注入这些依赖项。这个过程基本上是bean本身的逆过程(因此是名称,控制反转),通过使用类的直接构造或服务定位器模式等机制来控制其依赖项的实例化或位置。
The BeanFactory interface provides an advanced configuration mechanism capable of managing any type of object. ApplicationContext is a sub-interface of BeanFactory.
BeanFactory接口提供了一种高级配置机制,能够管理任何类型的对象。ApplicationContext是BeanFactory的一个子接口。
In Spring, the objects that form the backbone of your application and that are managed by the Spring IoC container are called beans. A bean is an object that is instantiated, assembled, and otherwise managed by a Spring IoC container. Otherwise, a bean is simply one of many objects in your application. Beans, and the dependencies among them, are reflected in the configuration metadata used by a container.
在Spring中,构成应用程序主干并由Spring IoC容器管理的对象称为bean。bean是由Spring IoC容器实例化、组装和管理的对象。否则,bean只是应用程序中许多对象中的一个。bean以及它们之间的依赖关系反映在容器使用的配置元数据中。
1.2. Container Overview
The org.springframework.context.ApplicationContext interface represents the Spring IoC container and is responsible for instantiating, configuring, and assembling the beans. The container gets its instructions on what objects to instantiate, configure, and assemble by reading configuration metadata. The configuration metadata is represented in XML, Java annotations, or Java code. It lets you express the objects that compose your application and the rich interdependencies between those objects.
ApplicationContext接口表示Spring IoC容器,负责实例化、配置和组装bean。容器通过读取配置元数据来获取实例化、配置和组装哪些对象的指令。配置元数据以XML、Java注释或Java代码表示。它允许您表达组成应用程序的对象以及这些对象之间丰富的相互依赖关系。
Several implementations of the ApplicationContext interface are supplied with Spring. In stand-alone applications, it is common to create an instance of ClassPathXmlApplicationContext or FileSystemXmlApplicationContext. While XML has been the traditional format for defining configuration metadata, you can instruct the container to use Java annotations or code as the metadata format by providing a small amount of XML configuration to declaratively enable support for these additional metadata formats.
Spring提供了ApplicationContext接口的几个实现。在独立应用程序中,通常创建ClassPathXmlApplicationContext或FileSystemXmlApplicationContext的实例。虽然XML是定义配置元数据的传统格式,但是您可以通过提供少量的XML配置来声明性地支持这些附加的元数据格式,从而指示容器使用Java注释或代码作为元数据格式。
1.2.1. Configuration Metadata
Spring configuration consists of at least one and typically more than one bean definition that the container must manage. XML-based configuration metadata configures these beans as <bean/>
elements inside a top-level <beans/>
element. Java configuration typically uses @Bean
-annotated methods within a @Configuration
class.
These bean definitions correspond to the actual objects that make up your application. Typically, you define service layer objects, data access objects (DAOs), presentation objects such as Struts Action
instances, infrastructure objects such as Hibernate SessionFactories
, JMS Queues
, and so forth. Typically, one does not configure fine-grained domain objects in the container, because it is usually the responsibility of DAOs and business logic to create and load domain objects. However, you can use Spring’s integration with AspectJ to configure objects that have been created outside the control of an IoC container.
这些bean定义对应于构成应用程序的实际对象。通常,您定义服务层对象、数据访问对象(DAO)、表示对象(如Struts操作实例)、基础结构对象(如Hibernate SessionFactories、JMS队列等)。通常,不会在容器中配置细粒度的域对象(???),因为创建和加载域对象通常是dao和业务逻辑的责任。但是,您可以使用Spring与AspectJ的集成来配置在IoC容器控制之外创建的对象。
<bean id="..." class="...">
<!-- collaborators and configuration for this bean go here -->
</bean>
The id
attribute is a string that identifies the individual bean definition.
The class
attribute defines the type of the bean and uses the fully qualified classname.
The value of the id
attribute refers to collaborating objects. (引用协作对象)
1.2.2. Instantiating a Container
The location path or paths supplied to an ApplicationContext
constructor are resource strings that let the container load configuration metadata from a variety of external resources, such as the local file system, the Java CLASSPATH
, and so on.
提供给ApplicationContext构造函数的一个或多个位置路径是资源字符串,允许容器从各种外部资源(如本地文件系统、Java类路径等)加载配置元数据。
Spring’s Resource
abstraction , which provides a convenient mechanism for reading an InputStream from locations defined in a URI syntax. In particular, Resource
paths are used to construct applications contexts
Spring的资源抽象,为从URI语法中定义的位置读取InputStream提供了一种方便的机制。特别是,资源路径用于构造应用程序上下文
<bean id="petStore" class="......PetStoreServiceImpl">
<property name="accountDao" ref="accountDao"/>
<property name="itemDao" ref="itemDao"/>
<!-- additional collaborators and configuration for this bean go here -->
</bean>
In the preceding example, the service layer consists of the PetStoreServiceImpl
class and two data access objects of the types JpaAccountDao
and JpaItemDao
(based on the JPA Object-Relational Mapping standard). The property name
element refers to the name of the JavaBean property, and the ref
element refers to the name of another bean definition. This linkage between id
and ref
elements expresses the dependency between collaborating objects.
在前面的示例中,服务层由PetStoreServiceImpl类和两个类型为JPaaAccountDao和JpaItemDao(基于JPA对象关系映射标准)的数据访问对象组成。property name元素引用JavaBean属性的名称,ref元素引用另一个bean定义的名称。id和ref元素之间的这种链接表示协作对象之间的依赖关系。
<beans>
<import resource="services.xml"/>
<import resource="resources/messageSource.xml"/>
<import resource="/resources/themeSource.xml"/>
<bean id="bean1" class="..."/>
<bean id="bean2" class="..."/>
</beans>
It can be useful to have bean definitions span multiple XML files. Often, each individual XML configuration file represents a logical layer or module in your architecture.
You can use the application context constructor to load bean definitions from all these XML fragments. This constructor takes multiple Resource
locations. Alternatively, use one or more occurrences of the <import/>
element to load bean definitions from another file or files.
让bean定义跨越多个XML文件是很有用的。通常,每个单独的XML配置文件都表示体系结构中的逻辑层或模块。
您可以使用应用程序上下文构造函数从所有这些XML片段加载bean定义。此构造函数接受多个资源位置。或者,使用<import/>元素的一个或多个匹配项从另一个或多个文件加载bean定义。
In the preceding example, external bean definitions are loaded from three files: services.xml
, messageSource.xml
, and themeSource.xml
. All location paths are relative to the definition file doing the importing, so services.xml
must be in the same directory or classpath location as the file doing the importing, while messageSource.xml
and themeSource.xml
must be in a resources
location below the location of the importing file. As you can see, a leading slash is ignored. However, given that these paths are relative, it is better form not to use the slash at all. The contents of the files being imported, including the top level <beans/>
element, must be valid XML bean definitions, according to the Spring Schema.
如您所见,前导斜杠被忽略。然而,考虑到这些路径是相对的,最好不要使用斜线。根据Spring模式,要导入的文件的内容(包括顶级<beans/>元素)必须是有效的XML bean定义。
It is possible, but not recommended, to reference files in parent directories using a relative "../" path. Doing so creates a dependency on a file that is outside the current application. In particular, this reference is not recommended for classpath:
URLs (for example, classpath:../services.xml
), where the runtime resolution process chooses the “nearest” classpath root and then looks into its parent directory. Classpath configuration changes may lead to the choice of a different, incorrect directory.
可以(但不建议)使用相对“../”路径引用父目录中的文件。这样做会创建对当前应用程序外部文件的依赖关系。特别是,不建议对classpath:url(例如,类路径:./services.xml),其中运行时解析进程选择“最近的”类路径根,然后查看其父目录。类路径配置更改可能导致选择不同的、不正确的目录。
You can always use fully qualified resource locations instead of relative paths: for example, file:C:/config/services.xml
or classpath:/config/services.xml
. However, be aware that you are coupling your application’s configuration to specific absolute locations. It is generally preferable to keep an indirection for such absolute locations — for example, through "${…}" placeholders that are resolved against JVM system properties at runtime.
您始终可以使用完全限定的资源位置而不是相对路径:例如,文件:C:配置/服务.xml或类路径:/配置/服务.xml. 但是,请注意,您正在将应用程序的配置耦合到特定的绝对位置。一般来说,对于这样的绝对位置 - 保持间接寻址比较好,例如,通过在运行时根据JVM系统属性解析的“${…}”占位符。
1.2.3. Using the Container
The ApplicationContext
is the interface for an advanced factory capable of maintaining a registry of different beans and their dependencies. By using the method T getBean(String name, Class<T> requiredType)
, you can retrieve instances of your beans.
ApplicationContext是一个高级工厂的接口,能够维护不同bean及其依赖项的注册表。通过使用方法getBean,可以检索bean的实例。
The ApplicationContext
interface has a few other methods for retrieving beans, but, ideally, your application code should never use them. Indeed, your application code should have no calls to the getBean()
method at all and thus have no dependency on Spring APIs at all. For example, Spring’s integration with web frameworks provides dependency injection for various web framework components such as controllers and JSF-managed beans, letting you declare a dependency on a specific bean through metadata (such as an autowiring annotation).
ApplicationContext接口还有一些其他方法用于检索bean,但理想情况下,应用程序代码不应该使用它们。实际上,应用程序代码根本不应该调用getBean()方法,因此根本不依赖SpringAPI。例如,Spring与web框架的集成为各种web框架组件(如控制器和JSF托管bean)提供依赖注入,允许您通过元数据(如自动连接注释)声明对特定bean的依赖。
1.3. Bean Overview
Within the container itself, these bean definitions are represented as BeanDefinition
objects, which contain (among other information) the following metadata:
-
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).
-
References to other beans that are needed for the bean to do its work. These references are also called collaborators or dependencies.
-
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的实际实现类。
Bean行为配置元素,用于说明Bean在容器中的行为(范围、生命周期回调等)。
对bean执行其工作所需的其他bean的引用。这些引用也称为协作者或依赖项。
要在新创建的对象 - 中设置的其他配置设置,例如池的大小限制或要在管理连接池的bean中使用的连接数。
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通过registerSingleton(..)和registerBeanDefinition(..)方法支持此注册。但是,典型的应用程序只处理通过常规bean定义元数据定义的bean。
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元数据和手动提供的singleton实例需要尽早注册,以便容器在自动连接和其他内省步骤中正确地解释它们。虽然在某种程度上支持重写现有元数据和现有的单例实例,但运行时注册新bean(与对工厂的实时访问同时进行)并没有得到官方支持,可能会导致并发访问异常、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通常只有一个标识符。但是,如果需要不止一个,则可以将额外的别名视为别名。