pring拡張インタフェースのFactoryBean、そのソースコード実装を見てみましょう

6417 ワード

前言が楽しい
その年お見合いに行って、場所はホテルの中で、ウィットは先に2杯の水をあげて、男性の紳士のは1口飲んで、口を開けて舌を軽くテーブルの上で放して、額をなでて目を閉じて陶酔して、白い水は無理に82年飲みました×××という感じです.このような生活の情調のユーモアのある男は、思い切って取って、付き合った後、彼が比較的にぼんやりしていることに気づいて、彼にどうしてあの日水を飲むのがそんなに面白いのかと聞いて、彼は仰向けに言った:あの水がどうしてそんなに熱いのか知っています!
FactoryBeanのソースコードは简単です.コメントをよく読んでください.简単な翻訳をしました.
/**
  • がこのインタフェースを実装するbeanは、通常のbeanとして使用できない.このbeanが露出しているオブジェクトは、getObject()によって作成されたオブジェクトであり、それ自体*/public interface FactoryBean{/**ではありません.
  • は、このファクトリが管理するオブジェクトのインスタンス(isSingleton()の戻り値に応じて共有または独立している可能性がある)br/>*/@NullableT getObject()throws Exceptionを返します.

  • /**
  • は、このFactoryBeanによって作成されたオブジェクトタイプを返します.br/>*/@NullableClass>getobjectType();

  • /**
  • この工場が管理する対象は単例ですか?
  • (return true)の場合、getObject()は常に同じ共有インスタンスを返し、BeanFactoryによってキャッシュされる
  • (return false)の場合、getObject()は独立したインスタンス
  • を返します.
  • 一般的にはtrue*/default boolean isSingleton(){return true;}を返します.


  • }簡単に言えば、FactoryBeanはBeanFactoryがサポートするbeanインスタンスを露出するためのインタフェースです.
    何が先にみんなを連れて思い出して、今私达はbeanを配置して主にどんないくつかの方式がありますか?
    1、XMLベースの配置方式
    xmlファイルでの構成、たとえば
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-4.1.xsd">;
    
        
        

    Springのリリースの第1版がサポートされています.
    2、注釈に基づく配置方式
        spring2.5サポートを開始します.例えば、@Component、@Repository、@Controller、@Serviceなど、普段はたくさん使っています.
    3、Javaクラスに基づく配置方式
        spring3.0がサポートを開始するのも、現在springが推奨している方法で、@Configuration結合@Bean、springbootでは非常に多く使われています.
    一般的にSpringでは、反射メカニズムで使用されるclassプロパティによってクラスインスタンス化Beanを指定します.場合によっては、インスタンス化Beanプロセスが複雑で、従来のxml方式では、多くの構成情報を提供する必要があります.xml構成方式の柔軟性は制限されており、この場合、符号化方式を採用すると簡単なスキームが得られる可能性がある.では、符号化方式にはどんなものがありますか.spring3.0以降、符号化の方式は注釈ベース、Javaクラスベース、FactoryBeanベースである、spring 2.5の前に、インスタンス化プロセスが複雑なBeanをxmlで構成するにはどうすればいいですか?xmlはFactoryBeanと組み合わせて実装できます.xmlではFactoryBeanを構成し、FactoryBeanは必要なインスタンス化プロセスが複雑なBeanを作成します.コアコードの例は以下の通りです.springコンテナからuserのbeanインスタンスを取得し、UserタイプのBeanを取得します.
    xml構成
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-4.1.xsd">;

      UserFactoryBean
    package com.lee.factorybean.config;
    import com.lee.factorybean.entity.User;import org.springframework.beans.factory.FactoryBean;
    public class UserFactoryBean implements FactoryBean {
    @Override
    public User getObject() throws Exception {
        //   User          ,     User    
        return new User();
    }
    
    @Override
    public Class> getObjectType() {
        return User.class;
    }
    
    @Override
    public boolean isSingleton() {
        return true;
    }

    }  spring2.5以前は、xmlの構成方式でしかBeanをspring管理に登録できなかったが、xmlの構成方式は柔軟ではなく、インスタンス化プロセスが複雑なBeanを構成するのは面倒で、FactoryBeanと結合して、符号化方式でインスタンス化プロセスが複雑なBeanを構築することもできるし、BeanをSpring管理に渡すこともできる.spring2.5以降、特にspring 3.0以降、インスタンス化プロセスが複雑なBeanからspringコンテナへの登録が多くなり(採用可能な符号化方式が多い)、FactoryBeanの登録もspringでサポートされている.
    もっと簡単に言えば、FactoryBeanによってインスタンス化プロセスが複雑なBeanを作成することができます.FactoryBeanのインスタンスをSpringコンテナに登録する方法については、springバージョンによって異なる方法で使用できます.
    FactoryBeanがどのように使われているかを簡単な例で見てみましょう
    適用例アドレス:spring-boot-FactoryBean
        UserFactoryBean
    View Code    User
    View Code    FactoryBeanTest
    ViewCodeテスト例を実行すると、出力の結果はcom.lee.factorybean.entity.User、ではなく:com.lee.factorybean.config.UserFactoryBean
    SpringのFactoryBean実装Spring自体は多くのFactoryBean実装を提供している(springバージョンが異なり実装数が異なる)、springboot 2.0.3(spring 5.0.7対応)のFactoryBeanは次のように実装されています.
    私たちがカスタマイズしたUserFactoryBeanのほか、60個がspringbootの実装で、そのうち50個以上がspringの実装です.興味深いのは詳しく見て、springbootバージョンに注意して、直接springを使うならば、springのバージョンに注意します
    実际の仕事の中で、私达自身がFactoryBeanを実现するシーンはとても少なくて、どうせ私の仕事の中で使うのはとても少なくて、印象の中であって、しかし感じはとても长い前の事です;SpringにはFactoryBeanの実装が多く、MyBatisのMapperFactoryBean、druidのJdbcStatManagerFactoryBean、shiroのShiroFilterFactoryBeanなど、サードパーティの実装もたくさんあります.FactoryBeanを使わないで、すべて私達個人を見て、しかし私達はきっとFactoryBeanを知っていなければならなくて、私達がFactoryBeanの実現に出会う時(ソースコードを読むのはとても出会いやすい)、私達は一目でその意図を理解することができて、私達がインスタンス化の過程の比較的に複雑なBeanを構築する必要がある時、FactoryBeanも1種のオプションの方案です
    なぜ具体的な問題は、上記の例ではspringコンテナから取得されたnameがuserのインスタンスであり、そのタイプはUserFactoryBeanではなくUserであるのか.抽象的な質問:FactoryBeanインスタンスのnameに基づいて取得されるのは、なぜFactoryBeanインスタンスではなく、FactoryBeanインスタンスのgetObject()が返すオブジェクトなのか.www.202sdgc.com
    ソースを探究するにはbeanFactory.getBean("user");ブレークポイントエントリ
    @Testpublic void test(){//ブレークポイントエントリObject user=beanFactory.getBean("user");System.out.println(user.getClass().getName();}
    最初はspringコンテナからuserという名前のbeanをもらいました.タイプは確かにUserFactoryBeanですが、後でgetObjectForBeanInstanceを通って本当に必要なオブジェクトを取得します.
    ViewCodeはnameに基づいてspringコンテナからインスタンスを取得し、インスタンスがFactoryBeanタイプでない場合は、インスタンスを直接返します.これも私たちが普段使っている最も多く、最も一般的な状況です.インスタンスがFactoryBeanタイプで、nameが&で始まる場合も、インスタンスを直接返します.FactoryBeanインスタンスが望ましいことを示します.名前が&で始まるのではなく、インスタンスがFactoryBeanタイプである場合、インスタンスのgetObject()が呼び出され、必要なターゲットインスタンスが作成されます.
    FactoryBeanインスタンスを取得する方法という答えはすでにありますが、nameの前に&を付けることで、次のようになります.
    @Testpublic void test() {Object user = beanFactory.getBean("&user");System.out.println(user.getClass().getName());}出力結果は以下の通りです.
    com.lee.factorybean.config.UserFactoryBeanまとめ1、FactoryBeanはBeanFactoryがサポートするbeanインスタンスを露出するためのインタフェースであり、インスタンス化プロセスが複雑なbeanの作成を完了するためにこのインタフェースを実現することができる.
    2、beanNameでspringコンテナからbeanインスタンスを取得すると、最初にbeanNameに直接関連付けられたbeanインスタンスが取得され、その後のspringコンテナはこのbeanインスタンスに基づいて必要なオブジェクトインスタンスを返します.beanインスタンスがFactoryBeanタイプでない場合はbeanインスタンスを直接返します.beanインスタンスがFactoryBeanタイプであり、beanNameが&で始まる場合はbeanインスタンスを直接返します.beanインスタンスがFactoryBeanタイプであり、beanNameが&でない場合は、beanインスタンスのgetObject()メソッドで取得したオブジェクトインスタンス(一般的にgetObjectでは必要なインスタンスオブジェクトの作成プロセス)を返します.http://jbk.39.net/yiyuanzaixian/shxkwckyy/
    3、作成プロセスが複雑なオブジェクトの作成については、springには多くの実装方法がありますが、FactoryBeanはその1つにすぎません.インスタンスオブジェクトの作成にはこの方法を採用しないかもしれませんが、この方法を理解し、この実装方法があることを知る必要があります.多くの第三者はこのような方法に沿っていて、私たちがソースコードを追うとき、簡単に出会うことができます.
    4、通常のbeanの作成に比べて、FactoryBeanの方式ではspringコンテナにFactoryBeanのインスタンスが1つ多く存在し、FactoryBeanインスタンスオブジェクトを取得するにはFactoryBeanのbeanNameに&を加えるだけでよい.
    分類:springソースラベルspringソースラベル:FactoryBean