SpringFramework之AnnotatedBeanDefinitionReader

    Spring版本是5.0.9.release.java

    AnnotatedBeanDefinitionReader沒有繼承任何類。git

    在AnnotationConfigApplicationContext中使用到,以下List-1,AnnotatedBeanDefinitionReader的構造方法中參數爲BeanDefinitionRegistrygithub

    List-1web

public class AnnotationConfigApplicationContext extends GenericApplicationContext implements AnnotationConfigRegistry {

	private final AnnotatedBeanDefinitionReader reader;

	private final ClassPathBeanDefinitionScanner scanner;


	/**
	 * Create a new AnnotationConfigApplicationContext that needs to be populated
	 * through {@link #register} calls and then manually {@linkplain #refresh refreshed}.
	 */
	public AnnotationConfigApplicationContext() {
		this.reader = new AnnotatedBeanDefinitionReader(this);
		this.scanner = new ClassPathBeanDefinitionScanner(this);
	}
...

    AnnotatedBeanDefinitionReader的重要方法是register,以下List-2,spring

    List-2api

public void register(Class<?>... annotatedClasses) {
    for (Class<?> annotatedClass : annotatedClasses) {
        registerBean(annotatedClass);
    }
}

public void registerBean(Class<?> annotatedClass) {
    doRegisterBean(annotatedClass, null, null, null);
}

<T> void doRegisterBean(Class<T> annotatedClass, @Nullable Supplier<T> instanceSupplier, @Nullable String name,
        @Nullable Class<? extends Annotation>[] qualifiers, BeanDefinitionCustomizer... definitionCustomizers) {

    AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);//1
    if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {//2
        return;
    }
    abd.setInstanceSupplier(instanceSupplier);
    ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
    abd.setScope(scopeMetadata.getScopeName());
    String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));//3

    AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);//4
    if (qualifiers != null) {
        for (Class<? extends Annotation> qualifier : qualifiers) {
            if (Primary.class == qualifier) {
                abd.setPrimary(true);
            }
            else if (Lazy.class == qualifier) {
                abd.setLazyInit(true);
            }
            else {
                abd.addQualifier(new AutowireCandidateQualifier(qualifier));
            }
        }
    }
    for (BeanDefinitionCustomizer customizer : definitionCustomizers) {
        customizer.customize(abd);
    }

    BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
    definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
    BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}
  1.  List-2中,將類轉換爲AnnotatedGenericBeanDefinition。
  2. 調用conditionEvaluator的shouldSkip判斷是否須要過濾,shouldSkip方法中先判斷類上是否有Conditional註解,只處理有Conditional註解或其衍生註解的狀況。
  3. 獲取beanName,若是咱們設置了value則取其值,若是沒有設置,底層上是調用JDK的Introspector.decapitalize方法,好比類名是HelloWorld,則對應的beanName是helloWorld。
  4. 調用AnnotationConfigUtils.processCommonDefinitionAnnotations,獲取Lazy、Primary、DependsOn等註解的值。

    最後將這個BeanDefinition註冊到registry中。app

    List-3this

public static void processCommonDefinitionAnnotations(AnnotatedBeanDefinition abd) {
    processCommonDefinitionAnnotations(abd, abd.getMetadata());
}

static void processCommonDefinitionAnnotations(AnnotatedBeanDefinition abd, AnnotatedTypeMetadata metadata) {
    AnnotationAttributes lazy = attributesFor(metadata, Lazy.class);
    if (lazy != null) {
        abd.setLazyInit(lazy.getBoolean("value"));
    }
    else if (abd.getMetadata() != metadata) {
        lazy = attributesFor(abd.getMetadata(), Lazy.class);
        if (lazy != null) {
            abd.setLazyInit(lazy.getBoolean("value"));
        }
    }

    if (metadata.isAnnotated(Primary.class.getName())) {
        abd.setPrimary(true);
    }
    AnnotationAttributes dependsOn = attributesFor(metadata, DependsOn.class);
    if (dependsOn != null) {
        abd.setDependsOn(dependsOn.getStringArray("value"));
    }

    if (abd instanceof AbstractBeanDefinition) {
        AbstractBeanDefinition absBd = (AbstractBeanDefinition) abd;
        AnnotationAttributes role = attributesFor(metadata, Role.class);
        if (role != null) {
            absBd.setRole(role.getNumber("value").intValue());
        }
        AnnotationAttributes description = attributesFor(metadata, Description.class);
        if (description != null) {
            absBd.setDescription(description.getString("value"));
        }
    }
}

    這樣,有@Component註解及其衍生註解的類都註冊到registry中,lua

    AnnotatedBeanDefinitionReader用於獲取一個或多個帶有註解的具體類,以後將他們解析爲BeanDefintion,以後註冊到Registry中;ClassPathBeanDefinitionScanner用獲取一個或多個包下的帶有註解的類,以後將他們解析爲BeanDefintion,註冊到Registry中。spa

    AnnotationConfigApplicationContext使用AnnotatedBeanDefinitionReader和ClassPathBeanDefinitionScanner,將帶有註解的類解析爲BeanDefinition,以後註冊到Registry中;ClassPathXmlApplicationContext則使用XmlBeanDefinitionReader將xml的bean配置解析爲BeanDefinition,以後註冊到Registry中。

    Springboot中,若是是servlet web應用,則使用AnnotationConfigServletWebServerApplicationContext,也和AnnotationConfigApplicationContext相似,使用了AnnotatedBeanDefinitionReader和ClassPathBeanDefinitionScanner,以下List-4.

    List-4

public class AnnotationConfigServletWebServerApplicationContext
		extends ServletWebServerApplicationContext implements AnnotationConfigRegistry {

	private final AnnotatedBeanDefinitionReader reader;

	private final ClassPathBeanDefinitionScanner scanner;

	private final Set<Class<?>> annotatedClasses = new LinkedHashSet<>();

	private String[] basePackages;

	/**
	 * Create a new {@link AnnotationConfigServletWebServerApplicationContext} that needs
	 * to be populated through {@link #register} calls and then manually
	 * {@linkplain #refresh refreshed}.
	 */
	public AnnotationConfigServletWebServerApplicationContext() {
		this.reader = new AnnotatedBeanDefinitionReader(this);
		this.scanner = new ClassPathBeanDefinitionScanner(this);
	}
...

 

Reference

  1. 源碼
相關文章
相關標籤/搜索