Spring Source resolve a series: initialization process configuration class

Starting today, ready to write a blog about the Spring source code, then ado, let's start out!

1. Preparing the Environment

1) Figure:

PersonService categories:

@Component
public class PersonService {
	public void run(){
		System.out.println("run方法执行了");
	}
}
复制代码

SpringConfiguration类:

@ComponentScan("my.blog")
public class SpringConfiguration {

}
复制代码

Test01 categories:

public class Test01 {
	public static void main(String[] args) {
		//这个构造方法会把Spring所有的环境都准备好
		AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(SpringConfiguration.class);
		PersonService person = ac.getBean(PersonService.class);
		person.run();
	}
}
复制代码

2. Introduction: Notes configure the application context

AnnotationConfigApplicationContext As the name suggests: Notes configure the application context, which I used in the presentation is the way notes

So we need new AnnotationConfigApplicationContextthis object.

If that's xml configuration is required new ClassPathXmlApplicationContext, this should I Needless to say, I think you should know!

Then the object instantiation process, Spring in the end in which people can not see a thing done? Then follow me to uncover the mystery of his!

We click on new AnnotationConfigApplicationContextto see what he's constructor:

public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
		//这个类有父类,所以会先初始化父类的构造方法,接着初始化自己的构造方法

		//调用无参构造方法进行初始化一个读取器和扫描仪
		this();
		
       //这个方法的作用:主要是把配置类的信息加载进工厂中
       //在这里需要你记住一个类:DefaultListableBeanFactory,后面会非常的重要
		register(annotatedClasses);

		//实例化所有被加了组件的对象
		refresh();
	}

复制代码

We find this argument constructor can pass more than a one-time configuration class, in fact, behind the code will traverse annotatedClassesthe array

We look at this()what things done?

	public AnnotationConfigApplicationContext() {
		//这里也会先初始化父类的构造方法
        
        //创建一个读取被加了注解的bean读取器 ,这个读取器到底什么鬼,不是这节的重点,可以先忽略
        //你就知道他创建了一个读取器就完事了
		this.reader = new AnnotatedBeanDefinitionReader(this);
		this.scanner = new ClassPathBeanDefinitionScanner(this);
	}
复制代码

We return to register(annotatedClasses);this method, which is the big brother of this section, we are going to look at what he did dirty work for the Spring!

3. Load configuration class

We click on register(annotatedClasses)

.... ah, it seems futile!

Click this.reader.register(annotatedClasses);method

That's when we found this method began to traverse annotatedClassesthe array, so we can write more than a one-time configuration file passed to the constructor

Start traversing annotatedClasses(Note: this presentation, I just added a configuration class), callregisterBean(annotatedClass);

This time we click on registerBean(annotatedClass);

Click on 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) {
        //(1)(解析:查看下面图)
		AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);
	 
        
        //这个不是重点,跳过
		if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
			return;
		}
        
         //这个不是重点,跳过 instanceSupplier为null值
		abd.setInstanceSupplier(instanceSupplier);

		//(2)得到类的作用域 单例还是多例(解析:查看下面图)
		ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
        
		//把类的作用域赋值给AnnotatedGenericBeanDefinition对象
		abd.setScope(scopeMetadata.getScopeName());

		//生成配置类的名称,如果@Component没有对应的名称   (我没有加名称)
        //默认是类的小驼峰式命名称 (所有此时beanName为springConfiguration)
		String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));

		/**
		 * (3)把AnnotatedGenericBeanDefinition对象传进
		 * 然后获取获取元数据metadata对象,判断元数据对象中是否存在lazy,DependsOn,Primary Role 等注解
		 * 如果有这些注解,则在AnnotatedGenericBeanDefinition对象中记录
		 */
		AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);

		//qualifiers本身传过来的就是一个 null 值
		//如果不手动传,永远为空值,没有意义
		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);
		}
        
         //(4)把abd放进去,赋值给了成员变量beanDefinition
		//把BeanName赋值进去,可以说是增强版的abd对象
		//查看后面的代码发现,其实definitionHolder就只是起到一个临时容器的作用
		BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);

		//这个比较复杂,以后可以讲 和本节无关
		definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);

		//(5)现在又把增强版的 definitionHolder 放到registry这个容器中
		//BeanDefinitionRegistry 顾名思义 就是注册BeanDefinition的
		BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
	}
复制代码

1). We look at the code AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);which things done?

View abd target content through debug

to sum up:

  1. According to the configuration specified class, create a GenericBeanDefinition objects
  2. This GenericBeanDefinition object contains some kind of meta-information, such as information notes: scope, lazy, ComponentScan and other notes
  3. The metadata annotations are stored in GenericBeanDefinition (Metadata) object
  4. Metadata annotation object has a collection of annotations, all annotations stored information

2) Next View ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);

After you do this abd.setScope(scopeMetadata.getScopeName());Methods

3) View AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);

click to enter

Amount ..., this method seems to have nothing ...

Abd objects to pass into the open, and has passed the object abd abd.getMetadata () metadata object

Click on processCommonDefinitionAnnotations(abd, abd.getMetadata());

	static void processCommonDefinitionAnnotations(AnnotatedBeanDefinition abd, AnnotatedTypeMetadata metadata) {
		//判断当前的类是否加了lazy注解
		AnnotationAttributes lazy = attributesFor(metadata, Lazy.class);
        
		//如果不为null,则把AnnotatedBeanDefinition中的 lazyInit 默认的false 修改为true
		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"));
			}
		}
        
		//判断元数据对象中时候有@Primary,默认时候primary是 false ,如果有则该为true
		if (metadata.isAnnotated(Primary.class.getName())) {
			abd.setPrimary(true);
		}
        
		//判断时候有@DependsOn注解
		AnnotationAttributes dependsOn = attributesFor(metadata, DependsOn.class);
		if (dependsOn != null) {
			abd.setDependsOn(dependsOn.getStringArray("value"));
		}

		//判断时候有@Role注解
		AnnotationAttributes role = attributesFor(metadata, Role.class);
		if (role != null) {
			abd.setRole(role.getNumber("value").intValue());
		}
        
		//判断时候有@Description注解
		AnnotationAttributes description = attributesFor(metadata, Description.class);
		if (description != null) {
			abd.setDescription(description.getString("value"));
		}
	}
复制代码

to sum up:

  1. The objects pass in AnnotatedGenericBeanDefinition
  2. Acquiring metadata metdata objects, metadata object is determined whether there is lazy, DependsOn, Primary Role other annotations
  3. If these notes is recorded in AnnotatedGenericBeanDefinition object

4) View BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);

debug found

5) View BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);

click to enter

public static void registerBeanDefinition(
			BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
			throws BeanDefinitionStoreException {

		
		//在这里又获取beanName的名称
		String beanName = definitionHolder.getBeanName();
    
		//现在把definitionHolder拆分了,又把abd对象拿出来了
		//似乎definitionHolder就只是封装了一下,然后又给拆分, 可以理解为一个临时的容器
		registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());

		 //这个不重要,spring当中处理别名的
		String[] aliases = definitionHolder.getAliases();
		if (aliases != null) {
			for (String alias : aliases) {
				registry.registerAlias(beanName, alias);
			}
		}
	}
复制代码

We click on registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());

Found to be an interface, hold down the shortcut key Ctrl + Alt + B, there are three implementation classes, call your attention to the front DefaultListableBeanFactoryhere appeared,

select DefaultListableBeanFactory

	@Override
	public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
			throws BeanDefinitionStoreException {
   //-------------------------------------------------------------------------------
		Assert.hasText(beanName, "Bean name must not be empty");
		Assert.notNull(beanDefinition, "BeanDefinition must not be null");
     
		if (beanDefinition instanceof AbstractBeanDefinition) {
			try {
				((AbstractBeanDefinition) beanDefinition).validate();
			}
			catch (BeanDefinitionValidationException ex) {
				throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
						"Validation of bean definition failed", ex);
			}
		}
        //查看该bean时候在map集合中存储过
		BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
		if (existingDefinition != null) {
			if (!isAllowBeanDefinitionOverriding()) {
				throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);
			}
			else if (existingDefinition.getRole() < beanDefinition.getRole()) {
				// e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE
				if (logger.isInfoEnabled()) {
					logger.info("Overriding user-defined bean definition for bean '" + beanName +
							"' with a framework-generated bean definition: replacing [" +
							existingDefinition + "] with [" + beanDefinition + "]");
				}
			}
			else if (!beanDefinition.equals(existingDefinition)) {
				if (logger.isDebugEnabled()) {
					logger.debug("Overriding bean definition for bean '" + beanName +
							"' with a different definition: replacing [" + existingDefinition +
							"] with [" + beanDefinition + "]");
				}
			}
			else {
				if (logger.isTraceEnabled()) {
					logger.trace("Overriding bean definition for bean '" + beanName +
							"' with an equivalent definition: replacing [" + existingDefinition +
							"] with [" + beanDefinition + "]");
				}
			}
			this.beanDefinitionMap.put(beanName, beanDefinition);
		}
		else {
			if (hasBeanCreationStarted()) {
				// Cannot modify startup-time collection elements anymore (for stable iteration)
				synchronized (this.beanDefinitionMap) {
					this.beanDefinitionMap.put(beanName, beanDefinition);
					List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);
					updatedDefinitions.addAll(this.beanDefinitionNames);
					updatedDefinitions.add(beanName);
					this.beanDefinitionNames = updatedDefinitions;
					removeManualSingletonName(beanName);
				}
			}
     //---------------------------------------------------------------------------------------
            //前面的代码都是一些判断,验证不是重点
            //重点是这里的代码,前方高能
			else {
				//在这个方法中就把 beanDefinition 存储在 DefaultListableBeanFactory的map集合中
				//顾名思义,beanDefinitionMap就是一个存储beanDefinition的map集合
				//在这个集合当中还有Spring当中本身已经初始好的对象
				this.beanDefinitionMap.put(beanName, beanDefinition);
				//把beanName存储在这个list集合中
				this.beanDefinitionNames.add(beanName);
				//这个是去重的,不是重点
				removeManualSingletonName(beanName);
			}
			this.frozenBeanDefinitionNames = null;
		}

		if (existingDefinition != null || containsSingleton(beanName)) {
			resetBeanDefinition(beanName);
		}
	}
复制代码

this.beanDefinitionMap.put(beanName, beanDefinition); prior to

this.beanDefinitionMap.put(beanName, beanDefinition); after that

this.beanDefinitionNames.add(beanName); prior to

this.beanDefinitionNames.add(beanName); after that

Loading the entire configuration on the implementation of the class finished, sum up register(annotatedClasses);what things are done?

  1. Loading configuration metadata category AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);
  2. Abd objects to set the scope
  3. Traversing the metadata annotations, annotation exists a determined time
  4. The configuration information of an object class is stored DefaultListableBeanFactoryin the collection beanDefinitionMap
  5. The class name is stored in the configuration DefaultListableBeanFactoryof the collection beanDefinitionNames

Guess you like

Origin juejin.im/post/5d7b7b346fb9a06b0703ec77