1.8. Container Extension Points

上一节 1.7. Bean Definition Inheritance

目录

下一节 1.9. Annotation-based Container Configuration

1.8. Container Extension Points

1.8. 容器扩展点

Typically, an application developer does not need to subclass ApplicationContext implementation classes. Instead, the Spring IoC container can be extended by plugging in implementations of special integration interfaces. The next few sections describe these integration interfaces.

通常,应用程序开发人员不需要ApplicationContext子类实现类。
相反,可以通过插入特殊集成接口的实现来扩展Spring IoC容器。
接下来的几节将描述这些集成接口。

1.8.1. Customizing Beans by Using a BeanPostProcessor
1.8.1. 通过使用BeanPostProcessor定制bean

The BeanPostProcessor interface defines callback methods that you can implement to provide your own (or override the container’s default) instantiation logic, dependency resolution logic, and so forth. If you want to implement some custom logic after the Spring container finishes instantiating, configuring, and initializing a bean, you can plug in one or more custom BeanPostProcessor implementations.

BeanPostProcessor接口定义了回调方法,您可以实现这些方法来提供自己的
(或覆盖容器的默认值)实例化逻辑、依赖项解析逻辑等等。
如果您想在Spring容器完成实例化、配置和初始化bean之后实现一些自定义逻辑,
您可以插入一个或多个自定义BeanPostProcessor实现。

You can configure multiple BeanPostProcessor instances, and you can control the order in which these BeanPostProcessor instances execute by setting the order property. You can set this property only if the BeanPostProcessor implements the Ordered interface. If you write your own BeanPostProcessor, you should consider implementing the Ordered interface, too. For further details, see the javadoc of the BeanPostProcessor and Ordered interfaces. See also the note on programmatic registration of BeanPostProcessor instances.

您可以配置多个BeanPostProcessor实例,并且可以通过设置order属性来控制这些BeanPostProcessor实例的执行顺序。
只有当BeanPostProcessor实现了order 接口时,才能设置此属性。
如果您编写自己的BeanPostProcessor,也应该考虑实现Ordered接口。
有关详细信息,请参阅BeanPostProcessor和Ordered接口的javadoc。
请参见BeanPostProcessor实例的编程注册说明。

BeanPostProcessor instances operate on bean (or object) instances. That is, the Spring IoC container instantiates a bean instance and then BeanPostProcessor instances do their work.

BeanPostProcessor实例操作bean(或对象)实例。
也就是说,Spring IoC容器实例化一个bean实例,然后BeanPostProcessor实例
执行它们的工作。

BeanPostProcessor instances are scoped per-container. This is relevant only if you use container hierarchies. If you define a BeanPostProcessor in one container, it post-processes only the beans in that container. In other words, beans that are defined in one container are not post-processed by a BeanPostProcessor defined in another container, even if both containers are part of the same hierarchy.

BeanPostProcessor实例的作用域为每个容器。
只有当您使用容器层次结构时,这才是相关的。
如果在一个容器中定义BeanPostProcessor,那么它只对该容器中的bean进行后处理。
换句话说,在一个容器中定义的bean不会被另一个容器中定义的BeanPostProcessor
进行后处理,即使这两个容器属于同一层次结构。

To change the actual bean definition (that is, the blueprint that defines the bean), you instead need to use a BeanFactoryPostProcessor, as described in Customizing Configuration Metadata with a BeanFactoryPostProcessor.

要更改实际的bean definition(即定义bean的蓝图),您需要使用
BeanFactoryPostProcessor,正如在使用BeanFactoryPostProcessor
自定义配置元数据中所描述的那样。

The org.springframework.beans.factory.config.BeanPostProcessor interface consists of exactly two callback methods. When such a class is registered as a post-processor with the container, for each bean instance that is created by the container, the post-processor gets a callback from the container both before container initialization methods (such as InitializingBean.afterPropertiesSet() or any declared init method) are called, and after any bean initialization callbacks. The post-processor can take any action with the bean instance, including ignoring the callback completely. A bean post-processor typically checks for callback interfaces, or it may wrap a bean with a proxy. Some Spring AOP infrastructure classes are implemented as bean post-processors in order to provide proxy-wrapping logic.

org.springframework.beans.factory.config.BeanPostProcessor接口
恰好由两个回调方法组成。
当这样一个类注册为post-processor的容器,每个容器创建bean实例,
post-processor 从容器之前得到一个回调容器初始化方法
(如InitializingBean.afterPropertiesSet()或任何宣布init方法),
任何bean初始化后回调。
post-processor可以对bean实例采取任何操作,包括完全忽略回调。
bean 的post-processor 通常检查回调接口,或者用代理包装bean。
为了提供代理包装逻辑,一些Spring AOP基础类被实现为bean post-processor。

An ApplicationContext automatically detects any beans that are defined in the configuration metadata that implements the BeanPostProcessor interface. The ApplicationContext registers these beans as post-processors so that they can be called later, upon bean creation. Bean post-processors can be deployed in the container in the same fashion as any other beans.

ApplicationContext自动检测配置元数据中实现BeanPostProcessor接口
定义的任何bean。
ApplicationContext将这些bean注册为post-processors,
以便稍后在bean创建时调用它们。
Bean的post-processors可以在容器中以与其他Bean相同的方式部署。

Note that, when declaring a BeanPostProcessor by using an @Bean factory method on a configuration class, the return type of the factory method should be the implementation class itself or at least the org.springframework.beans.factory.config.BeanPostProcessor interface, clearly indicating the post-processor nature of that bean. Otherwise, the ApplicationContext cannot autodetect it by type before fully creating it. Since a BeanPostProcessor needs to be instantiated early in order to apply to the initialization of other beans in the context, this early type detection is critical.

注意,当通过在配置类上使用@Bean工厂方法声明BeanPostProcessor时,
工厂方法的返回类型应该是实现类本身,或者至少是
org.springframework.bean .factory.config.BeanPostProcessor接口,
清楚地表明该bean的post-processor特性。
否则,ApplicationContext不能在完全创建它之前按类型自动检测它。
由于BeanPostProcessor需要尽早实例化,以便应用于上下文
中其他bean的初始化,因此这种早期类型检测非常关键。

Programmatically registering BeanPostProcessor instances
通过编程注册BeanPostProcessor实例

While the recommended approach for BeanPostProcessor registration is through ApplicationContext auto-detection (as described earlier), you can register them programmatically against a ConfigurableBeanFactory by using the addBeanPostProcessor method. This can be useful when you need to evaluate conditional logic before registration or even for copying bean post processors across contexts in a hierarchy. Note, however, that BeanPostProcessor instances added programmatically do not respect the Ordered interface. Here, it is the order of registration that dictates the order of execution. Note also that BeanPostProcessor instances registered programmatically are always processed before those registered through auto-detection, regardless of any explicit ordering.

虽然推荐的BeanPostProcessor注册方法是通过ApplicationContext自动检测(如前所述),
但是您可以通过使用addBeanPostProcessor方法通过编程方式针对
ConfigurableBeanFactory注册它们。
当您需要在注册前计算条件逻辑时,或者甚至在跨层次结构中的上下文复制
bean post处理器时,这一点非常有用。
但是请注意,通过编程方式添加的BeanPostProcessor实例不遵守Ordered 接口。
在这里,注册的顺序决定了执行的顺序。
还要注意,无论任何显式排序如何,编程注册的BeanPostProcessor实例总是在
通过自动检测注册的实例之前处理。

BeanPostProcessor instances and AOP auto-proxying
BeanPostProcessor实例和AOP自动代理

Classes that implement the BeanPostProcessor interface are special and are treated differently by the container. All BeanPostProcessor instances and beans that they directly reference are instantiated on startup, as part of the special startup phase of the ApplicationContext. Next, all BeanPostProcessor instances are registered in a sorted fashion and applied to all further beans in the container. Because AOP auto-proxying is implemented as a BeanPostProcessor itself, neither BeanPostProcessor instances nor the beans they directly reference are eligible for auto-proxying and, thus, do not have aspects woven into them.

实现BeanPostProcessor接口的类是特殊的,容器会以不同的方式处理它们。
作为ApplicationContext特殊启动阶段的一部分,所有BeanPostProcessor实例
和它们直接引用的bean都在启动时实例化。
接下来,以排序的方式注册所有BeanPostProcessor实例,并应用于容器中
所有附加的bean。
因为AOP自动代理是作为BeanPostProcessor本身实现的,所以无论是
BeanPostProcessor实例还是它们直接引用的bean都不适合自动代理,
因此,它们没有将这方面包含到其中。

For any such bean, you should see an informational log message: Bean someBean is not eligible for getting processed by all BeanPostProcessor interfaces (for example: not eligible for auto-proxying).

对于任何这样的bean,您应该看到一个信息日志消息:
bean someBean不适合由所有BeanPostProcessor接口处理
(例如:不适合自动代理)。

If you have beans wired into your BeanPostProcessor by using autowiring or @Resource (which may fall back to autowiring), Spring might access unexpected beans when searching for type-matching dependency candidates and, therefore, make them ineligible for auto-proxying or other kinds of bean post-processing. For example, if you have a dependency annotated with @Resource where the field or setter name does not directly correspond to the declared name of a bean and no name attribute is used, Spring accesses other beans for matching them by type.

如果您通过使用autowiring或@Resource(这可能会回到autowiring)
将bean连接到BeanPostProcessor中,那么Spring可能会在搜索类型
匹配依赖项候选者时访问其他的bean,从而使它们不符合自动代理或
其他类型的bean post-processing的条件。
例如,如果您有一个注释为@Resource的依赖项,其中字段或setter名称并不直接
对应于bean的声明名称,并且没有使用name属性,那么Spring将访问其他bean
以按类型匹配它们。


The following examples show how to write, register, and use BeanPostProcessor instances in an ApplicationContext.

下面的示例展示了如何在ApplicationContext中编写、注册和使用
BeanPostProcessor实例。

Example: Hello World, BeanPostProcessor-style
示例:Hello World, BeanPostProcessor 样式

This first example illustrates basic usage. The example shows a custom BeanPostProcessor implementation that invokes the toString() method of each bean as it is created by the container and prints the resulting string to the system console.

第一个示例演示了基本用法。示例展示了一个自定义BeanPostProcessor实现,
它在容器创建每个bean时调用该bean的toString()方法,并将结果字符串打印到系统控制台。

The following listing shows the custom BeanPostProcessor implementation class definition:

下面的清单显示了自定义的BeanPostProcessor实现类定义:

package scripting;

import org.springframework.beans.factory.config.BeanPostProcessor;

public class InstantiationTracingBeanPostProcessor implements BeanPostProcessor {

    // simply return the instantiated bean as-is
    public Object postProcessBeforeInitialization(Object bean, String beanName) {
        return bean; // we could potentially return any object reference here...
    }

    public Object postProcessAfterInitialization(Object bean, String beanName) {
        System.out.println("Bean '" + beanName + "' created : " + bean.toString());
        return bean;
    }
}

The following beans element uses the InstantiationTracingBeanPostProcessor:

下面的bean元素使用了InstantiationTracingBeanPostProcessor:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:lang="http://www.springframework.org/schema/lang"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/lang
        https://www.springframework.org/schema/lang/spring-lang.xsd">

    <lang:groovy id="messenger"
            script-source="classpath:org/springframework/scripting/groovy/Messenger.groovy">
        <lang:property name="message" value="Fiona Apple Is Just So Dreamy."/>
    </lang:groovy>

    <!--
    when the above bean (messenger) is instantiated, this custom
    BeanPostProcessor implementation will output the fact to the system console
    -->
    <bean class="scripting.InstantiationTracingBeanPostProcessor"/>

</beans>

Notice how the InstantiationTracingBeanPostProcessor is merely defined. It does not even have a name, and, because it is a bean, it can be dependency-injected as you would any other bean. (The preceding configuration also defines a bean that is backed by a Groovy script. The Spring dynamic language support is detailed in the chapter entitled Dynamic Language Support.)

请注意 InstantiationTracingBeanPostProcessor 是如何定义的。
它甚至没有名称,而且,因为它是一个bean,所以可以像其他bean一样进行依赖注入。
(前面的配置还定义了一个由Groovy脚本支持的bean。
Spring的动态语言支持在名为 Dynamic Language Support 的章节中有详细说明。)

The following Java application runs the preceding code and configuration:

下面的Java应用程序运行前面的代码和配置:

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

public final class Boot {

    public static void main(final String[] args) throws Exception {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("scripting/beans.xml");
        Messenger messenger = ctx.getBean("messenger", Messenger.class);
        System.out.println(messenger);
    }

}

The output of the preceding application resembles the following:

上述应用程序的输出类似如下:

Bean ‘messenger’ created : org.springframework.scripting.groovy.GroovyMessenger@272961
org.springframework.scripting.groovy.GroovyMessenger@272961

Example: The RequiredAnnotationBeanPostProcessor

Using callback interfaces or annotations in conjunction with a custom BeanPostProcessor implementation is a common means of extending the Spring IoC container. An example is Spring’s RequiredAnnotationBeanPostProcessor — a BeanPostProcessor implementation that ships with the Spring distribution and that ensures that JavaBean properties on beans that are marked with an (arbitrary) annotation are actually (configured to be) dependency-injected with a value.

例子:RequiredAnnotationBeanPostProcessor
将回调接口或注释与自定义BeanPostProcessor实现结合使用是扩展
Spring IoC容器的常见方法。
一个例子是Spring的RequiredAnnotationBeanPostProcessor
——一个随Spring发行版附带的BeanPostProcessor实现,
它确保用(任意)注释标记的bean上的JavaBean属性实际上(配置为)依赖注入一个值。

1.8.2. Customizing Configuration Metadata with a BeanFactoryPostProcessor
使用BeanFactoryPostProcessor自定义配置元数据

The next extension point that we look at is the org.springframework.beans.factory.config.BeanFactoryPostProcessor. The semantics of this interface are similar to those of the BeanPostProcessor, with one major difference: BeanFactoryPostProcessor operates on the bean configuration metadata. That is, the Spring IoC container lets a BeanFactoryPostProcessor read the configuration metadata and potentially change it before the container instantiates any beans other than BeanFactoryPostProcessor instances.

我们要查看的下一个扩展点是org.springframework.beans.factory.config.BeanFactoryPostProcessor。
这个接口的语义与BeanPostProcessor类似,但有一个主要区别:
BeanFactoryPostProcessor操作bean配置元数据。
也就是说,Spring IoC容器允许BeanFactoryPostProcessor
在实例化BeanFactoryPostProcessor实例之外的任何bean之前
读取配置元数据并可能更改它。

You can configure multiple BeanFactoryPostProcessor instances, and you can control the order in which these BeanFactoryPostProcessor instances run by setting the order property. However, you can only set this property if the BeanFactoryPostProcessor implements the Ordered interface. If you write your own BeanFactoryPostProcessor, you should consider implementing the Ordered interface, too. See the javadoc of the BeanFactoryPostProcessor and Ordered interfaces for more details.

您可以配置多个BeanFactoryPostProcessor实例,并且您可以通过
设置order属性来控制这些BeanFactoryPostProcessor实例运行的顺序。
但是,您只能在BeanFactoryPostProcessor实现了 Ordered 接口的
情况下设置此属性。
如果您编写自己的BeanFactoryPostProcessor,也应该考虑实现Ordered接口。
有关更多细节,请参阅BeanFactoryPostProcessor和 Ordered 接口的javadoc。

If you want to change the actual bean instances (that is, the objects that are created from the configuration metadata), then you instead need to use a BeanPostProcessor (described earlier in Customizing Beans by Using a BeanPostProcessor). While it is technically possible to work with bean instances within a BeanFactoryPostProcessor (for example, by using BeanFactory.getBean()), doing so causes premature bean instantiation, violating the standard container lifecycle. This may cause negative side effects, such as bypassing bean post processing.

如果希望更改实际bean实例(即从配置元数据创建的对象),则需要使用
BeanPostProcessor
(在前面通过使用BeanPostProcessor自定义bean中进行了描述)。
虽然在BeanFactoryPostProcessor中使用bean实例在技术上是可行的
(例如,通过使用BeanFactory.getBean()),但是这样做会导致过早的bean实例化,
违反标准的容器生命周期。
这可能会导致负面的副作用,比如绕过bean的 post processing 。


premature 
英 /ˈpremətʃə(r)/  美 /ˌpriːməˈtʃʊr,ˌpriːməˈtʊr/ 
adj. 早产的;不成熟的;比预期早的 
n. 早产儿;过早发生的事物

Also, BeanFactoryPostProcessor instances are scoped per-container. This is only relevant if you use container hierarchies. If you define a BeanFactoryPostProcessor in one container, it is applied only to the bean definitions in that container. Bean definitions in one container are not post-processed by BeanFactoryPostProcessor instances in another container, even if both containers are part of the same hierarchy.

另外,BeanFactoryPostProcessor实例的作用域为每个容器。
这只有在使用容器层次结构时才有用。
如果您在一个容器中定义了BeanFactoryPostProcessor,
那么它只应用于该容器中的bean定义。
一个容器中的Bean定义不会被另一个容器中的BeanFactoryPostProcessor
实例进行后处理,即使这两个容器属于同一层次结构。

A bean factory post-processor is automatically executed when it is declared inside an ApplicationContext, in order to apply changes to the configuration metadata that define the container. Spring includes a number of predefined bean factory post-processors, such as PropertyOverrideConfigurer and PropertySourcesPlaceholderConfigurer. You can also use a custom BeanFactoryPostProcessor — for example, to register custom property editors.

当bean工厂 post-processor  在ApplicationContext中声明时,它将自动执行,
以便对定义容器的配置元数据应用更改。
Spring包括许多预定义的bean工厂 post-processors ,
如PropertyOverrideConfigurer和PropertySourcesPlaceholderConfigurer。
您还可以使用自定义BeanFactoryPostProcessor—例如,注册自定义属性编辑器。

An ApplicationContext automatically detects any beans that are deployed into it that implement the BeanFactoryPostProcessor interface. It uses these beans as bean factory post-processors, at the appropriate time. You can deploy these post-processor beans as you would any other bean.

ApplicationContext自动检测部署到其中实现BeanFactoryPostProcessor
接口的任何bean。
在适当的时候,它将这些bean用作bean工厂的post-processors 。
您可以像部署任何其他bean一样部署这些 post-processors  bean。

As with BeanPostProcessors , you typically do not want to configure BeanFactoryPostProcessors for lazy initialization. If no other bean references a Bean(Factory)PostProcessor, that post-processor will not get instantiated at all. Thus, marking it for lazy initialization will be ignored, and the Bean(Factory)PostProcessor will be instantiated eagerly even if you set the default-lazy-init attribute to true on the declaration of your element.

与BeanPostProcessors一样,您通常不希望配置BeanFactoryPostProcessors
为延迟初始化。
如果没有其他bean引用bean(工厂) PostProcessor,则该PostProcessor
根本不会实例化。
因此,将它标记为延迟初始化将被忽略,并且即使在声明您的<beans />元素 
default-lazy-init属性设置为true, Bean(工厂)后处理器也将被快速实例化。


Example: The Class Name Substitution PropertySourcesPlaceholderConfigurer

You can use the PropertySourcesPlaceholderConfigurer to externalize property values from a bean definition in a separate file by using the standard Java Properties format. Doing so enables the person deploying an application to customize environment-specific properties, such as database URLs and passwords, without the complexity or risk of modifying the main XML definition file or files for the container.

示例:类名替换PropertySourcesPlaceholderConfigurer
您可以使用PropertySourcesPlaceholderConfigurer使用标准的Java属性
格式将bean definition中的属性值外部化到单独的文件中。
这样,部署应用程序的人员就可以自定义特定于环境的属性,
比如数据库url和密码,而无需考虑修改主XML定义文件或容器文件的复杂性或风险。

Consider the following XML-based configuration metadata fragment, where a DataSource with placeholder values is defined:

考虑以下基于xml的配置元数据片段,其中定义了具有占位符值的数据源:

<bean class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer">
    <property name="locations" value="classpath:com/something/jdbc.properties"/>
</bean>

<bean id="dataSource" destroy-method="close"
        class="org.apache.commons.dbcp.BasicDataSource">
    <property name="driverClassName" value="${jdbc.driverClassName}"/>
    <property name="url" value="${jdbc.url}"/>
    <property name="username" value="${jdbc.username}"/>
    <property name="password" value="${jdbc.password}"/>
</bean>

The example shows properties configured from an external Properties file. At runtime, a PropertySourcesPlaceholderConfigurer is applied to the metadata that replaces some properties of the DataSource. The values to replace are specified as placeholders of the form ${property-name}, which follows the Ant and log4j and JSP EL style.

示例显示了从外部属性文件配置的属性。
在运行时,PropertySourcesPlaceholderConfigurer应用于替换数据源的
某些属性的元数据。
要替换的值指定为表单${property-name}的占位符,
该表单遵循Ant、log4j和JSP EL风格。

The actual values come from another file in the standard Java Properties format:

实际值来自另一个标准Java属性格式的文件:

jdbc.driverClassName=org.hsqldb.jdbcDriver
jdbc.url=jdbc:hsqldb:hsql://production:9002
jdbc.username=sa
jdbc.password=root

Therefore, the ${jdbc.username} string is replaced at runtime with the value, ‘sa’, and the same applies for other placeholder values that match keys in the properties file. The PropertySourcesPlaceholderConfigurer checks for placeholders in most properties and attributes of a bean definition. Furthermore, you can customize the placeholder prefix and suffix.

因此, ${jdbc.username} 字符串在运行时被替换为值'sa',
对于属性文件中匹配键的其他占位符值也是如此。
PropertySourcesPlaceholderConfigurer检查bean definition 的
大多数属性和属性中的占位符。
此外,还可以自定义占位符前缀和后缀。

With the context namespace introduced in Spring 2.5, you can configure property placeholders with a dedicated configuration element. You can provide one or more locations as a comma-separated list in the location attribute, as the following example shows:

使用Spring 2.5中引入的上下文名称空间,您可以用一个专用的
配置元素配置属性占位符。
您可以在location属性中以逗号分隔的列表形式提供一个或多个位置,
如下面的示例所示:

<context:property-placeholder location="classpath:com/something/jdbc.properties"/>

The PropertySourcesPlaceholderConfigurer not only looks for properties in the Properties file you specify. By default, if it cannot find a property in the specified properties files, it checks against Spring Environment properties and regular Java System properties.

PropertySourcesPlaceholderConfigurer不仅在您指定的属性文件中查找属性。
默认情况下,如果在指定的属性文件中找不到属性,它将检查Spring环境属性和
常规Java系统属性。

You can use the PropertySourcesPlaceholderConfigurer to substitute class names, which is sometimes useful when you have to pick a particular implementation class at runtime. The following example shows how to do so:

您可以使用PropertySourcesPlaceholderConfigurer来替换类名,
当您必须在运行时选择特定的实现类时,这有时很有用。
下面的例子展示了如何做到这一点:

<bean class="org.springframework.beans.factory.config.PropertySourcesPlaceholderConfigurer">
    <property name="locations">
        <value>classpath:com/something/strategy.properties</value>
    </property>
    <property name="properties">
        <value>custom.strategy.class=com.something.DefaultStrategy</value>
    </property>
</bean>

<bean id="serviceStrategy" class="${custom.strategy.class}"/>

If the class cannot be resolved at runtime to a valid class, resolution of the bean fails when it is about to be created, which is during the preInstantiateSingletons() phase of an ApplicationContext for a non-lazy-init bean.

如果不能在运行时将类解析为有效类,则在即将创建bean时,
即在ApplicationContext non-lazy-init bean的 
preInstantiateSingletons()阶段,对bean的解析将失败。

Example: The PropertyOverrideConfigurer

The PropertyOverrideConfigurer, another bean factory post-processor, resembles the PropertySourcesPlaceholderConfigurer, but unlike the latter, the original definitions can have default values or no values at all for bean properties. If an overriding Properties file does not have an entry for a certain bean property, the default context definition is used.

例子:PropertyOverrideConfigurer
PropertyOverrideConfigurer是另一个bean factory post-processor,
它类似于PropertySourcesPlaceholderConfigurer,但与后者不同的是,
原始定义可以有bean属性的默认值,也可以没有值。
如果覆盖属性文件没有特定bean属性的条目,则使用默认上下文定义。

Note that the bean definition is not aware of being overridden, so it is not immediately obvious from the XML definition file that the override configurer is being used. In case of multiple PropertyOverrideConfigurer instances that define different values for the same bean property, the last one wins, due to the overriding mechanism.

请注意,bean definition不知道被覆盖,因此从XML定义文件中不能立即
看出正在使用覆盖配置器。
在多个PropertyOverrideConfigurer实例为同一个bean属性定义不同值的情况
下,由于覆盖机制,最后一个实例胜出。

Properties file configuration lines take the following format:

属性文件配置行采用以下格式:

beanName.property=value

The following listing shows an example of the format:

下面的清单显示了这种格式的一个示例:

dataSource.driverClassName=com.mysql.jdbc.Driver
dataSource.url=jdbc:mysql:mydb

This example file can be used with a container definition that contains a bean called dataSource that has driver and url properties.

这个示例文件可以与一个容器定义一起使用,该容器定义包含一个
名为dataSource的bean,该bean具有驱动程序和url属性。

Compound property names are also supported, as long as every component of the path except the final property being overridden is already non-null (presumably initialized by the constructors). In the following example, the sammy property of the bob property of the fred property of the tom bean is set to the scalar value 123:

框架还支持复合属性名,只要路径的每个组件(除了被覆盖的final属性)都是
非空的(假定由构造函数初始化)。
在下面的示例中,tom bean的fred属性的bob属性的sammy属性被设置为
标量值123:

tom.fred.bob.sammy=123

Specified override values are always literal values. They are not translated into bean references. This convention also applies when the original value in the XML bean definition specifies a bean reference.

指定的重写值总是文字值。它们没有被转换为bean引用。当XML bean定义中的
原始值指定了一个bean引用时,这个约定也适用。

With the context namespace introduced in Spring 2.5, it is possible to configure property overriding with a dedicated configuration element, as the following example shows:

在spring2.5中引入了上下文名称空间,可以用一个专用的配置元素来配置
property override,如下面的例子所示:

<context:property-override location="classpath:override.properties"/>
1.8.3. Customizing Instantiation Logic with a FactoryBean
1.8.3. 使用FactoryBean自定义实例化逻辑

You can implement the org.springframework.beans.factory.FactoryBean interface for objects that are themselves factories.

您可以实现org.springframework.beans.factory.FactoryBean 
为本身是工厂的对象提供接口。

The FactoryBean interface is a point of pluggability into the Spring IoC container’s instantiation logic. If you have complex initialization code that is better expressed in Java as opposed to a (potentially) verbose amount of XML, you can create your own FactoryBean, write the complex initialization inside that class, and then plug your custom FactoryBean into the container.

FactoryBean接口是Spring IoC容器实例化逻辑的可插入点。
如果您有复杂的初始化代码(用Java来表达比(可能)冗长的XML更好),
那么您可以创建自己的FactoryBean,在类中编写复杂的初始化,
然后将定制的FactoryBean插入到容器中。

The FactoryBean interface provides three methods:

FactoryBean接口提供了三种方法:

  • Object getObject(): Returns an instance of the object this factory creates. The instance can possibly be shared, depending on whether this factory returns singletons or prototypes.
* Object getObject():返回工厂创建的对象的实例。
实例可能被共享,这取决于这个工厂返回的是单例还是原型。

  • boolean isSingleton(): Returns true if this FactoryBean returns singletons or false otherwise.
* boolean isSingleton():如果FactoryBean返回singletons类型,返回true;否则返回false。

  • Class getObjectType(): Returns the object type returned by the getObject() method or null if the type is not known in advance.
Class getObjectType():返回getObject()方法返回的对象类型,
如果事先不知道该类型,则返回null。

The FactoryBean concept and interface is used in a number of places within the Spring Framework. More than 50 implementations of the FactoryBean interface ship with Spring itself.

FactoryBean的概念和接口在Spring框架的许多地方使用。
Spring本身附带了50多个FactoryBean接口的实现。

When you need to ask a container for an actual FactoryBean instance itself instead of the bean it produces, preface the bean’s id with the ampersand symbol (&) when calling the getBean() method of the ApplicationContext. So, for a given FactoryBean with an id of myBean, invoking getBean(“myBean”) on the container returns the product of the FactoryBean, whereas invoking getBean("&myBean") returns the FactoryBean instance itself.

当您需要向容器请求实际的FactoryBean实例本身而不是它生成的bean时,
在调用ApplicationContext的getBean()方法时,在bean的id之前加上&符号 。
因此,对于id为myBean的给定FactoryBean,
在容器上调用getBean(“myBean”)返回FactoryBean的产品,
而调用getBean("&myBean") 返回FactoryBean实例本身。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了小程序应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值