剑指spring源码(一)

19 篇文章 3 订阅

剑指spring源码(一)

入口

配置类

		@ComponentScan("com.lry")
		@Configuration
		public class AppConfig {

		}

入口类

		AnnotationConfigApplicationContext app =
				new AnnotationConfigApplicationContext(AppConfig.class);
		String[] strs = app.getBeanDefinitionNames();
		for (String str:strs) {
			System.out.println(str);
		}

构造器

		public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
		//调用父类构造方法实例化bean工厂DefaultListableBeanFactory
		//初始化BeanDefinition注解读取器以及包扫描器
		this();//第一行代码
		
		//把传入的类进行注册
		//传入的类有两种情况
		//其一是加了@Configuration的配置类FULL
		//其二是没有@Configuration但是有@Component@Service等注解的普通类LITE
		register(annotatedClasses);//第二行代码
		
		refresh();//这个最难 第三行代码
	}

第一行代码this()

由于AnnotationConfigApplicationContext extends GenericApplicationContext
所以实例AnnotationConfigApplicationContext 的时候会调用GenericApplicationContext的构造器如下:

bean工厂的初始化

	public GenericApplicationContext() {
		this.beanFactory = new DefaultListableBeanFactory();
	}

BeanDefinition的读取器和扫描器
BeanDefinition是spring对bean的描述类,里面有属性例如scope,lazy,dependsOn等,之后会一直叫做bd

	public AnnotationConfigApplicationContext() {
		this.reader = new AnnotatedBeanDefinitionReader(this);
		//这个scanner不重要,他仅仅是为了程序员手动调用scan方法才会用到。后面我们做扫描会再new一个scanner
		this.scanner = new ClassPathBeanDefinitionScanner(this);
	}

BeanDefinition的读取器

	public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
		Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
		Assert.notNull(environment, "Environment must not be null");
		this.registry = registry;
		this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);//condition评估会用到
		AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);//重要方法
	}	

registerAnnotationConfigProcessors里的核心代码摘录

	Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
		//beanName=org.springframework.context.annotation.internalConfigurationAnnotationProcessor
		if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
			//spring内部的bd,ConfigurationClassPostProcessor,beanName是上面的字串
			RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def,CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
		}

registerPostProcessor

		//还在启动阶段
		// Still in startup registration phase
		//bd的map
		this.beanDefinitionMap.put(beanName, beanDefinition);
		//beanName的集合
		this.beanDefinitionNames.add(beanName);

类似ConfigurationClassPostProcessor的rootBD一共注册了五个,如下


beanName=org.springframework.context.annotation.internalConfigurationAnnotationProcessor
beanClass=ConfigurationClassPostProcessor.class

beanName=org.springframework.context.annotation.internalAutowiredAnnotationProcessor
beanClass=AutowiredAnnotationBeanPostProcessor.class

支持JSR-250
beanName=org.springframework.context.annotation.internalCommonAnnotationProcessor
beanClass=CommonAnnotationBeanPostProcessor.class

beanName=org.springframework.context.event.internalEventListenerProcessor
beanClass=EventListenerMethodProcessor.class

beanName=org.springframework.context.event.internalEventListenerFactory
beanClass=DefaultEventListenerFactory.class

到此为止this代码解析完毕

入口类打印的bdNames结果

org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
appConfig

可以看出来前五行的打印和我分析的bdNames一摸一样,
至于还有一个appConfig,这就是第二行代码register(annotatedClasses)的事情了。

this干的活
实例bean工厂
bd的读取器reader
bd的扫描器scanner(不重要)
注册了5个rootBD

第二行代码register(annotatedClasses)

可以看出来annotatedClasses可以传多个
reader是第一行代码this创建的,利用bd读取器去注册配置类和普通类

	public void register(Class<?>... annotatedClasses) {
		Assert.notEmpty(annotatedClasses, "At least one annotated class must be specified");
		this.reader.register(annotatedClasses);
	}

this.reader.register(annotatedClasses);最终调用的代码如下

<T> void doRegisterBean(Class<T> annotatedClass, @Nullable Supplier<T> instanceSupplier, @Nullable String name,
			@Nullable Class<? extends Annotation>[] qualifiers, BeanDefinitionCustomizer... definitionCustomizers) {
		//带注解的bd
		AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);
		///condition的判断,如果不满足condition,那么这个bean不会被注册
		if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
			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));
		//处理公共的注解Lazy,Primary,DependsOn,Role
		AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
		//限定符处理,不重要,可以忽略
		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);
		}
		//bdHolder只是在bd上又包装了一层
		BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
		//代理模式处理
		definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
		//注册bd,最最核心就这一行,前面的都可忽略
		BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
	}

registerBeanDefinition

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

		// Register bean definition under primary name.
		String beanName = definitionHolder.getBeanName();
		//核心代码
		registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());

		// Register aliases for bean name, if any.
		//处理bean的别名
		String[] aliases = definitionHolder.getAliases();
		if (aliases != null) {
			for (String alias : aliases) {
				registry.registerAlias(beanName, alias);
			}
		}
	}

registry.registerBeanDefinition的核心代码

		//在第三行代码refresh中会在alreadyCreated的set集合添加beanName
		//这样一来hasBeanCreationStarted()就是返回true了
		//但是前两行代码注册bd走的都是else
		if (hasBeanCreationStarted()) {
				//第三行代码注册bd会进来这里
				//省略
		}else{
				// Still in startup registration phase
				//还在启动注册阶段
				//bd的map
				this.beanDefinitionMap.put(beanName, beanDefinition);
				//beanName的集合
				this.beanDefinitionNames.add(beanName);
		}
		

到这里我们的appconfig也注册进去了。
前两行代码大致做的事情
实例bean工厂
scaner,reader
注册spring5个rootBD
注册我们写的配置类或者普通类

第三行代码太难了,很多扩展接口,循环依赖,循环引用,包扫描都在这里处理
限于篇幅,加之本人还要再研究一段时间,下次再说。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值