Spring組立Beanの自動化組立(一)

4969 ワード

自動アセンブリ
Spring自動化組立を2つの角度から実現
  • コンポーネントスキャン:springは、アプリケーションコンテキストで作成されたbean
  • を自動的に検出します.
  • 自動アセンブリ:springはbean間の依存を自動的に満たす
  • springで発見できるbeanを作成する
    発見が必要なクラスに注記@Componentを追加
    public interface CompactDisc {
    	void play();
    }
    
    @Component
    public class SgtPeppers implements CompactDisc {
    
    	public void play() {
    		...
    	}
    }
    

    @Component注記を使用すると、クラスがコンポーネントクラスとして使用され、springにbeanを作成するように通知されます.
    コンポーネントスキャン@ComponentScanの有効化
    @Configuration
    @ComponentScan
    public class CDPlayerConfig {
    }
    

    他の構成がない場合、@ComponentScanはデフォルトで構成クラスと同じパッケージをスキャンします.つまりspringはこのパッケージとこのパッケージの下のすべてのサブパッケージをスキャンし、@Component注釈のあるクラスを検索し、自動的にbeanを作成します.XMLを使用してコンポーネントスキャンを有効にすると、spring contextネーミングスペースの要素を使用できます.
    コンポーネントスキャンのbeanに名前を付ける
    SpringアプリケーションコンテキストのすべてのbeanにはIDが与えられ、上記の例ではbeanに明確に命名するが、springはクラス名に基づいてID(クラス名の最初のアルファベットを小文字に変更する)を指定し、例えばSgtPeppersが指定するIDはsgtPeppersである.このbeanのために別のIdを設定することもできます
    @Component("testabc")
    public class SgtPeppers implements CompactDisc {
    	......
    }
    

    もう1つのbeanに名前を付ける方法は、@Component注釈を使用せず、Java依存注入仕様(Java Dependency Injection)で提供される@Named注釈を使用する.
    @Named("abcd")
    public class SgtPeppers implements CompactDisc {
    	......
    }
    

    @Componentと@Nameは、ほとんどのシーンで互いに置き換えることができ、両者の間にわずかな違いがあります.いくつかの資料を調べて、両者のわずかな違いを少し理解しました:@Named JSR-330は組合せモデルを提供していません.@Componentは組合せ可能な注釈例です.
    // @Named        
    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Named("test")
    public class Test  {
    	......
    }
    
    // @Component     
    @Target({ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Component("test2")
    public class Test2  {
    	......
    }
    

    コンポーネントスキャンのベースパッケージの設定
    コンポーネントスキャンを有効にするときに使用する@ComponentScanの注記は、プロパティが設定されていない場合、クラスが存在するパッケージをベースパッケージとして構成するデフォルトのルールに従ってコンポーネントスキャンを行います.
    構成クラスを別のパッケージに配置すると、他のアプリケーションコードとは別に、デフォルトのベースパッケージは私たちのニーズを満たすことができません.
    この場合、@ComponentScanvalueプロパティを使用して、パッケージの名前を指定できます.
    @Configuration
    @ComponentScan("autoconfig")
    public class CDPlayerConfig {
    }
    

    このパッケージがベースパッケージであることを明確に示すには、basePackagesプロパティ設定を使用します.
    @Configuration
    @ComponentScan(basePackages ="autoconfig")
    public class CDPlayerConfig {
    }
    
    basePackages属性は複数形なので、複数のベースパッケージをスキャンできる
    @Configuration
    @ComponentScan(basePackages ={"autoconfig","autoconfig2"})
    public class CDPlayerConfig {
    }
    
    basePackagesの属性は、コードを再構築すると、ベースパッケージにエラーが発生する可能性があるなど、タイプが安全ではない.この場合、basePackageClassesの属性を用いる、パッケージに含まれるクラスまたはインタフェースとして指定することができる.
    @Configuration
    @ComponentScan(basePackageClasses ={CDPlayer.class,DVDPlayer.class})
    public class CDPlayerConfig {
    }
    

    スキャン用の空のタグインタフェースを作成することもできます.たとえば、次のようにします.
    public interface TestInterface {
    	void play();
    }
    
    @Component
    public class A implements TestInterface {
    	......
    }
    
    @Component
    public class B implements TestInterface {
    	......
    }
    
    @Configuration
    @ComponentScan(basePackageClasses ={TestInterface.class})
    public class TestConfig {
    }
    

    beanに注釈を追加して自動アセンブリを実現
    注釈@Autowiredを使用して自動アセンブリを実装します.たとえば、この注釈を に追加します.
    @Component
    public class CDPlayer implements MediaPlayer {
    	private CompactDisc cd;
    
    	@Autowired
    	public CDPlayer(CompactDisc cd) {
    		this.cd = cd;
    	}
    
    	public void play() {
    		cd.play();
    	}
    
    }
    
    @Autowired注記は のみならず Setterメソッドにも使用可能
    @Autowired
    public void setCompactDisc(CompactDisc cd) {
    	this.cd = cd;
    }
    

    Setterメソッドには特別な点はないが、@Autowiredの注釈はクラスのいかなるメソッドにも用いることができ、CDPlayerクラスにinsertDisc()メソッドがあると仮定すると、@Autowiredの注釈も同様の役割を果たすことができる.
    @Autowried
    public void insertDisc(CompactDisc cd) {
    	this.cd = cd;
    }
    

    コンストラクタ、Setterメソッド、または他のメソッドにかかわらず、springはメソッドパラメータに宣言された依存を満たすことを試みるが、 beanであれば、このbeanは組み込まれる.一致するbeanがない場合、コンテキスト作成を適用するとspringは例外を放出し、@Autowried注記のrequiredプロパティをfalseに設定できます.
    @Autowired(required=false)
    public CDPlayer(CompactDisc cd) {
    	this.cd = cd;
    }
    

    @Autowried注記のrequiredプロパティをfalseに設定すると、springは自動アセンブリを実行しようとしますが、一致するbeanがない場合、springはこのbeanを未アセンブリ状態にし、コードでnullチェックを行わないとNull PointerExceptionが発生する可能性があります.
    複数のbeanが依存関係を満たす場合、springはどのbeanを選択して自動アセンブリするかを明確に指定していないことを示す異常を投げ出す.(自動組立における曖昧性)@Autowriedはspring特有の注釈である、Java依存注入仕様が提供する@Injectを用いてもよく、両者には微細な差(この2つの微細な差は、しばらくは調べられていない)があるが、多くの場合互いに置き換えることができる.
    ソース:https://gitee.com/jincheng-921/sp_ch2_2.git
    最近spring in action(第4版)を読んで、見ながらメモを書いて、整理して、自分で記録を勉強するために使うだけで、ケースは本の中のソースコードから選別したのです.