当時、私たちはSpringに魅了されていました:Beanアノテーションの実装(6)

SpringBeanの定義とスコープアノテーションの実装

1.クラスパススキャンとコンポーネント管理

3.0以降、次のようにxmlではなくjavaアノテーションを使用してBean定義します。
@ configuration @Bean @Import @DependsOn

  • @コンポーネントは一般的なアノテーションであり、どのBeanにも使用できます。
  • @ Resporityは通常、永続層であるDAOクラスに注釈を付けます
  • @サービスは通常、サービスレイヤーであるサービスクラスに注釈を付けるために使用されます
  • @ Controllerは通常、制御層(mvc)であるControllerクラスで使用されます。

2.メタアノテーション

1. Springが提供する多くのアノテーションは、独自のコード、つまり「メタデータアノテーション」として使用できます。メタアノテーションは、別のアノテーションに適用できる単純なアノテーションです。2。value
()に加えて、メタアノテーションは他の属性、カスタマイズを可能にする

4つの元のアノテーションは次のとおりです。@ Target、@ Retention、@ Documented、@ AliExpress、アノテーションアノテーション定義するように設計されています。その効果は次のとおりです。
アノテーションの@Targetは可能な場合は列挙型クラス値ElemenetTypeに含まれるものを示します。

ElemenetType 説明
ElemenetType.CONSTRUCTOR コンストラクタ宣言
ElemenetType.FIELD ドメイン宣言(列挙型インスタンスを含む)
ElemenetType.LOCAL_VARIABLE ローカル変数宣言
ElemenetType.METHOD メソッド宣言
ElemenetType.PACKAGE パッケージ宣言
ElemenetType.PARAMETER パラメータ宣言
ElemenetType.TYPE クラス、インターフェース(アノテーションタイプを含む)または列挙型宣言

@Retentionは、注釈情報がどのレベルで保存されるかを示します
オプションのパラメーター値は、次のような列挙型RetentionPolicyにあります。

RetentionPolicy 説明
RetentionPolicy.SOURCE 注釈はコンパイラによって破棄されます
RetentionPolicy.CLASS 注釈はクラスファイルで利用できますが、VMによって破棄されます
RetentionPolicy.RUNTIME VM 注釈も実行時に保持されるため、注釈情報はリフレクションメカニズムを介して読み取ることができます。

@Documentedはこの注釈をjavadocに含めます。つまり、この注釈はjavadocツールによってドキュメントに抽出されます。
この注釈の情報内容が異なるため、ドキュメントドキュメントの内容は異なります。@ see、@ paramなどと非常によく似ています。
@AliExpressを使用すると、サブクラスは親クラスのアノテーションを継承できます。

3.クラスの自動検出とBean登録

Springはクラスを自動的に検出し、BeanをApplicationContextに登録できます。
クラスには@ Service @Controllerおよびその他のアノテーションが付けられます。

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd>
<!-- <context:component-scan>可以实现基于类的注解,
而<context:annotation-config>只能在完成了bean的注册配置之后实现对成员变量和方法的注解,
前者包含后者,一般配置了前者之后就不再配置后者了。
AutowiredAnnotationBeanPostProcessor和CommonAnnotationBeanPostProcessor也会被包含 -->
	<context:component-scan base-package:"org.example"/>
<beans>

4.カスタムスキャンにフィルターを使用する

デフォルトでは、クラスが自動的に検出され、Beanが登録されるための条件は次のとおりです。@ component @repository @service @controllerを使用するか、@ Componentカスタムアノテーションを使用します。

上記の動作は、フィルター、次のxml構成を介して変更でき、すべての@resporitoryアノテーション(context:exclude-filter)を無視して、スタブに置き換えます。

<beans>
	<context:component-scan base-package:"org.example">
	<!--包含过滤器 -->
	<context:include-filter type="regex"--通配符
	expression=".Stub.*Respository"/>
	<!--排除过滤器 -->
	<context:exclude-filter type="annotation"
	expression="org.springframework.stereotype.Respository"/>
	</context:component-scan>
<beans>

user-default-filter:false自動検出と登録無効にするために使用することもできます

5.Beanを定義します

Beanを定義する

6.範囲

範囲

7.スプリングプロキシモード

scoped-proxy属性はプロキシを指定します。3つの値から選択できます:no(デフォルト)インターフェイス、target-class

<beans>
	<context:component-scan base-package:"org.example"  scoped-proxy="interface">
</beans>

1.必須

@Requiredアノテーションは
Beanプロパティのsetterメソッドに適用されます。このアノテーションは、影響を受けるBeanプロパティが、Bean定義の明確なプロパティ値を通じて、または自動アセンブリを通じて、構成中に入力(割り当て)される必要があることを意味します。

public class SimpleMovieLister{
    
    
	private MovieFinder  movieFinder;	
	@Required
	public void setMovieFinder(MovieFinder movieFinder){
    
    
		this.movieFinder=movieFinder;
	}
}

2.AutoWired

@AutoWiredは、「従来の」セッターメソッドとしてアノテーションを付けることができます

private MovieFinder  movieFinder;	
@AutoWired
public void setMovieFinder(MovieFinder movieFinder){
    
    
		this.movieFinder=movieFinder;
	}

コンストラクターまたはメンバー変数にも使用できます

@AutoWired
private MovieFinder  movieFinder;	

private Customer**Dao  customer**Dao;
@AutoWired
public  ***(Customer**Dao  customer**Dao){
    
    
		this.customer**Dao=customer**Dao;
	}

デフォルトでは、自動配線が失敗し、適切なBeanが見つからないために例外がスローされた場合、アノテーションで必要な属性をfalseに設定できます。

@AutoWired(required=false)
public void setXX(XX xx){
    
    
    this.xx = xx
}

各クラスには、required = trueとしてマークされたコンストラクターを1つだけ
含めることができます{各クラスの下に複数のコンストラクターが存在する可能性があります} AutoWiredの必要な属性、@ Requiredアノテーションを使用することをお勧めします(上記の場合、AutoWiredの代わりにRequiredを使用します。通常はAutoWired)

3. @ AutoWiredアノテーションと@Resourceアノテーションの違い

  • Springは、それ自体で定義された@Autowiredアノテーションをサポートするだけでなく、JSR-250仕様で定義されたいくつかのアノテーションもサポートします。@Resource、@PostConstruct以及@PreDestroy。
  • @Resourceの役割は、@Autowired按byType(即class)自動的に注入されることを除いて@Autowiredと同等ですが、@Resource默认按byName(即ID)自動的に注入されます。
  • @Resourceには、より重要な2つの属性があります。Springは@Resourcename和typeアノテーションが付けられたname属性をBeanの名前として解析し、type属性はBeanのタイプとして解析します。

したがって、name属性を使用する場合は、byNameの自動注入戦略が使用され、type属性を使用する場合は、byTypeの自動注入戦略が使用されます。name属性もtype属性も指定されていない場合、byName自動注入戦略リフレクションメカニズムを通じて使用されます。

@リソースの組み立て順序

同時に指定された場合name和type、一致するBeanのみがアセンブリのSpringコンテキストから検出され、見つからない
場合は例外がスローされます指定された場合name、一致する名前(id)のBeanがアセンブリのコンテキストから検出されます。それが見つからない場合、および、例外が例外スローされている
指定した場合type、一致するタイプのみBeanはアセンブリのコンテキストで発見され
た場合既没有指定name,又没有指定type、それが見つからないか、複数のビーンが見つかった場合、例外があろうスローされる場合、それは自動的にBYNAME方法に従って組み立てられる、一致がない場合、それが一致する場合に組み立てる自動的に元のマッチタイプにフォールバック、およびだろう。

@Autowiredと@Resourceの違い:

  1. @Autowiredと@Resourceの両方を使用してBeanをアセンブルできます。どちらもフィールドまたはsetterメソッドに書き込むことができます。
  2. @Autowiredはデフォルトで类型アセンブルされます(このアノテーションはSpringに属します)。デフォルトでは、依存オブジェクトが存在する必要があります。null値を許可する場合は、必要な属性をfalseに設定でき@Autowired(required=false)ます(名前を使用する場合)。アセンブリでは、@ Qualifierアノテーションを組み合わせて使用​​できます
  3. @Resource(このアノテーションはJ2EEに属します)、デフォルト名称は名前に従ってアセンブルれます。名前はname属性で指定できます。name属性が指定されていない場合、アノテーションがフィールドに書き込まれると、フィールド名は次のようになります。アノテーションがsetterメソッドで記述されている場合、デフォルトで検索に使用されます。デフォルトでは、属性名がアセンブリに使用されます。名前に一致するBeanが見つからない場合は、タイプに応じてアセンブリが実行されます。ただし、name属性が指定されている場合は、名前に従ってのみアセンブルされることに注意してください。
  4. 使用範囲の違い
    @AutoWiredは、フィールド、コンストラクター、マルチ引数、メソッドに適用されます。これにより、@ Qualifierアノテーションをパラメーターレベルで使用して、範囲を狭めることができます。@ Resource
    メンバー変数に適用されます。パラメーターセッターメソッド1つだけです。したがって、ターゲットはコンストラクターまたはマルチパラメーターメソッドです。最良の方法は修飾子を使用することです

推奨される使用法:@Resourceアノテーションはフィールド上にあるため、setterメソッドを記述する必要はなく、このアノテーションはJ2EEに属しているため、スプリングとの結合が減少します。このコードはよりエレガントに見えます。

4.その他の用途

@Autowiredを使用して、BeanFactory、ApplicationContext、Environment、ResourceLoader、ApplicationEventPublisher、MessageSourceなどのよく知られた解像度依存関係インターフェースに注釈を付けることができます

ここに写真の説明を書いてください
ただし、Orderは配列に対してのみ有効です对map集合无效

BeanOneImplとBeanTwoImplはどちらもBeanInterfaceを実装しています

 @Autowired
 private List<BeanInterface> list;
//遍历list
 for (BeanInterface bean : list) {
    
    
     System.out.println(bean.getClass().getName());
}
//输出
com.zjx.multibean.BeanTwoImpl
com.zjx.multibean.BeanOneImpl

@Autowired
private Map<String, BeanInterface> map;
//遍历map
 for (Map.Entry<String, BeanInterface> entry : map.entrySet()) {
    
    
       System.out.println(entry.getKey() + "   "
                  + entry.getValue().getClass().getName());
	}
//输出
beanOneImpl   com.zjx.multibean.BeanOneImpl
beanTwoImpl   com.zjx.multibean.BeanTwoImpl

5.注意

@AutowiredはSpringBeanPostProcessorによって処理されるため、これらのアノテーションを独自のBeanPostProcessorまたはBeanFactoryPostProcessorタイプに適用することはできません。これらのタイプはXMLまたはSpring @ Beanアノテーションを介してロードする必要があります。

@Qualifier

自動アセンブリのタイプによって、Beanの複数のインスタンスがSpring@Qualifierアノテーションの狭い範囲で使用される(または一意に指定される)場合があり、個別の構成パラメーターまたはプロセスパラメーターを指定するために使用される場合もあります

// 在BeanInvoker类中增加一个成员变量,因为我们不知道BeanInterface的实现类是哪一个
 //(beanOneImpl、beanTwoImpl),通过@Qualifier注解缩小范围为id为”beanTwoImpl”的这个实现类
	@Autowired
    @Qualifier("beanTwoImpl")
    private BeanInterface beanInterface;

@Autowired
private void setComedyCatalog(@Qualifier("对应id") MovieCatalog comedyCatalog){
    
    
    this.comedyCatalog = comedyCatalog;
}

コレクション型変数に注釈を付けるために使用できます

アノテーションインジェクションが名前で実行される場合、主に@Autowiredではありません(@Qualifierを介してBeanの名前を指定することが技術的に可能であっても)、代わりにJSR-250 @Resourceアノテーションを使用して特定のターゲットを識別します一意の名前(これは、宣言されたタイプとは関係のないマッチングプロセスです)

@Resourceアノテーションを使用して、コレクションまたはMapBeanを一意の名前で参照します

Springは@Autowiredを使用してマップを問題
に注入します。Autowiredを使用してマップまたは他のコレクションタイプを注入する場合、springはbeanNameに従ってBeanを取得して割り当てるのではなく、次のコンテナから一致するすべてのBeanを取得します。セットタイプに応じて1回、直接入れます。コレクションへ。
[春] @Autowiredインジェクションクラスのコレクションタイプの詳細な構造

おすすめ

転載: blog.csdn.net/eluanshi12/article/details/86477908