• 35648

    文章

  • 23

    评论

  • 20

    友链

  • 最近新加了很多技术文章,大家多来逛逛吧~~~~
  • 喜欢这个网站的朋友可以加一下QQ群,我们一起交流技术。

SpringFramework之AnnotatedBeanDefinitionReader 原

欢迎来到阿八个人博客网站。本 阿八个人博客 网站提供最新的站长新闻,各种互联网资讯。 喜欢本站的朋友可以收藏本站,或者加QQ:我们大家一起来交流技术! URL链接:https://www.abboke.com/jsh/2019/0628/4154.html

>>>

    Spring版本是5.0.9.release.

    AnnotatedBeanDefinitionReader没有继承任何类。

    在AnnotationConfigApplicationContext中使用到,如下List-1,AnnotatedBeanDefinitionReader的构造方法中参数为BeanDefinitionRegistry

    List-1

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,

    List-2

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中。

    List-3

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中,

    AnnotatedBeanDefinitionReader用于获取一个或多个带有注解的具体类,之后将他们解析为BeanDefintion,之后注册到Registry中;ClassPathBeanDefinitionScanner用获取一个或多个包下的带有注解的类,之后将他们解析为BeanDefintion,注册到Registry中。

    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. 源码

 

相关文章

暂住......别动,不想说点什么吗?
  • 全部评论(0
    还没有评论,快来抢沙发吧!