Spring source code analysis notes (b)

BeanDefinition, Google has become the definition of Bean's translation, meaning almost, he used to describe the Bean, which store information about Bean series, such as Bean scopes, Bean corresponding to the Class, if lazy loading, such as whether Primary Wait

private static BeanDefinitionHolder registerPostProcessor(
			BeanDefinitionRegistry registry, RootBeanDefinition definition, String beanName) {

		definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
		registry.registerBeanDefinition(beanName, definition);
		return new BeanDefinitionHolder(definition, beanName);
	}

This method BeanDefinition set up a Role, ROLE_INFRASTRUCTURE represent this is spring inside, not user-defined, and then call registerBeanDefinition method, and then point into a port, he has three implementation class
Here Insert Picture Description
DefaultListableBeanFactory is what we call container, and inside stood beanDefinitionMap, beanDefinitionNames, beanDefinitionMap is a hashMap, beanName as Key, beanDefinition as Value, beanDefinitionNames is a collection, stored inside beanName.
ConfigurationClassPostProcessor achieve BeanDefinitionRegistryPostProcessor interfaces, interfaces and extends the BeanDefinitionRegistryPostProcessor BeanFactoryPostProcessor interfaces, BeanFactoryPostProcessor is one of Spring's extension points, ConfigurationClassPostProcessor Spring is a very important class, must firmly bear in mind the above mentioned class and its inheritance.

Here Insert Picture Description
Followed by a second line

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

Multiple clicks find it is registered by the for loop

<T> void doRegisterBean(Class<T> annotatedClass, @Nullable Supplier<T> instanceSupplier, @Nullable String name,
            @Nullable Class<? extends Annotation>[] qualifiers, BeanDefinitionCustomizer... definitionCustomizers) {
        //AnnotatedGenericBeanDefinition可以理解为一种数据结构,是用来描述Bean的,这里的作用就是把传入的标记了注解的类
        //转为AnnotatedGenericBeanDefinition数据结构,里面有一个getMetadata方法,可以拿到类上的注解
        AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);

        //判断是否需要跳过注解,spring中有一个@Condition注解,当不满足条件,这个bean就不会被解析
        if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
            return;
        }

        abd.setInstanceSupplier(instanceSupplier);

        //解析bean的作用域,如果没有设置的话,默认为单例
        ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
        abd.setScope(scopeMetadata.getScopeName());

        //获得beanName
        String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));

        //解析通用注解,填充到AnnotatedGenericBeanDefinition,解析的注解为Lazy,Primary,DependsOn,Role,Description
        AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);

        //限定符处理,不是特指@Qualifier注解,也有可能是Primary,或者是Lazy,或者是其他(理论上是任何注解,这里没有判断注解的有效性),如果我们在外面,以类似这种
        //AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(Appconfig.class);常规方式去初始化spring,
        //qualifiers永远都是空的,包括上面的name和instanceSupplier都是同样的道理
        //但是spring提供了其他方式去注册bean,就可能会传入了
        if (qualifiers != null) {
            //可以传入qualifier数组,所以需要循环处理
            for (Class<? extends Annotation> qualifier : qualifiers) {
                //Primary注解优先
                if (Primary.class == qualifier) {
                    abd.setPrimary(true);
                }
                //Lazy注解
                else if (Lazy.class == qualifier) {
                    abd.setLazyInit(true);
                }
                //其他,AnnotatedGenericBeanDefinition有个Map<String,AutowireCandidateQualifier>属性,直接push进去
                else {
                    abd.addQualifier(new AutowireCandidateQualifier(qualifier));
                }
            }
        }

        for (BeanDefinitionCustomizer customizer : definitionCustomizers) {
            customizer.customize(abd);
        }

        //这个方法用处不大,就是把AnnotatedGenericBeanDefinition数据结构和beanName封装到一个对象中
        BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);

        definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);

        //注册,最终会调用DefaultListableBeanFactory中的registerBeanDefinition方法去注册,
        //DefaultListableBeanFactory维护着一系列信息,比如beanDefinitionNames,beanDefinitionMap
        //beanDefinitionNames是一个List<String>,用来保存beanName
        //beanDefinitionMap是一个Map,用来保存beanName和beanDefinition
        BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
    }

Register arranged in a conventional manner to the class, except that in this method the first parameter, the other parameters are the default values.
By constructing method AnnotatedGenericBeanDefinition obtain BeanDefinition configuration class, there is not may have been similar, registered ConfigurationClassPostProcessor class, but also to get BeanDefinition by the constructor, was just to get through RootBeanDefinition, now it is to get through AnnotatedGenericBeanDefinition .
Here Insert Picture Description
Analyzing or need to skip register, Spring has a @Condition annotation, if the condition is not satisfied, the registered class will be skipped.

Then parse the scope, if not set, the default is a single embodiment.

Get BeanName.

General analytical notes, filled AnnotatedGenericBeanDefinition, analytical notes for the Lazy, Primary, DependsOn, Role, Description.

Qualifier process, not especially @Qualifier notes, there may be a Primary, or Lazy, or other (theoretically any notes, there is no judge the effectiveness of annotations).

The data structures and AnnotatedGenericBeanDefinition beanName encapsulated into an object (this is not very important, can be simply understood as a reference to facilitate transfer).

Registration will eventually call registerBeanDefinition method of DefaultListableBeanFactory to register:

	public static void registerBeanDefinition(
			BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
			throws BeanDefinitionStoreException {
		//获取beanname
		// Register bean definition under primary name.
		String beanName = definitionHolder.getBeanName();
		//注册bean
		registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
		//别名注册
		// Register aliases for bean name, if any.
		String[] aliases = definitionHolder.getAliases();
		if (aliases != null) {
			for (String alias : aliases) {
				registry.registerAlias(beanName, alias);
			}
		}
	}
Published 25 original articles · won praise 22 · views 3632

Guess you like

Origin blog.csdn.net/weixin_42443419/article/details/104324387