転載記事します。https://blog.csdn.net/sinat_21843047/article/details/80297951
IOC
- コントロールの定義されたIOC-反転:あり、「制御の反転は」技術ではなく、デザインのアイデア。Java開発では、IOCはあなたではなくあなたの内部のオブジェクトの上に伝統的な直接制御するよりも、コンテナコントロールにオブジェクトを設計していることを意味します。新しいオブジェクトを介してライン上のオブジェクトが作成された内部の従来のJava SEプログラミングは、我々は直接、プログラムが自動的に依存オブジェクトを作成されていますが、オブジェクトを作成するためのIoCコンテナによって制御され、これらのオブジェクトを作成するための特別なIOCコンテナは、そこにあります
IOCのメリット
従来のアプリケーションは、クラスの中に依存オブジェクトを作成するために、当社のイニシアチブによるものであり、クラス間の高い結合が生じます難しいテスト;あなたはIoCコンテナを持っていたら、作成してコンテナにコントロールの依存オブジェクトを見つける、複合オブジェクトはまた、テストを容易にするであろう機能を多重化するのに役立ちますそのため、オブジェクト間、コンテナによって注入され、オブジェクトが疎結合されていますさらに重要なのは、プログラムの構造は、システム全体が非常に柔軟になりますです。
実際には、最大の変化をもたらすのIoCプログラミングはコードからではなく、イデオロギー的変化、「マスタースレーブ転置」。アプリケーションは、リソースがイニシアチブを取るためにあるものを手に入れるために、もともと上司だったが、のIoC / DIでアプリケーションが受動的になり、考え、そして受動的にそれが必要なリソースを作成し、注入するIoCコンテナを待っています。
IOC与、IN
- DI-依存性注入、すなわち、「依存性注入」:実行時のコンポーネント間の依存関係は、容器によって決定され、コンポーネントに容器ダイナミック依存性によって注入される画像は述べています。依存性の注入は、ソフトウェアシステムに多くの機能を持ってますが、コンポーネントの再利用頻度を向上させるために、そして柔軟でスケーラブルなプラットフォームを構築するためのシステムのためのものではありません。
DIは、理解するための鍵です:私たちは徹底的に分析するために持っていることを「注入された方の依存、なぜ頼りに、注入何か」:
●誰が誰に依存します。もちろん、IoCコンテナに依存したアプリケーションです。
●なぜに依存しています。アプリケーションは、オブジェクトを必要な外部リソースを提供するために、IoCコンテナを必要とします。
●誰注射:アプリケーションに依存し、オブジェクトがオブジェクトにIoCコンテナアプリケーションに注入されることは明らかです。
外部リソースに注入されたオブジェクトは、(オブジェクト、資源、定数データを含む)が必要:●何を注入しました。
参考記事:HTTPS://blog.csdn.net/a909301740/article/details/78379720
三つの方法の依存性注入
- コンストラクタインジェクション
コンストラクタ注入は、この方法は、(我々が通常クラスを作成クラスコンストラクタによって作成され、初期値が割り当てられている)と同じ、引数ないかもしれない参照を有するように構成することができる構成で実行される方法に主に依存しています反射ばね機構に、コンストラクタ(割当)することによって注射を完了する。
コードの実装
- 関連するBeanクラスを書きます
public class UserService implements IUserService {
private IUserDao userDao;
public UserService(IUserDao userDao) {
this.userDao = userDao;
}
public void loginUser() {
userDao.loginUser();
}
}
- 関連する設定(コンストラクタに注入UserServiceのコンストラクタ、引数タグによってパラメータを有します)
<!-- 注册userService -->
<bean id="userService" class="com.lyu.spring.service.impl.UserService">
<constructor-arg ref="userDaoJdbc"></constructor-arg>
</bean>
<!-- 注册jdbc实现的dao -->
<bean id="userDaoJdbc" class="com.lyu.spring.dao.impl.UserDaoJdbc"></bean>
- テストカテゴリ
@Test
public void testDI() {
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
// 获取bean对象
UserService userService = ac.getBean(UserService.class, "userService");
// 模拟用户登录
userService.loginUser();
}
パラメータ・タイプのタイプを定義するために使用されるクラス定義のコンストラクタ、引数要素引数コンストラクタは、インデックスパラメータの位置を定義するために使用されてもよく、ここで設定された値は、コード上値は春に至るです豆を組み立てます
セッター・インジェクション
コードの実装
- 最初は(setterメソッドを記述してください)Beanクラスであります
クラスメンバ変数名とパラメータ名のname属性の値のみセットに対応するメソッド名に関係なく、方法の設定され、そのようなアプローチを、以下、第2のコードとの組み合わせで成功を実行することです
public class UserService implements IUserService {
private IUserDao userDao1;
public void setUserDao(IUserDao userDao1) {
this.userDao1 = userDao1;
}
public void loginUser() {
userDao1.loginUser();
}
}
- プロファイル
以前に「セット」をステッチ、その後(次の書き込みのための2つの方法があり、春には各単語の最初の文字の値に名前を付けます大文字に変換し、メソッド名を構成して、対応するクラス探しに行く方法のを、反射実現注射、主に彼が見ているsetメソッドによって呼び出され、)プロパティ名を見つけられません
<!-- 注册userService -->
<bean id="userService" class="com.lyu.spring.service.impl.UserService">
<!-- 写法一 -->
<!-- <property name="UserDao" ref="userDaoMyBatis"></property> -->
<!-- 写法二 -->
<property name="userDao" ref="userDaoMyBatis"></property>
</bean>
<!-- 注册mybatis实现的dao -->
<bean id="userDaoMyBatis" class="com.lyu.spring.dao.impl.UserDaoMyBatis"></bean>
- 注意事項:方法による注入特性が設定されている場合、デフォルトの空のコンストラクタのパラメータによってインスタンス化オブジェクトへの春、クラスのコンストラクタのパラメータを持つ書き込み方法の構成は、空の書き込みパラメータを取る必要があります場合にはそうでない場合、ばねは、エラーが発生した、オブジェクトをインスタンス化する方法はありません。
注釈ベースの注入
- コンストラクタ、BYNAME、byType:まず、3つのプロパティの豆autowireのプロパティを教えて。
-
コンストラクタ:1つのつのみコンストラクタパラメータは、コンストラクタ、マッチングマルチパラメータの複数の容器にマルチパラメータを検索することがあればラインが自動的工法を通じて注入され、同じバネが、コンストラクタパラメータタイプ豆注入に一致します豆コンストラクタ、スプリングが優先コンストラクタ豆複数のパラメータに注入されます。
-
BYNAMEは:半分と一致している必要がありビーンID名に注入され、設定された方法の後、最初の単語および名前IDの最初の文字を手動で別のセットを注射する小文字でなければなりません。
-
byType:豆注入のパラメータの型と一致して、すべてのsetメソッドを検索します。
4つの主要な注釈は、Beanを登録することがありますが、各注釈は、任意の使用であってもよいが、意味論では異なることができます。
@Component:すべてのBeanを登録するために使用することができる
@Repository:主登録DAO豆層に使用
@Controller:豆は、主登録制御層のために使用される
@Service:主登録サービス層豆のために使用
@資源
- 定義:byTypeがもっと発見した場合のBeanのidの同じ属性名を一致させるために行くためのBYNAME方法をデフォルトにJavaアノテーション、見つからない場合は@Qualifier注釈(春の注釈)を使用し、byTypeする方法を探します指定豆特定名。
@Resource
@Qualifier("userDaoMyBatis")
private IUserDao userDao;
public UserService(){
}
@Autowired
- 定義:唯一の試合に、そして関係なくBean名を注射するものを、豆に直接注入されていない場合は春の注釈は、デフォルトでは、豆の同じタイプと一致するbyTypeの方法であり、複数の一致は、それが呼び出す場合これは、特定の注入を決定するdetermineAutowireCandidate豆方法のDefaultListableBeanFactory。メソッドdetermineAutowireCandidate内容は以下のように:
// candidateBeans 为上一步通过类型匹配到的多个bean,该 Map 中至少有两个元素。
protected String determineAutowireCandidate(Map<String, Object> candidateBeans, DependencyDescriptor descriptor) {
// requiredType 为匹配到的接口的类型
Class<?> requiredType = descriptor.getDependencyType();
// 1. 先找 Bean 上有@Primary 注解的,有则直接返回
String primaryCandidate = this.determinePrimaryCandidate(candidateBeans, requiredType);
if (primaryCandidate != null) {
return primaryCandidate;
} else {
// 2.再找 Bean 上有 @Order,@PriorityOrder 注解的,有则返回
String priorityCandidate = this.determineHighestPriorityCandidate(candidateBeans, requiredType);
if (priorityCandidate != null) {
return priorityCandidate;
} else {
Iterator var6 = candidateBeans.entrySet().iterator();
String candidateBeanName;
Object beanInstance;
do {
if (!var6.hasNext()) {
return null;
}
// 3. 再找 bean 的名称匹配的
Entry<String, Object> entry = (Entry)var6.next();
candidateBeanName = (String)entry.getKey();
beanInstance = entry.getValue();
} while(!this.resolvableDependencies.values().contains(beanInstance) && !this.matchesBeanName(candidateBeanName, descriptor.getDependencyName()));
return candidateBeanName;
}
}
}
DetermineAutowireCandidateロジックプロセスは以下のとおりです。
- 豆は@Primaryノートに最初に行かなければならなかった、Bean名の直接のリターンがあります。
- 注文@、検索ビーンのPriorityOrderコメント@、返されたBean名があります。
- 最後に、名前がBeanを一致させる方法を見つけるために(BYNAME)と一致します。
単にマッチングの第ByTypeする方法として理解することができる、BYNAMEと一致する方法で、別の複数の一致した場合は、対応するBeanが注入を行った見つけ、それは例外をスロー見つけることができませんでした。
ノートへのもう一つのポイント:あなたが@Qualifier注釈を使用する場合は、複数の豆自動組立試合は、彼がdetermineAutowireCandidate法(プロテスト)を入力しませんが、直接同じに見えると@QualiferはにBean名Beanを指定しました注入は、直接注入が見つけ、例外がスローされます見つけることができませんでした。