https://blog.csdn.net/coding_1994/article/details/80634810からの転送、著者は非常に明確に記述します。
春は効果的に対象のJ2EEアプリケーション層を整理することができます。アクションは、制御層、ビジネスレイヤオブジェクトまたはサービス、またはDAOオブジェクトの永続化層オブジェクトかどうか、有機的に管理・運用の春にコーディネートすることができます。サービスオブジェクトの特定の実装を気にせず疎結合の方法で一緒にグループ化されたオブジェクト、アクションオブジェクトの層を春、永続層を気にすることなくサービスオブジェクトは、特定の目的を達成する完全にインターフェースをオブジェクト指向の層を呼び出します。システムが再構成を必要とする場合、符号量を大幅に削減する書き換えます。
上記のすべては春、依存性注入に適したコアメカニズムを持っていました。むしろハードコーディング豆と豆の間で互いに結合されたよりも、一緒にコンフィギュレーションファイルを作成するには、依存性注入。感謝の依存性の注入
依存性注入(依存性注入)と(制御の反転)制御を逆に同じ概念です。特定の意味は次のとおりです。役割(おそらくJavaインスタンス、呼び出し側が)別のロール(別のJavaインスタンス、呼び出し先を)支援が必要な場合には、従来のプログラムの設計プロセスでは、通常、発信者によって作成されたときに、呼び出し側の例。しかし、春には、呼び出し側によって、呼び出し側が作成した作品は、コントロールの完全な、いわゆる反転ではありません。作成したインスタンス呼び出し先の作業は通常、春のコンテナで行われ、その後、呼び出し側に注入され、それはまた依存して知られています注入。
依存性注入、または制御の反転するかどうかを、さまざまなオブジェクトを管理するためのスプリングダイナミック、柔軟な方法を示していました。オブジェクト透明各オブジェクトインプリメンテーション間の詳細。依存性注入を理解する前に、社会的な状態のさまざまな問題を解決する方法下記参照:男(Javaインスタンス、呼び出し側)斧を必要とする(Javaインスタンス、発信者を)。
(1)原始社会、労働力のほとんどない社会的分裂。人々 (呼び出し側)が斧(発信者)研削するだけで、自分の斧を必要としています。ケースに対応:呼び出し側の自身の作成でJavaプログラムが呼び出されます。
(2)産業社会の中に、工場が表示されます。Axはもはや普通の人によって行われていない、工場で生産され、この時間の人(呼び出し側)は、製造プロセスを心配することなく斧、斧を買って、斧の工場を見つける必要があります。Javaプログラムに対応するシンプルな工場のデザインパターン。
斧の必要性:(3)「オンデマンド」の社会に、人々は、必要な斧の工場を見つけ、自宅で座って、簡単な指示を発行する必要はありません。彼の前で自然に斧。依存性注入に対応した春。
最初のケースでは、Javaインスタンス作成の発信者Javaインスタンスが起動され、Javaクラスは避けられない要件は、呼び出し元のコードで表示されますと呼ばれています。両者間の疎結合を達成することができません。
後者の場合、呼び出し側は、発信者の特定の実施プロセスを心配する必要はなく、ただのインスタンスが一定の基準(Interface)を満たし、あなたが使用することができます見つける必要があります。コード指向のプログラミング・インタフェースは、工場モデルの使用の理由はたくさんある呼び出し元と呼び出し先のデカップリングを、できるように、この時点で呼び出されます。しかし、呼び出し側は、互いに結合され、特定の発信者の工場で、それ自体が工場を配置する必要があります。
プログラムが呼び出し元に実行する必要がある第三の場合には、工場自体を配置せずに、発信者は、発信者が例を自動的に提供されます。実際には、呼び出し元と呼び出し先は春が提供するそれらの間の依存関係の管理下に春です。
いわゆる依存性の注入は、呼び出し側がコードである作成しなくても、あなたは援助コール別のオブジェクトが必要な場合は、実行中のプログラムを意味するが、代わりに外部の注射に依存しています。Springの依存性注入呼び出し元と呼び出し先のためのほとんどの要件は、完全にPOJO(プレーン普通のJavaオブジェクト)間の依存関係の管理があるサポートしています。2依存性の注入は、通常はあります
。・セッターインジェクション。
・建設注射。
上記のすべては春、依存性注入に適したコアメカニズムを持っていました。むしろハードコーディング豆と豆の間で互いに結合されたよりも、一緒にコンフィギュレーションファイルを作成するには、依存性注入。感謝の依存性の注入
依存性注入(依存性注入)と(制御の反転)制御を逆に同じ概念です。特定の意味は次のとおりです。役割(おそらくJavaインスタンス、呼び出し側が)別のロール(別のJavaインスタンス、呼び出し先を)支援が必要な場合には、従来のプログラムの設計プロセスでは、通常、発信者によって作成されたときに、呼び出し側の例。しかし、春には、呼び出し側によって、呼び出し側が作成した作品は、コントロールの完全な、いわゆる反転ではありません。作成したインスタンス呼び出し先の作業は通常、春のコンテナで行われ、その後、呼び出し側に注入され、それはまた依存して知られています注入。
依存性注入、または制御の反転するかどうかを、さまざまなオブジェクトを管理するためのスプリングダイナミック、柔軟な方法を示していました。オブジェクト透明各オブジェクトインプリメンテーション間の詳細。依存性注入を理解する前に、社会的な状態のさまざまな問題を解決する方法下記参照:男(Javaインスタンス、呼び出し側)斧を必要とする(Javaインスタンス、発信者を)。
(1)原始社会、労働力のほとんどない社会的分裂。人々 (呼び出し側)が斧(発信者)研削するだけで、自分の斧を必要としています。ケースに対応:呼び出し側の自身の作成でJavaプログラムが呼び出されます。
(2)産業社会の中に、工場が表示されます。Axはもはや普通の人によって行われていない、工場で生産され、この時間の人(呼び出し側)は、製造プロセスを心配することなく斧、斧を買って、斧の工場を見つける必要があります。Javaプログラムに対応するシンプルな工場のデザインパターン。
斧の必要性:(3)「オンデマンド」の社会に、人々は、必要な斧の工場を見つけ、自宅で座って、簡単な指示を発行する必要はありません。彼の前で自然に斧。依存性注入に対応した春。
最初のケースでは、Javaインスタンス作成の発信者Javaインスタンスが起動され、Javaクラスは避けられない要件は、呼び出し元のコードで表示されますと呼ばれています。両者間の疎結合を達成することができません。
後者の場合、呼び出し側は、発信者の特定の実施プロセスを心配する必要はなく、ただのインスタンスが一定の基準(Interface)を満たし、あなたが使用することができます見つける必要があります。コード指向のプログラミング・インタフェースは、工場モデルの使用の理由はたくさんある呼び出し元と呼び出し先のデカップリングを、できるように、この時点で呼び出されます。しかし、呼び出し側は、互いに結合され、特定の発信者の工場で、それ自体が工場を配置する必要があります。
プログラムが呼び出し元に実行する必要がある第三の場合には、工場自体を配置せずに、発信者は、発信者が例を自動的に提供されます。実際には、呼び出し元と呼び出し先は春が提供するそれらの間の依存関係の管理下に春です。
いわゆる依存性の注入は、呼び出し側がコードである作成しなくても、あなたは援助コール別のオブジェクトが必要な場合は、実行中のプログラムを意味するが、代わりに外部の注射に依存しています。Springの依存性注入呼び出し元と呼び出し先のためのほとんどの要件は、完全にPOJO(プレーン普通のJavaオブジェクト)間の依存関係の管理があるサポートしています。2依存性の注入は、通常はあります
。・セッターインジェクション。
・建設注射。
注入の設定値
例セッターの方法により、呼び出し側によって渡さセッター注入手段。この注入方法は、Spring依存性注入で、簡単で直感的なので、広く使用されています。次のコードは、Personインターフェースを見てください
例セッターの方法により、呼び出し側によって渡さセッター注入手段。この注入方法は、Spring依存性注入で、簡単で直感的なので、広く使用されています。次のコードは、Personインターフェースを見てください
//人インタフェース定義 パブリックインターフェイス人{ AXの定義で使用//者インターフェース方法 公共ボイドuseAxeを(); }
その後、斧インターフェース
AX //定義されたインタフェース パブリックインターフェイスAX { // AXインターフェイスカット法がある )(公共ボイドCHOP; }
実装クラスの人
用具は、Personクラス中国語{パブリック //アックス指向プログラミングインタフェースではなく、特定のカテゴリ 専用アックスアックス; //デフォルトコンストラクタ パブリック中国語(){ } 注入セッターメソッドの所望の値に設定// 公共ボイドsetAxe(AXをAX){ this.axe = AX; } //者インターフェース方法実施useAxe 公共useAxeボイド(){ System.out.printlnは(axe.chop()); } }
アックス最初の実装クラス
//アックス第実装クラスStoneAxe パブリッククラスStoneAxe実装はアックス { //デフォルトコンストラクタ パブリックStoneAxe() {} アックス・インタフェースの実現方法CHOP // パブリックストリングCHOP() { リターン「薪非常に遅い軸を」; } } |
春には、次の設定ファイルと一緒に組織の人インスタンスアックスの例を使用しています。設定ファイルは次のよう:
<! -以下は、標準のXMLファイルのヘッダーがある- > <xmlのバージョン= "1.0"エンコード= "2312" ??> < -春の次の行で定義されたDTDのXML設定ファイル- !> 「HTTP:/ /www.springframework.org/dtd/spring-beans.dtd「> <! -すべてのSpring構成ファイル以上の3行が同じである- > <! - Spring構成ファイルのルート要素- > < BEANS> <! - IDの中国で最初のBeanを、定義し、クラスのBeanのクラスのインスタンスを指定- > <Beanクラス=「リー」ID =中国.Chinese> <! - Property要素を指定するために使用されます注入されたコンテナが、ここで設定された噴射プロパティ値をAxに必要コンテナ、に要求される特性が注入され、そのためのクラスは、中国のsetAxeメソッドを持っている必要があります- > |
<プロパティ名= "斧"> <! -ここにもう一つの参照注入豆豆中国語- > <= REFローカル"" stoneAxe "/"> </プロパティ> </ BEAN> <! - > -ビーンstoneAxe定義 <BEANクラス= "イ" .StoneAxe ID = stoneAxe /> </豆> |
コンフィギュレーション・ファイルから、あなたは器用のSpring管理Beanを見ることができます。ないコード自体における組織上の豆と豆構成ファイル間の依存関係。設定ファイルを指定することで、各注入性のための正確な春の豆。したがって、Beanクラス要素の設定ファイルは、インターフェイスだけでなく、実装クラスは実数でなければなりません。
春は自動的に要素の定義内の各Bean定義のプロパティを引き継ぎます。スプリングは、デフォルトのBeanの例を作成し、対応するプロパティ値設定メソッドの注入手順を呼び出し、コンストラクタの自由パラメータの後に行われます。プロパティ値を属性することはもはやBeanは自動的に作成、管理、および代わりに受動的に受信春注入ことによって定義されません。
IDは、各Beanは、Bean、また、id属性によって行われるid属性のアクセス豆、豆とマメ依存介してプログラムで識別する属性。
のは、メインプログラムの一部を見てみましょう:
BeanTestクラス公開 { //メイン方法、プログラムエントリ パブリック静的な無効メイン(文字列[]引数)は例外スロー { それがアプリケーションとは独立しているので、文脈が明示的にスプリングをインスタンス化し、//を。 CTX =新しい新しいFileSystemXmlApplicationContextのApplicationContext(「bean.xml」); //人ビーンビーンインスタンスID、指向プログラミング・インターフェース、そうすることによって取得された //このインタフェースタイプはキャスト 人物P =(人物)ctx.getBeanを( ) "中国の"; // userAxe人()メソッドを直接実行。 p.useAxe(); } } |
程序的执行结果如下:
石斧砍柴好慢
主程序调用Person的useAxe()方法时,该方法的方法体内需要使用Axe的实例,但程序里没有任何地方将特定的Person实例和Axe实 例耦合在一起。或者说,程序里没有为Person实例传入Axe的实例,Axe实例由Spring在运行期间动态注入。
Person实例不仅不需要了解Axe实例的具体实现,甚至无须了解Axe的创建过程。程序在运行到需要Axe实例的时候,Spring创建了Axe 实例,然后注入给需要Axe实例的调用者。Person实例运行到需要Axe实例的地方,自然就产生了Axe实例,用来供Person实例使用。
调用者不仅无须关心被调用者的实现过程,连工厂定位都可以省略(真是按需分配啊!)。下面也给出使用Ant编译和运行该应用的简单脚本:
<?xml version="1.0"?> <!-- 定义编译该项目的基本信息--> <PROJECT name="spring" default="." basedir="."> <!-- 定义编译和运行该项目时所需的库文件 --> <PATH id=classpath> <!-- 该路径下存放spring.jar和其他第三方类库 --> <FILESET dir=../../lib> <INCLUDE name="*.jar" /> </FILESET> <!-- 同时还需要引用已经编译过的class文件--> <PATHELEMENT path="." /> </PATH> <!-- 编译全部的java文件--> <TARGET description="Compile all source code" name="compile"> <!-- 指定编译后的class文件的存放位置 --> <JAVAC debug="true" destdir="."> deprecation="false" optimize="false" failοnerrοr="true"> <!-- 指定需要编译的源文件的存放位置 --> <SRC path="." /> <!-- 指定编译这些java文件需要的类库位置--> <CLASSPATH refid="classpath" /> </JAVAC> </TARGET> <!-- 运行特定的主程序 --> <TARGET description="run the main class" name="run" depends="compile"> <!-- 指定运行的主程序:lee.BeanTest。--> <JAVA failοnerrοr="true" fork="yes" classname="lee.BeanTest"> <!-- 指定运行这些java文件需要的类库位置--> <CLASSPATH refid="classpath" /> </JAVA> </TARGET> </PROJECT> |
如果需要改写Axe的实现类。或者说,提供另一个实现类给Person实例使用。Person接口、Chinese类都无须改变。只需提供另一个Axe的实现,然后对配置文件进行简单的修改即可。
Axe的另一个实现如下:
//Axe的另一个实现类 SteelAxe public class SteelAxe implements Axe { //默认构造器 public SteelAxe() {} //实现Axe接口的chop方法 public String chop() { return "钢斧砍柴真快"; } } |
然后,修改原来的Spring配置文件,在其中增加如下一行:
<!-- 定义一个steelAxe bean--> <BEAN class="lee".SteelAxe id=steelAxe /> |
该行重新定义了一个Axe的实现:SteelAxe。然后修改chinese bean的配置,将原来传入stoneAxe的地方改为传入steelAxe。也就是将
<REF local="”stoneAxe”/"> |
改成
<REF local="”steelAxe”/"> |
此时再次执行程序,将得到如下结果:
钢斧砍柴真快
Person与Axe之间没有任何代码耦合关系,bean与bean之间的依赖关系由Spring管理。采用setter方法为目标bean注入属性的方式,称为设值注入。
业务对象的更换变得相当简单,对象与对象之间的依赖关系从代码里分离出来,通过配置文件动态管理。
构造注入
所谓构造注入,指通过构造函数来完成依赖关系的设定,而不是通过setter方法。对前面代码Chinese类做简单的修改,修改后的代码如下:
所谓构造注入,指通过构造函数来完成依赖关系的设定,而不是通过setter方法。对前面代码Chinese类做简单的修改,修改后的代码如下:
//Chinese实现Person接口 public class Chinese implements Person { //面向Axe接口编程,而不是具体的实现类 private Axe axe; //默认的构造器 public Chinese() {} //构造注入所需的带参数的构造器 public Chinse(Axe axe) { this.axe = axe; } //实现Person接口的useAxe方法 public void useAxe() { System.out.println(axe.chop()); } } |
此时无须Chinese类里的setAxe方法,构造Person实例时,Spring为Person实例注入所依赖的Axe实例。构造注入的配置文件也需做简单的修改,修改后的配置文件如下:
<!-- 下面是标准的XML文件头 --> <xml version="1.0" encoding="gb2312"?> <!-- 下面一行定义Spring的XML配置文件的dtd --> "http://www.springframework.org/dtd/spring-beans.dtd"> <!-- 以上三行对所有的Spring配置文件都是相同的 --> <!-- Spring配置文件的根元素 --> <BEANS> <!—定义第一个bean,该bean的id是chinese, class指定该bean实例的实现类 --> <BEAN class="lee".Chinese id=chinese> </BEAN> <!-- 定义stoneAxe bean --> <BEAN class="lee".SteelAxe id=steelAxe /> </BEANS> |
执行效果与使用steelAxe设值注入时的执行效果完全一样。区别在于:创建Person实例中Axe属性的时机不同——设值注入是现创建一个默认的bean实例,然后调用对应的构造方法注入依赖关系。而构造注入则在创建bean实例时,已经完成了依赖关系的