日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

環境:Spring5.3.10


通常,應用程序開發人員不需要對ApplicationContext實現類進行子類化。相反,SpringIOC容器可以通過插入特殊集成接口的實現來擴展。

使用BeanPostProcessor自定義bean

BeanPostProcessor接口定義回調方法,你可以實現這些方法來提供自己的(或覆蓋容器的默認)實例化邏輯、依賴項解析邏輯等。如果希望在Spring容器完成bean的實例化、配置和初始化后實現一些自定義邏輯,可以編寫一個或多個自定義BeanPostProcessor實現。

你可以配置多個BeanPostProcessor實例,并且可以通過設置order屬性來控制這些BeanPostProcessor實例的運行順序。僅當BeanPostProcessor實現Ordered接口時,才能設置此屬性。如果編寫自己的BeanPostProcessor,也應該考慮實現有序接口。

BeanPostProcessor實例對bean(或對象)實例進行操作。也就是說,SpringIoC容器實例化一個bean實例,然后BeanPostProcessor實例執行它們的工作。

BeanPostProcessor實例的作用域為每個容器。這僅在使用容器層次結構時才相關。如果在一個容器中定義BeanPostProcessor,它將只對該容器中的bean進行后期處理。換句話說,一個容器中定義的bean不會被另一個容器中定義的BeanPostProcessor后處理,即使兩個容器都是同一層次結構的一部分。

要更改實際的bean定義(即定義bean的藍圖),您需要使用BeanFactoryPostProcessor,如使用BeanFactoryPostProcessor自定義配置元數據中所述。


org.springframework.beans.factory.config.BeanPostProcessor接口正好由兩個回調方法組成。當此類類在容器中注冊為后處理器時,對于容器創建的每個bean實例,后處理器在調用容器初始化方法(如InitializingBean.afterPropertiesSet()或任何聲明的init方法)之前都會從容器中獲取回調,在任何bean初始化回調之后。后處理器可以對bean實例執行任何操作,包括完全忽略回調。bean后處理器通常檢查回調接口,或者用代理包裝bean。一些SpringAOP基礎設施類被實現為bean后處理器,以提供代理包裝邏輯。

ApplicationContext自動檢測在實現BeanPostProcessor接口的配置元數據中定義的任何bean。ApplicationContext將這些bean注冊為后處理器,以便稍后在創建bean時調用它們。Bean后處理器可以像其他Bean一樣部署在容器中。

注意: 當在配置類上使用@Bean factory方法聲明BeanPostProcessor時,工廠方法的返回類型應該是實現類本身,或者至少是
org.springframework.beans.factory.config.BeanPostProcessor接口,清楚地指示該Bean的后處理器性質。否則,ApplicationContext無法在完全創建它之前按類型自動檢測它。由于BeanPostProcessor需要盡早實例化,以便應用于上下文中其他bean的初始化,因此這種早期類型檢測至關重要。

以編程方式注冊BeanPostProcessor實例

雖然推薦的BeanPostProcessor注冊方法是通過ApplicationContext自動檢測(如前所述),但你可以使用addBeanPostProcessor方法以編程方式針對可配置的BeanFactory注冊它們。當您需要在注冊之前評估條件邏輯,甚至在層次結構中跨上下文復制bean后處理器時,這非常有用。但是,請注意,以編程方式添加的BeanPostProcessor實例不遵循有序接口。在這里,登記的順序決定了執行的順序。還請注意,以編程方式注冊的BeanPostProcessor實例總是在通過自動檢測注冊的實例之前進行處理,而不考慮任何顯式順序。

BeanPostProcessor實例和AOP自動代理

實現BeanPostProcessor接口的類是特殊的,容器會對它們進行不同的處理。作為ApplicationContext特殊啟動階段的一部分,所有直接引用的BeanPostProcessor實例和bean都在啟動時實例化。接下來,以排序方式注冊所有BeanPostProcessor實例,并將其應用于容器中的所有其他bean。因為AOP自動代理是作為BeanPostProcessor本身實現的,所以無論是BeanPostProcessor實例還是它們直接引用的Bean都不符合自動代理的條件,因此,它們沒有編織方面。

對于任何這樣的bean,您都應該看到一條信息性日志消息:bean someBean不符合由所有BeanPostProcessor接口處理的條件(例如:不符合自動代理的條件)。

如果您使用autowiring或@Resource(可能會返回到autowiring)將bean連接到BeanPostProcessor中,Spring在搜索類型匹配的依賴項候選項時可能會訪問意外的bean,因此,使它們不符合自動代理或其他類型的bean后處理的條件。例如,如果你有一個用@Resource注釋的依賴項,其中字段或setter名稱不直接對應于bean的聲明名稱,并且沒有使用name屬性,那么Spring將訪問其他bean以按類型匹配它們。

示例:

該示例顯示了一個自定義BeanPostProcessor實現,該實現在容器創建每個bean時調用其toString()方法,并將結果字符串打印到系統控制臺。

@Component
public class InstantiationTracingBeanPostProcessor implements BeanPostProcessor {

  // 只需按原樣返回實例化的bean
  public Object postProcessBeforeInitialization(Object bean, String beanName) {
    return bean; // 我們可能會在這里返回任何對象引用。。。
  }

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

AutowiredAnnotationBeanPostProcessor

將回調接口或注釋與自定義BeanPostProcessor實現結合使用是擴展Spring IOC容器的常用方法。Spring的
AutowiredAnnotationBeanPostProcessor就是一個例子 — BeanPostProcessor實現。

使用BeanFactoryPostProcessor自定義配置元數據

下一個擴展點是
org.springframework.beans.factory.config.BeanFactoryPostProcessor。此接口的語義與BeanPostProcessor的語義相似,但有一個主要區別:BeanFactoryPostProcessor操作bean配置元數據。也就是說,SpringIoC容器允許BeanFactoryPostProcessor讀取配置元數據,并在容器實例化除BeanFactoryPostProcessor實例之外的任何Bean之前可能對其進行更改。

你可以配置多個BeanFactoryPostProcessor實例,并且可以通過設置order屬性來控制這些BeanFactoryPostProcessor實例的運行順序。但是,僅當BeanFactoryPostProcessor實現有序接口時,才能設置此屬性。如果編寫自己的BeanFactoryPostProcessor,也應該考慮實現有序接口。

如果你想要更改實際的bean實例(即,從配置元數據創建的對象),那么您需要使用BeanPostProcessor(前面在使用BeanPostProcessor定制bean中描述)。雖然在技術上可以在BeanFactoryPostProcessor中使用bean實例(例如,通過使用BeanFactory.getBean()),但這樣做會導致過早的bean實例化,違反標準容器生命周期。這可能會導致負面的副作用,例如繞過bean后處理。

此外,BeanFactoryPostProcessor實例的作用域為每個容器。這僅在使用容器層次結構時才相關。如果在一個容器中定義BeanFactoryPostProcessor,則它僅應用于該容器中的bean定義。一個容器中的Bean定義不會由另一個容器中的BeanFactoryPostProcessor實例進行后處理,即使兩個容器都是同一層次結構的一部分。

bean工廠后處理器在ApplicationContext中聲明時自動運行,以便對定義容器的配置元數據應用更改。Spring包括許多預定義的bean factory后處理器,如
PropertyOverrideConfiguler和PropertySourcePlaceHolderConfigurer。你還可以使用自定義BeanFactoryPostProcessor — 例如,注冊自定義屬性編輯器。

ApplicationContext自動檢測部署到其中實現BeanFactoryPostProcessor接口的任何Bean。它在適當的時候將這些bean用作bean工廠的后處理器。你可以像部署任何其他bean一樣部署這些后處理器bean。

屬性占位符替換PropertySourcesPlaceholderConfigurer

通過使用標準JAVA屬性格式,你可以使用
PropertySourcesPlaceholderConfigurer將bean定義中的屬性值外部化到單獨的文件中。這樣做使部署應用程序的人員能夠自定義特定于環境的屬性,例如數據庫URL和密碼,而無需修改容器的主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>

運行時,
PropertySourcesPlaceholderConfigurer應用于替換數據源某些屬性的元數據。要替換的值被指定為形式${property name}的占位符,它遵循Ant、log4j和JSP EL樣式。

實際值來自標準Java屬性格式的properties文件:

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

自定義BeanFactoryPostProcessor

public class CustomBeanFactoryPostProcessor implements BeanFactoryPostProcessor {

  @Override
  public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
    // 獲取Person的BeanDefinition對象,修改屬性name的值。
    BeanDefinition beanDefinition = beanFactory.getBeanDefinition("person") ;
    beanDefinition.getPropertyValues().addPropertyValue("name", "CNM") ;
    System.out.println("BeanFactoryPostProcessor") ;
  }

}

使用FactoryBean自定義實例化邏輯

你可以為本身就是工廠的對象實現
org.springframework.beans.factory.FactoryBean接口。

FactoryBean接口是Spring IoC容器實例化邏輯的一個可插拔點。如果你的復雜初始化代碼更好地用Java表示,而不是(可能)冗長的XML,那么你可以創建自己的FactoryBean,在該類中編寫復雜的初始化,然后將自定義FactoryBean插入容器。

FactoryBean<T> 接口提供三種方法:

  • T getObject(): 返回此工廠創建的對象的實例。實例可能是共享的,這取決于此工廠返回的是單例還是原型。
  • boolean isSingleton(): 如果此FactoryBean返回Singleton,則返回true,否則返回false。此方法的默認實現返回true。
  • Class<?> getObjectType(): 返回getObject()方法返回的對象類型,如果類型事先未知,則返回null。

FactoryBean概念和接口在Spring框架中的許多地方都有使用。超過50個FactoryBean接口的實現與Spring本身一起提供。

當你需要向容器請求一個實際的FactoryBean實例本身而不是它生成的bean時,在調用ApplicationContext的getBean()方法時,用符號(&)作為bean id的前綴。因此,對于id為myBean的給定FactoryBean,在容器上調用getBean("myBean")將返回FactoryBean的產品,而調用getBean("&myBean")將返回FactoryBean實例本身。

 

完畢!!!

分享到:
標簽:Spring
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定