Spring 5.0.0框架介紹_中英文對照_3.8

文章作者:Tyan
博客:noahsnail.com ?|? CSDN ?|? 簡書

3.8 Container Extension Points

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.

通常情況下泻轰,應(yīng)用開發(fā)者不需要繼承ApplicationContext的實現(xiàn)類友雳。反而是Spring的IoC容器可以通過插入特定集成接口的實現(xiàn)來進行擴展仪搔。下面幾節(jié)將描述這些集成接口。

3.8.1 Customizing beans using a BeanPostProcessor

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 BeanPostProcessor implementations.

BeanPostProcessor接口定義了回調(diào)方法,你可以實現(xiàn)這個方法來提供你自己的(或覆蓋容器默認的)實例化邏輯莫换,依賴解析邏輯等等。如果你想在Spring容器完成實例化没讲,配置和初始化bean之后實現(xiàn)一些定制的業(yè)務(wù)邏輯轰驳,你可以插入一個或多個BeanPostProcessor實現(xiàn)厚掷。

You can configure multiple BeanPostProcessor instances, and you can control the order in which these BeanPostProcessors 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, consult the javadocs of the BeanPostProcessor and Ordered interfaces. See also the note below on programmatic registration of BeanPostProcessors.

你可以配置多個BeanPostProcessor實例,通過設(shè)置order屬性你可以控制BeanPostProcessors的執(zhí)行順序级解。只有BeanPostProcessor實現(xiàn)了Ordered接口時你才可以設(shè)置這個屬性冒黑;如果你編寫了你自己的BeanPostProcessor,你也應(yīng)該考慮實現(xiàn)Ordered接口勤哗。更多細節(jié)請參考BeanPostProcessor接口和Ordered接口的Java文檔抡爹。也可以查看下面的BeanPostProcessors編程注冊的筆記。

BeanPostProcessors operate on bean (or object) instances; that is to say, the Spring IoC container instantiates a bean instance and then BeanPostProcessors do their work.

BeanPostProcessors are scoped per-container. This is only relevant if you are using container hierarchies. If you define a BeanPostProcessor in one container, it will only post-process 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.

To change the actual bean definition (i.e., the blueprint that defines the bean), you instead need to use a BeanFactoryPostProcessor as described in Section 3.8.2, “Customizing configuration metadata with a BeanFactoryPostProcessor”.

?

BeanPostProcessors操作一個bean(或?qū)ο螅嵗⒒灰簿褪钦f冬竟,Spring Ioc容器實例化一個bean實例,然后BeanPostProcessors完成它們的工作民逼。

BeanPostProcessors的作用域是每個容器泵殴。只有你在使用容器分層的情況下,這才是相關(guān)的拼苍。如果你在一個容器中定義了一個BeanPostProcessor笑诅,它將只后處理容器中的beans。換句話說,某個容器中定義的beans不能被另一個容器中定義的BeanPostProcessor進行后處理吆你,即使這兩個容器是同一層上的一部分弦叶。

為了改變實際的bean定義(例如,定義bean的藍圖)妇多,你可以使用3.8.2小節(jié)中描述的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’s afterPropertiesSet() and any declared init method) are called as well as 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 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接口包含恰好兩個回調(diào)方法。當(dāng)這樣一個類在容器中注冊為后處理器時砌梆,對于容器中創(chuàng)建的每一個bean實例默责,在容器初始化方法(例如InitializingBeanafterPropertiesSet()方法和任何已聲明的初始化方法)被調(diào)用之前和任何bean初始化回調(diào)函數(shù)之后,后處理器會從容器中得到一個回調(diào)函數(shù)咸包。后處理器可以對bean實例進行任何操作,包括完全忽略回調(diào)方法杖虾。bean后處理器通常檢查回調(diào)接口或?qū)ean包裹到代理中烂瘫。為了提供代理包裹邏輯,一些Spring AOP基礎(chǔ)結(jié)構(gòu)類被實現(xiàn)為bean后處理器奇适。

An ApplicationContext automatically detects any beans that are defined in the configuration metadata which implement 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 just like any other beans.

ApplicationContext會自動檢測任何配置元數(shù)據(jù)中定義的實現(xiàn)了BeanPostProcessor接口的bean坟比。為了能在后面bean創(chuàng)建時調(diào)用這些bean,ApplicationContext會將這些bean注冊為后處理器嚷往。bean后處理器可以像其它bean一樣在容器進行部署葛账。

Note that when declaring a BeanPostProcessor 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 won’t be able to 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.

注意當(dāng)在一個配置類上使用@Bean聲明一個BeanPostProcessor時,工廠方法的返回值應(yīng)該是實現(xiàn)類本身或是org.springframework.beans.factory.config.BeanPostProcessor接口皮仁,這能清晰的表明bean的后處理器特性籍琳。此外,在完整的創(chuàng)建它之前贷祈,ApplicationContext不能通過類型自動檢測它趋急。由于BeanPostProcessor需要早一點實例化,為了在上下文中初始化其它的beans势誊,早期的類型檢測是非常關(guān)鍵的呜达。

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

?

雖然推薦的注冊BeanPostProcessor的方法是通過ApplicationContext自動檢測(像前面描述的那樣),但也可以通過以編程方法通過使用ConfigurableBeanFactoryaddBeanPostProcessor方法來注冊粟耻。在注冊之前需要評估條件邏輯時查近,這是非常有用的,或者通過分層中的上下文來復(fù)制bean后處理器挤忙。注意以編程方式添加的BeanPostProcessors不需要Ordered接口霜威。這種情況下注冊順序意味著執(zhí)行順序。注意以編程方式注冊的BeanPostProcessors中是在那些通過自動檢測注冊的BeanPostProcessors之前進行處理饭玲,不管任何顯式的順序指定侥祭。

?

Classes that implement the BeanPostProcessor interface are special and are treated differently by the container. All BeanPostProcessors and beans that they reference directly are instantiated on startup, as part of the special startup phase of the ApplicationContext. Next, all BeanPostProcessors 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 BeanPostProcessors nor the beans they reference directly are eligible for auto-proxying, and thus do not have aspects woven into them.

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

Note that if you have beans wired into your BeanPostProcessor 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/setter name does not directly correspond to the declared name of a bean and no name attribute is used, then Spring will access other beans for matching them by type.

?

實現(xiàn)BeanPostProcessor接口的類是特別的并被容器不同對待。所有的BeanPostProcessors和它們直接引用的beans在啟動時進行實例化,它們是ApplicationContext特定啟動階段的一部分矮冬。接下來谈宛,所有BeanPostProcessors以有序形式進行注冊,并適用于容器中所有更進一步的beans胎署。由于AOP自動代理是作為BeanPostProcessor本身實現(xiàn)的吆录,既不是BeanPostProcessors也不是它們直接引用的beans適合進行自動代理,因此沒有融入它們的方面琼牧。

對于這樣的bean恢筝,你應(yīng)該看到一個信息日志消息:"Bean foo沒資格被所有的BeanPostProcessor接口進行處理(例如,不適合自動代理)巨坊。"撬槽。

注意如果有beans使用自動裝配或@Resource(可能回到自動裝配)注入你的BeanPostProcessor,當(dāng)搜索類型匹配的依賴候選者時趾撵,Spring可能訪問未預(yù)料到beans侄柔,因此使它們不適合自動代理或其他類型的進行后處理的bean。例如占调,如果你有一個帶有@Resource注解的依賴暂题,field/setter名稱不能直接對應(yīng)bean聲明的名字,也沒有使用name特性究珊,Spring將通過類型匹配來訪問其它的bean薪者。

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

下面的例子展示了在ApplicationContext中如何編寫,注冊和使用BeanPostProcessors剿涮。

Example: Hello World, BeanPostProcessor-style

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實現(xiàn),實現(xiàn)中調(diào)用了每一個bean的toString()方法幔虏。當(dāng)容器創(chuàng)建它時纺念,會將結(jié)果字符串輸出到系統(tǒng)控制臺。

Find below the custom BeanPostProcessor implementation class definition:

下面是定制BeanPostProcessor實現(xiàn)的類定義:

package scripting;

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

public class InstantiationTracingBeanPostProcessor implements BeanPostProcessor {

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

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

}
<?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
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/lang
        http://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 simply defined. It does not even have a name, and because it is a bean it can be dependency-injected just like 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 Chapter 31, Dynamic language support.)

注意InstantiationTracingBeanPostProcessor是怎樣簡單定義的想括。它甚至沒有一個名字陷谱,因為它是一個bean,它能像其它bean一樣進行依賴注入瑟蜈。(前面的配置也定義了一個bean烟逊,它被Groovy腳本支持。Spring動態(tài)語言支持在31章『動態(tài)語言支持』中進行了詳細描述铺根。)

The following simple Java application executes the preceding code and configuration:

下面的簡單Java應(yīng)用執(zhí)行了前面的代碼和配置:

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 = (Messenger) ctx.getBean("messenger");
        System.out.println(messenger);
    }

}

The output of the preceding application resembles the following:

前面的應(yīng)用輸出結(jié)果如下:

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 which ensures that JavaBean properties on beans that are marked with an (arbitrary) annotation are actually (configured to be) dependency-injected with a value.

使用回調(diào)函數(shù)接口或注解結(jié)合定制BeanPostProcessor實現(xiàn)是擴展Spring IoC容器的常見方法宪躯。一個例子是Spring的RequiredAnnotationBeanPostProcessor——一個BeanPostProcessor實現(xiàn)附帶在Spring發(fā)行中,它保證了標記有(任意)注解的beans上的JavaBean屬性能真正(配置成)通過值進行依賴注入位迂。

3.8.2 Customizing configuration metadata with a BeanFactoryPostProcessor

The next extension point that we will 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 allows a BeanFactoryPostProcessor to read the configuration metadata and potentially change it before the container instantiates any beans other than BeanFactoryPostProcessors.

接下來我們要看到的擴展點是org.springframework.beans.factory.config.BeanFactoryPostProcessor访雪。這個接口的語義與那些BeanPostProcessor類似详瑞,但有一個主要的不同:BeanFactoryPostProcessor可以操作配置元數(shù)據(jù);也就是說臣缀,Spring IoC容器允許在容器實例化除了BeanFactoryPostProcessor之外的任何beans之前坝橡,BeanFactoryPostProcessor讀取配置元數(shù)據(jù)并可能修改它們。

You can configure multiple BeanFactoryPostProcessors, and you can control the order in which these BeanFactoryPostProcessors execute 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. Consult the javadocs of the BeanFactoryPostProcessor and Ordered interfaces for more details.

你可以配置多個BeanFactoryPostProcessors精置,你可以通過設(shè)置order屬性來控制這些BeanFactoryPostProcessors的執(zhí)行順序计寇。但是,只有BeanFactoryPostProcessor實現(xiàn)了Ordered接口時你才可以設(shè)置這個屬性脂倦。如果你編寫了你自己的BeanFactoryPostProcessor番宁,你也應(yīng)該考慮實現(xiàn)Ordered接口。關(guān)于BeanFactoryPostProcessorOrdered的更多細節(jié)請看文檔赖阻。

If you want to change the actual bean instances (i.e., the objects that are created from the configuration metadata), then you instead need to use a BeanPostProcessor (described above in Section 3.8.1, “Customizing beans using a BeanPostProcessor”). While it is technically possible to work with bean instances within a BeanFactoryPostProcessor (e.g., 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.

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

?

如果你想改變真正的bean實例(例如蝶押,從配置元數(shù)據(jù)中創(chuàng)建的對象),你應(yīng)該需要使用BeanPostProcessor(3.8.1小節(jié)中描述的)政供。盡管在BeanFactoryPostProcessor中處理bean實例在技術(shù)上是可能的(例如使用BeanFactory.getBean())播聪,但這樣做會引起過早的bean實例化,違背標準的容器生命周期布隔。這可能會產(chǎn)生負面影響例如繞過bean后處理。

BeanFactoryPostProcessors的作用域也是在每個容器中稼虎。這僅對于容器分層而言衅檀。如果在一個容器中你定義了一個BeanFactoryPostProcessor,它將適用于那個容器中的bean定義霎俩。一個容器中的bean定義不能被另一個容器中的BeanFactoryPostProcessors進行后處理哀军,即使兩個容器是在同一個分層中。

A bean factory post-processor is executed automatically 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 PropertyPlaceholderConfigurer. A custom BeanFactoryPostProcessor can also be used, for example, to register custom property editors.

為了修改定義在容器中的配置元數(shù)據(jù)打却,當(dāng)一個bean工廠后處理器在ApplicationContext中聲明時杉适,它會自動執(zhí)行。Spring包含許多預(yù)先定義的bean工廠后處理器柳击,例如PropertyOverrideConfigurerPropertyPlaceholderConfigurer猿推。定制的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會自動檢測任何部署在它之內(nèi)的實現(xiàn)了BeanFactoryPostProcessor接口的bean。在合適的時間状知,它會使用這些beans作為bean工廠后處理器秽五。你可以像任何你使用的bean那樣部署這些后處理器beans。

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 trueon the declaration of your <beans/> element.

?

關(guān)于BeanPostProcessors, 通常情況下你不想配置BeanFactoryPostProcessors為延遲初始化饥悴。 如果沒有別的bean引用Bean(Factory)PostProcessor坦喘,后處理器將不會實例化盲再。因此,對它進行延遲初始化會被忽略瓣铣,即使你將<beans/>元素中的default-lazy-init特性設(shè)置為true答朋,Bean(Factory)PostProcessor也會急切的初始化。

Example: the Class name substitution PropertyPlaceholderConfigurer

You use the PropertyPlaceholderConfigurer to externalize property values from a bean definition in a separate file 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.

你可以使用PropertyPlaceholderConfigurer讀取單獨文件中的bean定義來使屬性具體化坯沪,這個單獨文件使用標準的Java Properties格式绿映。這樣做可以在部署應(yīng)用時定制特定環(huán)境屬性例如數(shù)據(jù)庫URLs和密碼,沒有復(fù)雜性或修改主XML定義文件及容器相關(guān)文件的風(fēng)險腐晾。

Consider the following XML-based configuration metadata fragment, where a DataSource with placeholder values is defined. The example shows properties configured from an external Properties file. At runtime, a PropertyPlaceholderConfigurer is applied to the metadata that will replace some properties of the DataSource. The values to replace are specified as placeholders of the form ${property-name} which follows the Ant/log4j/JSP EL style.

考慮一下下面的基于XML定義的配置元數(shù)據(jù)片段叉弦,其中定義了一個帶有占位符的DataSource。這個例子展示了從外部Properties文件進行屬性配置藻糖。在運行時淹冰,PropertyPlaceholderConfigurer會應(yīng)用到元數(shù)據(jù)中,將會替換DataSource中的一些屬性巨柒。通過${property-name}形式的占位符指定要替換的值樱拴,這遵循了Ant/log4j/JSP EL風(fēng)格。

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="locations" value="classpath:com/foo/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 actual values come from another file in the standard Java Properties format:

真正的屬性值來自于另一個以標準Java Properties形式編寫的文件:

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

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

因此洋满,在運行是字符串${jdbc.username}被替換為sa晶乔,其它的匹配屬性文件中的key的占位符的值以同樣方式替換。PropertyPlaceholderConfigurer會檢查bean中大多數(shù)屬性和特性的占位符牺勾。此外正罢,占位符的前綴和后綴都可以定制。

With the context namespace introduced in Spring 2.5, it is possible to configure property placeholders with a dedicated configuration element. One or more locations can be provided as a comma-separated list in the location attribute.

Spring 2.5中引入了上下文命名空間驻民,可以通過專用配置元素配置屬性占位符翻具。在location特性可以提供一個或多個位置,多個位置用逗號分開回还。

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

The PropertyPlaceholderConfigurer not only looks for properties in the Properties file you specify. By default it also checks against the Java System properties if it cannot find a property in the specified properties files. You can customize this behavior by setting the systemPropertiesMode property of the configurer with one of the following three supported integer values:

  • never (0): Never check system properties

  • fallback (1): Check system properties if not resolvable in the specified properties files. This is the default.

  • override (2): Check system properties first, before trying the specified properties files. This allows system properties to override any other property source.

PropertyPlaceholderConfigurer不僅僅查找指定Properties文件中的屬性裆泳。默認情況下,如果不能在指定屬性文件中找到屬性柠硕,它也檢查Java System屬性工禾。你可以通過下面三個支持的整數(shù)值中的一個設(shè)置配置器的systemPropertiesMode屬性,從而定制查找行為仅叫。

  • never (0): 從不檢查system屬性

  • fallback (1): 如果不能在指定文件中解析屬性帜篇,檢查system屬性,這是默認值诫咱。

  • override (2): 在查找指定文件之前笙隙,首先檢查system屬性,這可以使系統(tǒng)屬性覆蓋任何其它屬性源坎缭。

Consult the PropertyPlaceholderConfigurer javadocs for more information.

更多信息請看PropertyPlaceholderConfigurer文檔竟痰。

You can use the PropertyPlaceholderConfigurer to substitute class names, which is sometimes useful when you have to pick a particular implementation class at runtime. For example:

你可以PropertyPlaceholderConfigurer替換類名签钩,有時候非常有用,特別是運行時你必須選擇一個特別的實現(xiàn)類的情況下坏快。例如:

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="locations">
        <value>classpath:com/foo/strategy.properties</value>
    </property>
    <property name="properties">
        <value>custom.strategy.class=com.foo.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,當(dāng)它要創(chuàng)建時莽鸿,在ApplicationContextpreInstantiateSingletons()期間昧旨,bean會解析失敗。

Example: the PropertyOverrideConfigurer

The PropertyOverrideConfigurer, another bean factory post-processor, resembles the PropertyPlaceholderConfigurer, 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祥得,另一個bean工廠后處理器兔沃,類似于PropertyPlaceholderConfigurer,但不像后者级及,最初的定義可以有默認值或bean屬性一點也沒有值乒疏。如果一個覆寫的Properties文件對于某個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定義沒有意識到被覆寫了怕吴,因此從XML定義文件中它不能立刻很明顯的看出在使用覆寫的配置器。為了防止多個PropertyOverrideConfigurer實例對于同一個bean屬性定義不同的值县踢,根據(jù)覆寫機制转绷,使用最后一個定義的值。

Properties file configuration lines take this format:

屬性文件配置形式如下:

beanName.property=value

For example:

例如:

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, which has driver and url properties.

例子文件可以被包含名為dataSource bean的容器定義使用硼啤,它有一個driverurl屬性暇咆。

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 this example…?

混合屬性命名也支持,除了最后被覆寫的屬性丙曙,只要路徑的每部分都已經(jīng)是非空(假設(shè)構(gòu)造函數(shù)進行初始化)。在這個例子中:

foo.fred.bob.sammy=123

the sammy property of the bob property of the fred property of the foo bean is set to the scalar value 123.

foo bean中的fred屬性的bob屬性的sammy屬性設(shè)為標量值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.

?

指定的覆寫值總是字面值亏镰;它們不能轉(zhuǎn)成bean引用。當(dāng)XML bean定義中的初始值指定了一個bean引用時拯爽,這個規(guī)范同樣有效索抓。

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

Spring 2.5引入了上下文命名空間,可以用專用配置元素配置屬性覆寫:

<context:property-override location="classpath:override.properties"/>

3.8.3 Customizing instantiation logic with a FactoryBean

Implement the org.springframework.beans.factory.FactoryBean interface for objects that are themselves factories.

為對象實現(xiàn)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的實例化邏輯可插入性的一個點逼肯。如果你有復(fù)雜的初始化代碼,相比于大量的冗余的XML代碼用Java語言來表達會更好桃煎,那么你可以創(chuàng)建你自己的FactoryBean篮幢,在類里面編寫復(fù)雜的初始化邏輯,并將你定制的FactoryBean插入到容器中为迈。

The FactoryBean interface provides three methods:

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

  • boolean isSingleton(): returns true if this FactoryBean returns singletons, false otherwise.

  • Class getObjectType(): returns the object type returned by the getObject() method or null if the type is not known in advance.

FactoryBean接口提供了三個方法:

  • Object getObject(): 返回一個工廠創(chuàng)建的對象實例三椿。這個實例可能被共享缺菌, 依賴于工廠是否返回一個單例或原型。

  • boolean isSingleton(): 如果FactoryBean返回單例搜锰,返回true伴郁,否則返回false。

  • 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接口的實現(xiàn)狈涮。

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.

當(dāng)你需要向容器請求一個真正的FactoryBean實例本身來代替它產(chǎn)生的bean時狐胎,調(diào)用ApplicationContextgetBean()方法時,bean的id前面要加上一個$符薯嗤。因此給定一個id為myBeanFactoryBean顽爹,在容器中調(diào)用getBean("myBean"),返回FactoryBean的產(chǎn)品骆姐,但調(diào)用getBean("&myBean")會返回FactoryBean實例本身镜粤。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市玻褪,隨后出現(xiàn)的幾起案子肉渴,更是在濱河造成了極大的恐慌,老刑警劉巖带射,帶你破解...
    沈念sama閱讀 206,126評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件同规,死亡現(xiàn)場離奇詭異,居然都是意外死亡窟社,警方通過查閱死者的電腦和手機券勺,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來灿里,“玉大人关炼,你說我怎么就攤上這事∠坏酰” “怎么了儒拂?”我有些...
    開封第一講書人閱讀 152,445評論 0 341
  • 文/不壞的土叔 我叫張陵,是天一觀的道長色鸳。 經(jīng)常有香客問我社痛,道長,這世上最難降的妖魔是什么命雀? 我笑而不...
    開封第一講書人閱讀 55,185評論 1 278
  • 正文 為了忘掉前任蒜哀,我火速辦了婚禮,結(jié)果婚禮上咏雌,老公的妹妹穿的比我還像新娘凡怎。我一直安慰自己校焦,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 64,178評論 5 371
  • 文/花漫 我一把揭開白布统倒。 她就那樣靜靜地躺著寨典,像睡著了一般。 火紅的嫁衣襯著肌膚如雪房匆。 梳的紋絲不亂的頭發(fā)上耸成,一...
    開封第一講書人閱讀 48,970評論 1 284
  • 那天,我揣著相機與錄音浴鸿,去河邊找鬼井氢。 笑死,一個胖子當(dāng)著我的面吹牛岳链,可吹牛的內(nèi)容都是我干的花竞。 我是一名探鬼主播,決...
    沈念sama閱讀 38,276評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼掸哑,長吁一口氣:“原來是場噩夢啊……” “哼约急!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起苗分,我...
    開封第一講書人閱讀 36,927評論 0 259
  • 序言:老撾萬榮一對情侶失蹤厌蔽,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后摔癣,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體奴饮,經(jīng)...
    沈念sama閱讀 43,400評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,883評論 2 323
  • 正文 我和宋清朗相戀三年择浊,在試婚紗的時候發(fā)現(xiàn)自己被綠了戴卜。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 37,997評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡琢岩,死狀恐怖叉瘩,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情粘捎,我是刑警寧澤,帶...
    沈念sama閱讀 33,646評論 4 322
  • 正文 年R本政府宣布危彩,位于F島的核電站攒磨,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏汤徽。R本人自食惡果不足惜娩缰,卻給世界環(huán)境...
    茶點故事閱讀 39,213評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望谒府。 院中可真熱鬧拼坎,春花似錦浮毯、人聲如沸辕万。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,204評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽鉴嗤。三九已至盛龄,卻和暖如春饰迹,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背余舶。 一陣腳步聲響...
    開封第一講書人閱讀 31,423評論 1 260
  • 我被黑心中介騙來泰國打工啊鸭, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人匿值。 一個月前我還...
    沈念sama閱讀 45,423評論 2 352
  • 正文 我出身青樓赠制,卻偏偏與公主長得像,于是被迫代替她去往敵國和親挟憔。 傳聞我的和親對象是個殘疾皇子钟些,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,722評論 2 345

推薦閱讀更多精彩內(nèi)容