spring源码-register方法
前面结束了this方法对于两个类的创建
总结来说reader的创建就是做了对环境的获取并设置,载入了核心注解和类级别注解,而Scanner的创建就是做了创建了一个当@componentScan扫描时用来识别当前类是否需要被spring管理,重点关注了component注解和他的子注解
那么以上为第一个方法
以下为第二个方法register

同样的我们进入观察

这里我们使用到了前面创建的AnnotatedBeanDefinitionReader实例

我们只传入了AppConfig.class

调用到同类下的doRegisterBean,传入AppConfig.class其他都为null

同样的调用到doRegisterBean方法,这里我们需要看的方法也比较多
我们一个个来看
new AnnotationGenericBeanDefinition(AppConfig.class)
我们进入查看
这里将我们的AppConfig.class进行了set,并且调用了AnnotationMetadata.introspect(AppConfig.class)
这个方法我们需要查看一下

从注解描述我们能够看出,这是一个工厂方法去创建一个实例,给定一个class能够去使用反射。
我们在进入到from方法中
这里做了创建standardAnnotationMetadata(标准注解元数据)

先看super将AppConfgi.class传进去了

这里只做了一个赋值,那么这个introspectedClass和这个类到底是用来干什么的呢?我们看看它的描述和其他方法的名称
ClassMetadata使用反射来反思一个被给定的类
再看看它的方法


拿classname,拿interfaceName之类的,我们很容易就能猜到,他是不是使用反射来提供类的一些信息?
再看第二个方法from

调用了from函数

做了一些属性的set
那么他究竟是做什么的呢?

好像就是搜索注解和调整注解属性之类的?没用到暂时先这么认为,总之第二个方法也就是做一些set,可以去做注解的修改?反正还没使用,不需要我们去了解它的用处
我们再看第三个赋值

将注解嵌套起来

那么我们再回看这里,是不是这一段beanDefinition主要就是做了这么几个功能,首先通过反射去获取类的一些信息,然后可以去搜索注解,修改注解,最后提供是否允许嵌套的注解?还是比较清晰的
那么我们接着往下将

这个if里this.conditionEvaluator是不是很熟悉,他是在第一个reader分支进行的创建进行赋值的

进入后跳到这里,然后进行判断,判断肯定进不去啊,因为我们的AppConfig没有使用到conditional注解啊,这里从名字就能看出来了,是这样的,AppConfig被new了一个annotationGenericBeandefinition,去进行了获取类信息,那么我们的metadata里是一些类的信息,metadata.isAnnotated计算出来为0,那么这个判断体就要进入,返回false

那么继续往下走,set了一个supplier,这个传进来就是null
再就是scopeMetadata,这里我们走进去看看,他是一个接口

那么我们找他的实现类AnnotationScopeMetadataResolver

这里它首先创建了一个ScopeMetadata,再创建时他会初始化一个singleton属性,然后我们传进来的前面创建的abd也就是我们的AppConfig类的信息,肯定是继承自AnnotationBeanDefinition的,所以会进入判断体,我们再看先做了一个强转,然后执行attributesFor方法,我们看看他里面到底做了什么

主要看这两个方法,一个fromMap一个是getAnnotationAttributes,我们先来看参数
它在这get想拿scope,那他能拿到吗?我们没有在AppConfig上写scope类型,那他怎么拿到的,那只能返回missing,所以他会进入判断体返回null

同时也进入map的null,return null

返回到外面

没有scope返回的就是默认的singlton,那么就给这个AppConfig设置了singleton,然后设置beanName查看之前的传入链能够得知,name也是null,generateBeanName就不看了,里面生成beanName还有一些将AppConfig改成appConfig之类的算法,总之就是转换一些类名
我们接着来看下一句processCommonDefinitionAnnotations

继续往里进

attributes又见面了,那么这里也一样,判断有没有加lazy标签,肯定没有啊,在判断有没有primary,也没有跳过,跳过跳过,全部跳过,因为我们没有在AppConfig上写这些注解
又出来了

又因为我们传入的qualifiers和customizer也是null,所以继续跳过这两个判断,到最后的new BeanDefinitionHolder中,之前说过BeanDefinitionHolder里面就存储一些beanDefinition,beanName和别名,继续往下,applyScopedProxyMode


所以AppConfig这里相当于啥都没有做又出来
最后做registerBeanDefinition

进入这个方法查看

拿到刚才存储的BeanName之后去调用registerBeanDefinition,这里的register是之前new AnnotatedBeanDefinitionReader时构造函数赋值的,也就是AnnotationConfigApplicationContext,那么这个是genericApplicationContext的子类,那么就会去调用genericApplicationContext的方法
再进入,又一次的走到了这个方法

之前的文章讲过吧?第一篇读reader分支就讲过了,就是做一些判断然后做beanDefinition的注册,之前那次我们创建的是spring容器中那几个核心的bean,必须拥有他们才能够支持我们spring的使用,而这次我要注册的是我们的appconfig作为我们的bean来使用
到这里就算完成了我们register方法的一个源码解析
总结一些,我们的register是去将我们需要创建的容器做一个注册,先创建beanDefinition,然后查看设置scope,之后查看是否有lazy或者优先级的注解,到最后创建我们的holder进行存储beanDefinition和BeanName,别名,再使用上代理模式,最后从Holder中取出做BeanDefinition的创建

浙公网安备 33010602011771号