Spring Bean深入剖析(二)

BeanDefinition注冊(cè)

  • XML配置元信息
    <bean name="...." .../>
  • Java注解配置元信息: 1.@Bean 2.@Component3.@Import
/**
 * 3.通過@Import方式進(jìn)行導(dǎo)入
 */
@Import(AnnotationBeanDefinitionDemo.Config.class)
public class AnnotationBeanDefinitionDemo {
 public static void main(String[] args) {
 //創(chuàng)建BeanFactory容器
 AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
 //注冊(cè)Configuration Class(配置類)
 applicationContext.register(AnnotationBeanDefinitionDemo.class);
 //啟動(dòng)spring應(yīng)用上下文
 applicationContext.refresh();
 //按照類型依賴查找
 System.out.println("config 的所有 Beans"+applicationContext.getBeansOfType(Config.class));
 System.out.println("user 的所有 Beans"+applicationContext.getBeansOfType(User.class));
 //顯示的關(guān)閉spring應(yīng)用上下文
 applicationContext.close();
 }

 /**
 *   2.通過@component方式 定義當(dāng)前類作為Spring Bean(組件)
 */
 @Component
 public static class Config{
 /**
 * 1.通過Java 注解的方式凉逛,定義了一個(gè)bean
 * @return
 */
 @Bean(name={"user","zhangsan-user"})
 public User user(){
 User user = new User();
 user.setId(1L);
 user.setName("zhangsan");
 return user;
 }
 }
}
  • Java API 配置元信息

    • 命名方式:BeanDefinitionRegistry#registerBeanDefinition(String,BeanDefiniton)
    • 非命名方式:
      • BeanDefinitionReaderUtils#registerWithGeneratedName(AbstractBeanDefinition,BeanDefinitonRegistry)
    /**
     * 命名Bean注冊(cè)方式
     * @param registry
     * @param beanName
     */
     public static void registerUserBeanDefinition(BeanDefinitionRegistry registry,String beanName){
     BeanDefinitionBuilder beanDefinitionBuilder = genericBeanDefinition(User.class);
     beanDefinitionBuilder.addPropertyValue("id",1)
     .addPropertyValue("name","zhangsan");
     //判斷如果BeanName參數(shù)存在時(shí)
     if(StringUtils.hasText(beanName)){
     //注冊(cè)BeanDefinition
     registry.registerBeanDefinition(beanName,beanDefinitionBuilder.getBeanDefinition());
     }else {
     //非命名的注冊(cè)方法
     BeanDefinitionReaderUtils.registerWithGeneratedName(beanDefinitionBuilder.getBeanDefinition(),registry);
     }
     }
    
     /**
     * 非命名注冊(cè)bean
     * @param registry
     */
     public static void registerUserBeanDefinition(BeanDefinitionRegistry registry){
     registerUserBeanDefinition(registry,null);
     }
*   配置類方式:AnnotatedBeanDefinitionReader#register(Class....)

Spring Bean的實(shí)例化

Bean實(shí)例化(Instantiation)

  • 常規(guī)方式
    • 通過構(gòu)造器(配置元信息:XML腌歉、Java注解和Java API)
    • 通過靜態(tài)工廠方法(配置元信息:XML和Java API)
    • 通過Bean工廠方法(配置元信息:XML和Java API)
    • 通過FactoryBean(配置元信息:XML、Java注解和Java API)
      例如:通過xml方式進(jìn)行相關(guān)的配置
<?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xmlns="http://www.springframework.org/schema/beans"
     xsi:schemaLocation="http://www.springframework.org/schema/beans
     http://www.springframework.org/schema/beans/spring-beans.xsd">
    
     <!-- 靜態(tài)方法實(shí)例化bean-->
     <bean id="user-by-static-method" class="com.test.ioc.overview.dependency.domian.User"
     factory-method="createUser"/>
    
     <!--實(shí)例(Bean)的方法實(shí)例化Bean-->
     <bean class="com.test.thinking.in.spring.bean.factory.DefaultUserFactroy"/>

     <!--通過FactoryBean的方式實(shí)例化bean-->
     <bean id="user-by-factroy-bean" class="com.test.thinking.in.spring.bean.factory.UserFactoryBean"/>
    
    </beans>
  • 特殊方式
    • 通過ServiceLoaderFactoryBean(配置元信息:XML、Java注解和Java API)
    public final class ServiceLoader<S>
     implements Iterable<S>
    {  
     private static final String PREFIX = "META-INF/services/";</pre>
    ServiceLoader默認(rèn)的文件路徑是"META-INF/services/"下面迁筛,我們先新建一個(gè)相關(guān)目錄,然后寫入對(duì)應(yīng)的類路徑
![](https://upload-images.jianshu.io/upload_images/17885848-8585683ba841f1bc.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
    配置對(duì)應(yīng)的XML文件:
``` xml
<?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xmlns="http://www.springframework.org/schema/beans"
     xsi:schemaLocation="http://www.springframework.org/schema/beans
     http://www.springframework.org/schema/beans/spring-beans.xsd">
     <bean id="userFactoryServiceLoader" class="org.springframework.beans.factory.serviceloader.ServiceLoaderFactoryBean">
     <property name="serviceType" value="com.test.thinking.in.spring.bean.factory.UserFactory"/>
     </bean>
    </beans>
通過ServiceLoader對(duì)應(yīng)的API獲取:
 public static void main(String[] args) {
     BeanFactory beanFactory = new ClassPathXmlApplicationContext("META-INF/special-bean-instination-context.xml");
     ServiceLoader<UserFactory> serviceLoader  = beanFactory.getBean("userFactoryServiceLoader", ServiceLoader.class);
     displayServiceLoader( serviceLoader);
     demoServiceLoader();
     }
    
     public static void demoServiceLoader(){
     ServiceLoader<UserFactory> serviceLoader = ServiceLoader.load(UserFactory.class, Thread.currentThread().getContextClassLoader());
     displayServiceLoader(serviceLoader);
     }
    
     private static void displayServiceLoader(ServiceLoader<UserFactory> serviceLoader){
     Iterator<UserFactory> iterator = serviceLoader.iterator();
     while (iterator.hasNext()){
     UserFactory userFactory = iterator.next();
     System.out.println(userFactory.createUser());
     }
     }
*   通過AutowireCapableBeanFactory#createBean(java.lang.Class,int,boolen)
 ApplicationContext applicationContext = new ClassPathXmlApplicationContext("META-INF/special-bean-instination-context.xml");
     //通過ApplicationContext獲取AutowireCapableBeanFactory
     AutowireCapableBeanFactory beanFactory = applicationContext.getAutowireCapableBeanFactory();
     ServiceLoader<UserFactory> serviceLoader  = beanFactory.getBean("userFactoryServiceLoader", ServiceLoader.class);
     displayServiceLoader( serviceLoader);
     // demoServiceLoader();
     //創(chuàng)建beanfactory對(duì)象,通過AutowireCapableBeanFactory
     UserFactory userFactory = beanFactory.createBean(DefaultUserFactroy.class);
     userFactory.createUser();
*   通過BeanDefinitionRegistry#registerBeanDefinition(String,BeanDefiniton)
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末我注,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子迟隅,更是在濱河造成了極大的恐慌但骨,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,366評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件智袭,死亡現(xiàn)場離奇詭異奔缠,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)吼野,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,521評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門添坊,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人箫锤,你說我怎么就攤上這事贬蛙。” “怎么了谚攒?”我有些...
    開封第一講書人閱讀 165,689評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵阳准,是天一觀的道長。 經(jīng)常有香客問我馏臭,道長野蝇,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,925評(píng)論 1 295
  • 正文 為了忘掉前任括儒,我火速辦了婚禮绕沈,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘帮寻。我一直安慰自己乍狐,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,942評(píng)論 6 392
  • 文/花漫 我一把揭開白布固逗。 她就那樣靜靜地躺著浅蚪,像睡著了一般。 火紅的嫁衣襯著肌膚如雪烫罩。 梳的紋絲不亂的頭發(fā)上惜傲,一...
    開封第一講書人閱讀 51,727評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音贝攒,去河邊找鬼盗誊。 笑死,一個(gè)胖子當(dāng)著我的面吹牛隘弊,可吹牛的內(nèi)容都是我干的哈踱。 我是一名探鬼主播,決...
    沈念sama閱讀 40,447評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼长捧,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼嚣鄙!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起串结,我...
    開封第一講書人閱讀 39,349評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤哑子,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后肌割,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體卧蜓,經(jīng)...
    沈念sama閱讀 45,820評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,990評(píng)論 3 337
  • 正文 我和宋清朗相戀三年把敞,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了弥奸。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,127評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡奋早,死狀恐怖盛霎,靈堂內(nèi)的尸體忽然破棺而出赠橙,到底是詐尸還是另有隱情,我是刑警寧澤愤炸,帶...
    沈念sama閱讀 35,812評(píng)論 5 346
  • 正文 年R本政府宣布期揪,位于F島的核電站,受9級(jí)特大地震影響规个,放射性物質(zhì)發(fā)生泄漏凤薛。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,471評(píng)論 3 331
  • 文/蒙蒙 一诞仓、第九天 我趴在偏房一處隱蔽的房頂上張望缤苫。 院中可真熱鬧,春花似錦墅拭、人聲如沸活玲。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,017評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽翼虫。三九已至,卻和暖如春屡萤,著一層夾襖步出監(jiān)牢的瞬間珍剑,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,142評(píng)論 1 272
  • 我被黑心中介騙來泰國打工死陆, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留招拙,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,388評(píng)論 3 373
  • 正文 我出身青樓措译,卻偏偏與公主長得像别凤,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子领虹,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,066評(píng)論 2 355

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