spring beansのソースコードの解読--Beanの注釈(annotation)

19930 ワード

spring注釈の導入に従って、ますます多くの開発者が注釈を使用するようになりました.この文章は注釈のメカニズムに対して直列式の解説を行います.徹底していることを求めず、spring beans注解の真珠をつなげて、皆様に展示します.
1.spring beansでよく使われるコメント:
  public@interface Autowired:メンバー変数、方法と構成関数を表示して、自動組立の仕事を完成することができます.
Marks a constructor, field, setter method or config method as to be autowired by Spring's dependency injection facilities.
Only one constructor (at max) of any given bean class may carry this annotation, indicating the constructor to autowire when used as a Spring bean. Such a constructor does not have to be public.

Fields are injected right after construction of a bean, before any config methods are invoked. Such a config field does not have to be public.

Config methods may have an arbitrary name and any number of arguments; each of those arguments will be autowired with a matching bean in the Spring container. Bean property setter methods are effectively just a special case of such a general config method. Such config methods do not have to be public.

In the case of multiple argument methods, the 'required' parameter is applicable for all arguments.

In case of a Collection or Map dependency type, the container will autowire all beans matching the declared value type. In case of a Map, the keys must be declared as type String and will be resolved to the corresponding bean names.

Note that actual injection is performed through a BeanPostProcessor which in turn means that you cannot use @Autowired to inject references into BeanPostProcessor or BeanFactoryPostProcessor types. Please consult the javadoc for the AutowiredAnnotationBeanPostProcessor class (which, by default, checks for the presence of this annotation). Since: 2.5
  public@interface Cofigrable  @Configurable 注中のautwire属性はSpringを自動的に組み立てることができます.  @Configurable(autowire=Autowire.BY_TYPE) または  @Configurable(autowire=Autowire.BY_NAME、このようにタイプによって自動的に組み立てることができます.
Marks a class as being eligible for Spring-driven configuration.
Typically used with the AspectJ AnnotationBeanConfigurerAspect.

Since:
2.0
public @interface Value:    SpEL   ,             。
Annotation at the field or method/constructor parameter level that indicates a default value expression for the affected argument.
Typically used for expression-driven dependency injection. Also supported for dynamic resolution of handler method parameters, e.g. in Spring MVC.

A common use case is to assign default field values using "#{systemProperties.myProp}" style expressions.

Note that actual processing of the @Value annotation is performed by a BeanPostProcessor which in turn means that you cannot use @Value within BeanPostProcessor or BeanFactoryPostProcessor types. Please consult the javadoc for the AutowiredAnnotationBeanPostProcessor class (which, by default, checks for the presence of this annotation).

Since:
3.0
public @interface Qualifier:       ,     XML      ,@Qualifier                ,                  
@Qualifier(value = " ") 。
This annotation may be used on a field or parameter as a qualifier for candidate beans when autowiring. It may also be used to annotate other custom annotations that can then in turn be used as qualifiers.
Since:
2.5
public @interface Required     ;
Marks a method (typically a JavaBean setter method) as being 'required': that is, the setter method must be configured to be dependency-injected with a value.
Please do consult the javadoc for the RequiredAnnotationBeanPostProcessor class (which, by default, checks for the presence of this annotation).

Since:
2.0
 
2.注解beanの定義AnnotatedBenDefinition
public interface AnnotatedBeanDefinition extends BeanDefinition {

    /**
     * Obtain the annotation metadata (as well as basic class metadata)
     * for this bean definition's bean class.
     * @return the annotation metadata object (never {@code null})
     */
    AnnotationMetadata getMetadata();

}
   このインターフェースはBeanDefinitionを継承し、Bean definitionの注釈メタデータを取得するためのget Metadata()方法を提供する.
このうち、AnnotationMetadataは、特定のカテゴリにアクセスするための抽象的なインターフェースを定義しています.このクラスをロードする必要がありません.
public interface AnnotationMetadata extends ClassMetadata, AnnotatedTypeMetadata {
}
ClassMetadata              ,       。      :
String getClassName()       。boolean isInterface()         。boolean isAbstract()          。boolean isConcrete()          。boolean isFinal()       final boolean hasSuperClass()         
String getSuperClassName()       ,      null.
String[] getInterfaceNames()         ,    ,   .
String[] getMemberClassNames()         。
AnnotatedType Metadataは特定のタイプにアクセスする注釈を定義しています.ロードクラスは必要ありません.主な方法は:
boolean isAnnotated(String annotationType)          
Map getAnnotationAttributes(String annotationType,boolean classValuesAsString)           

AnnotationMetadataの標準実装クラスStandard AnnotationMetadataは、標準的な反射を使用して作成されたクラスの内部注解情報を取得します.主な方法は:
getAllAnnotationAttributes(String annotationType) 
getAnnotatedMethods(String annotationType) 
hasMetaAnnotation(String annotationType) 
isAnnotated(String annotationType) 
hasAnnotatedMethods(String annotationType) 
AnnotationMetadataはもう一つのサブクラスがあります.AnnotationMetadata Readingvisitorはバイトコードのアクセスが実現されます.
class ClassMetadataReadingVisitor extends ClassVisitor implements ClassMetadata {
}
visitorモードを調べてみましょう.
定義:
The ギャングオブフォール defines the Visitor as: "Represent an operation to be performed on elemens of an object struct.Visitor lets You define a new operation without change the clases of the elemens on which it operates."
The nature of the Visitor makes it an ideal pattern to plug into public API s thus allowing its clients to perform operation a classiting a“visiting”clast without having to dify the source.
uml構造図は以下の通りです.
 まとめ:vistor設定モードは状態を抽象化してインターフェース(訪問者)となり、状態によって異なる実現類(異なる訪問者)となります.
 3. 注解beanの実現類
    3.1 AnnotatedGeneraicBenDefinition
          GeneraicBeanDefinitionを継承し、注釈要素に対するサポートを追加しました.このサポートはAnnotationBeanDefinitionによって暴露された注釈要素インターフェースです.
    GeneraicBeanDefinitionは、主にAnnotatedBeanDefinition上の動作をテストするために使用されています.例えば、springのcomponentスキャンサポートの実装において(デフォルトの実装クラスはScannenDefinitionであり、AnnotatedBenDefinitionインターフェースも同様に実現されています.)
  3.2 ConfigrationClass BeanDefinition
    ConfigrationClass BeanDefinitionはConfigrationClass BeanDefinitionReaderの内部クラスであり、ConfigrationClass BeanDefinitionReaderは属性を完全に充填した構成例を読み取り、context内で所与のBeanDefinitionRegistryによってbean definitionを登録します.このクラスはBeanDefinitionReaderの層の後に改造されますが、配置類を継承または拡張していません.
   3.3 ScannendGenericBenDefinition
 asmベースのクラス解析器は、GeneraicBenDefinition類の拡張であり、注釈メタデータをサポートしています.このサポートはAnnotatedBenDefinitionインターフェースを通じて実現されます.
4.注の解析と処理
4.1@Autowired注解AutowiredAnnotationBeanPostProcessorを実現する
   
public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter
        implements MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware {
}
AutowiredAnnotationBeanPostProcessor      BeanPostProcessor,        field,setter          。    5 java            。spring      @Autowired @Value。
: JSR-330 @inject , @Autowired 。

bean required , required true , spring bean , 。 non-required , 。 spring bean , , 。 public 。
Field , , field public
, spring bean。bean setter 。 public
: AutowiredAnnotationBeanPostProcessor xml , AutowiredAnnotationBeanPostProcessor bean definition, 。

,MergedBeanDefinitionPostProcessor :
public interface MergedBeanDefinitionPostProcessor extends BeanPostProcessor {

    /**
     * Post-process the given merged bean definition for the specified bean.
     * @param beanDefinition the merged bean definition for the bean
     * @param beanType the actual type of the managed bean instance
     * @param beanName the name of the bean
     */
    void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class> beanType, String beanName);

}
BeanPostProcessor              bean       ,  :  marker            。
applicationContext bean BeanPostProcessor bean, bean。 bean factory Post-processor, bean factory bean 。

,post-processor bean marker postProcessBeforeInitialization(java.lang.Object, java.lang.String); bean postProcessAfterInitialization(java.lang.Object, java.lang.String).
4.2@configrable注解AnnotationBeanWiringInfoResoolverを実現します. 
設定  @Configurable 注中のautwire属性はSpringを自動的に組み立てることができます.  @Configurable(autowire=Autowire.BY_TYPE) または  @Configurable(autowire=Autowire.BY_NAME、このようにタイプによって自動的に組み立てることができます.
    AnnotationBeanWiringInfoResoolverはBeanWiringInfoResolaverから継承されています.BeanWiringInfoResolaverはconfigrableを使って、どのような種類が自動バインディングされているのかを探しています.
public class AnnotationBeanWiringInfoResolver implements BeanWiringInfoResolver {
}
BeanWiringInfoResolaverのresoveWiringInfoを実現しました.
@Override
    public BeanWiringInfo resolveWiringInfo(Object beanInstance) {
        Assert.notNull(beanInstance, "Bean instance must not be null");
        Configurable annotation = beanInstance.getClass().getAnnotation(Configurable.class);
        return (annotation != null ? buildWiringInfo(beanInstance, annotation) : null);
    }

    /**
     * Build the BeanWiringInfo for the given Configurable annotation.
     * @param beanInstance the bean instance
     * @param annotation the Configurable annotation found on the bean class
     * @return the resolved BeanWiringInfo
     */
    protected BeanWiringInfo buildWiringInfo(Object beanInstance, Configurable annotation) {
        if (!Autowire.NO.equals(annotation.autowire())) {
            return new BeanWiringInfo(annotation.autowire().value(), annotation.dependencyCheck());
        }
        else {
            if (!"".equals(annotation.value())) {
                // explicitly specified bean name
                return new BeanWiringInfo(annotation.value(), false);
            }
            else {
                // default bean name
                return new BeanWiringInfo(getDefaultBeanName(beanInstance), true);
            }
        }
    }
 4.3@qualiferの注釈実現類Qualfier AnnotationAutowireCanddidateResolaver
 
public class QualifierAnnotationAutowireCandidateResolver extends GenericTypeAwareAutowireCandidateResolver {
}

public class GenericTypeAwareAutowireCandidateResolver implements AutowireCandidateResolver, BeanFactoryAware {
}
その中でAutowireCanddidateResolaverは、特定のbean definitionに対する特定の依存性を決定するポリシーインターフェースであり、自動バインディングの候補として使用できるかどうか、その主要な方法は以下の通りである.
bollan isAutowireCanddidate(BenDefinitionHolder bdHolder、DependencyDescriptor descriptor)
Object getLazyResoloution ProxyIfNecessary(DependencyDescriptor descriptor、String beanName)
Object get SuggetedValue(DependencyDescriptor descriptor)
 Qualfier AnnotationAutowireCanddidateResolaverは間接的にAutowireCandar Resolaverを実現して、自動バインディングするfieldまたはパラメータとbean definitionに@qualiferの注釈によって一致します.@valueの注釈によって表現を結合する値もサポートされます.
また、JSR-330のjavax.inject.Qualfierの注釈だけです.
4.4@required注解実現類RequiredAnnotationBeanPostProcessor.
public class RequiredAnnotationBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter
        implements MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware {
}
AutowiredAnnotationBeanPostProcessorと同様に、直接的にBenPostProcessorから継承され、javaBean属性の配置に対する制約が追加されました.java 5の注釈はbeanのrequired属性を検出できます.springはデフォルトでは@Required注釈です.
    AutowiredAnnotationBeanPostProcessor       xml  ,            
    AutowiredAnnotationBeanPostProcessor       xml  ,            AutowiredAnnotationBeanPostProcessor bean definition,             。   AutowiredAnnotationBeanPostProcessor  ,      。
4.5初期化と廃棄方法の注釈実現類Init DestroyAnnotationBeanPostProcessor
public class InitDestroyAnnotationBeanPostProcessor
        implements DestructionAwareBeanPostProcessor, MergedBeanDefinitionPostProcessor, PriorityOrdered, Serializable {
}
InitDestroyAnnotationBeanPostProcessは間接的にBenPostProcessを継承しており、注釈による初期化と廃棄方法を実現しました.
「init AnnotationType」と「destroyAnnotationType」の属性によって指定された注釈の種類をチェックします.任意のユーザー定義の注釈も使用できます.
コメントの初期化と廃棄は、任意の可視方法で使用できます.public、package-protected、protected、prvateなど.複数の方法について注釈ができますが、一つの初期化と廃棄方法についてそれぞれ注釈を行うことを推奨します.
 
リボン:
 Spring 3の注釈に基づいてBen依存注入サポートを実現するために、Springは注入注解に依存しています.Springは注入注解に依存しています.JSR-250の注釈:Javaプラットフォームの共通注釈は、Java EE 5仕様の一つであり、JDK 6ではデフォルトでこれらの注釈が含まれています.Spring 2.5からサポートを開始します.JSR-330注:Javaは注入基準に依存しています.Java EE 6規格の一つで、将来のJDKバージョンに加入して、Spring 3からサポートを開始することができます.
このうち、Springは注入注解1@Requiredに依存しています.2@Autowired:自動組立2 XML構成による自動組立の代わりに、@Autowiredによる自動組立が行われていますが、デフォルトでは、タイプ別の注入によって、ビルダー、フィールド、メソッド注入3@Valueに使用できます.SpEL式を注入してSpEL式を注入します.フィールド方法やパラメータ上に@Value(value=「SpEL式」)を置くことができます. @Value(value=「啱{message}」) 4@Qualfier:記述子を限定して、細粒度選択候補@Qualfier限定記述子は名前によって注入できますが、より細かい粒度の制御ができます.候補者@Qualfier(value=「限定識別子」)はどうやって選択できますか? JSR-250注釈1@Resource:自動組立、デフォルトはタイプ別組立で、指定されたname属性は名前によって組み立てられ、下記のように@Resource(name=「識別子」)を指定することができます. フィールドまたはセット方法 
2@PostConstructとPredestry:注解で初期化と廃棄方法を指定して定義します.
 
JSR-330注釈1@Inject:デフォルトの@Autowiredに相当します.required属性2@Named:Bean名前を指定して、Springが@Qualfierを所有するデフォルトに対応して、Bean名前によって注入された場合3@Qualfier:Springが持つ@Qualfierの中の拡張@Qufier属性のみに対応します.

1. http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/beans/factory/annotation/
2. http://blog.csdn.net/wangshfa/article/details/9712379