java建立bean並註冊到spring中
從Spring 3.0開始,增加了一種新的途徑來配置Bean Definition,這就是通過Java Code配置Bean Definition。
與XML和Annotation兩種配置方式不同點在於:
前兩種方式XML和Annotation的配置方式為預定義方式,即開發人員通過XML檔案或者Annotation預定義配置Bean的各種屬性後,啟動Spring容器,Spring容器會首先解析這些配置屬性,生成對應的Bean Definition,裝入到DefaultListtableBeanFactory物件的屬性容器中,以此同時,Spring框架也會定義內部使用的Bean定義,如Bean名為:org.springframework.context.annotation.internalConfigurationAnnotationProcessor”的
ConfigurationClassPostProcessor 定義。而後此刻不會做任何Bean Definition的解析動作,Spring框架會根據前兩種配置,過濾出BeanDefinitionRegistryPostProcessor 型別的Bean定義,並通過Spring框架生成對應的Bean物件(如 ConfigurationClassPostProcessor 例項)。。結合 Spring 上下文原始碼可知這個物件是一個 processor 型別工具類,Spring 容器會在例項化開發人員所定義的
Bean 前先呼叫該 processor 的 postProcessBeanDefinitionRegistry(…) 方法。此處實現基於 Java Code 配置Bean Definition的處理。
基於 Java Code 的配置方式,其執行原理不同於前兩種。它是在 Spring 框架已經解析了基於 XML 和 Annotation 配置後,通過加入 BeanDefinitionRegistryPostProcessor 型別的 processor 來處理配置資訊,讓開發人員通過 Java 程式設計方式定義一個 Java 物件。其優點在於可以將配置資訊集中在一定數量的 Java 物件中,同時通過 Java 程式設計方式,比基於 Annotation 方式具有更高的靈活性。並且該配置方式給開發人員提供了一種非常好的範例來增加使用者自定義的解析工具類。其主要缺點在於與 Java 程式碼結合緊密,配置資訊的改變需要重新編譯 Java 程式碼,另外這是一種新引入的解析方式,需要一定的學習成本。
提及一點的就是,Spring框架有3個主要的Hook類,分別是:
org.springframework.context.ApplicationContextAware
它的setApplicationContext 方法將在Spring啟動之前第一個被呼叫。我們用來同時啟動Jdon框架。
org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor
它的postProcessBeanDefinitionRegistry 和 postProcessBeanFactory 方法是第二和第三被呼叫,它們在Bean初始化建立之前啟動,如果Spring的bean需要的其他第三方中的元件,我們在這裡將其注入給Spring。
org.springframework.context.ApplicationListener
用於在初始化完成後做一些事情,當Spring所有XML或元註解的Bean都啟動被建立成功了,這時會呼叫它的唯一方法onApplicationEvent。
下面我們來完成一個,自己通過java程式碼建立bean,並註冊為Spring管理。
<!--[if !supportLineBreakNewLine]-->
<!--[endif]-->
本例中,我們建立一個介面,然後建立該介面的2個實現類,分別命名不同的名字,然後在需要注入的地方使用@Qualifier 指定注入對應的例項。
介面com.kfit.demo.Shanhy.java
1 2 3 4 5 6 7 |
package com.kfit.demo;
publicinterface Shanhy {
publicvoid dispaly();
}
|
實現類com.kfit.demo.ShanhyA.java
1 2 3 4 5 6 7 8 9 |
package com.kfit.demo;
publicclass ShanhyA implements Shanhy{
@Override
publicvoid dispaly() {
System.out.println( "ShanhyA.dispaly()" );
}
}
|
實現類com.kfit.ShanhyB.java
1 2 3 4 5 6 7 8 9 10 |
package com.kfit.demo;
publicclass ShanhyB implements Shanhy {
@Override
publicvoid dispaly() {
System.out.println( "ShanhyB.dispaly()" );
}
}
|
定義介面BeanDefinitionRegistryPostProcessor的實現:
com.kfit.config.MyBeanDefinitionRegistryPostProcessor:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
package com.kfit.config;
import org.springframework.beans.BeansException;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition;
import org.springframework.beans.factory.annotation.AnnotatedGenericBeanDefinition;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.beans.factory.support.BeanNameGenerator;
import org.springframework.context.annotation.AnnotationBeanNameGenerator;
import org.springframework.context.annotation.Configuration;
import com.kfit.demo.ShanhyA;
import com.kfit.demo.ShanhyB;
/**
* 實現自己例項化bean並註冊為Spring管理
*
* @version v.0.1
*/
@Configuration
publicclass MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
//bean 的名稱生成器.
private BeanNameGenerator beanNameGenerator = new AnnotationBeanNameGenerator();
@Override
publicvoid postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
|