深夜敲代码 潜水
  • 5发帖数
  • 5主题数
  • 0关注数
  • 0粉丝
开启左侧

万字长文!Spring源码解析(建议收藏)

[复制链接]
深夜敲代码 发表于 2021-8-7 21:44:41 | 显示全部楼层 |阅读模式 打印 上一主题 下一主题
Spring源码解析(扫描bean)

测试用例代码块

//AppConfig.java类@ComponentScan({"com.llsydn"})@Configurationpublic class AppConfig {        @Bean        public ConfigDao1 configDao1(){   //自己写一个configDao1类即可                return new ConfigDao1();        }        @Bean        public ConfigDao2 configDao2(){   //自己写一个configDao2类即可                configDao1();                return new ConfigDao2();        }}//IndexDao.java类@Componentpublic class IndexDao {        public void query(){                System.out.println("query");        }}//Test.java类public static void main(String[] args) {        AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext();        ac.register(AppConfig.class);        ac.refresh();        IndexDao indexDao = ac.getBean(IndexDao.class);        System.out.println(indexDao);        indexDao.query();}

  • 这里我是直接用AnnotationConfigApplicationContext类初始化spring的环境,这个类是基于注解配置应用上下文(即是用注解的方式初始化一个spring容器)
Spring中用来注解Bean界说的类有两个:AnnotationConfigApplicationContext和AnnotationConfigWebApplicationContex。AnnotationConfigWebApplicationContext是AnnotationConfigApplicationContext的web版本两者的用法以及对注解的处置惩罚方式几乎没有什么差异通太过析这个类我们知道注册一个bean到spring容器有两种办法:一、直接将注解Bean注册到容器中:(参考)public void register(Class... annotatedClasses)但是直接把一个注解的bean注册到容器当中也分为两种方法1、在初始化容器时注册并且解析2、也可以在容器创建之后手动调用注册方法向容器注册,然后通过手动刷新容器,使得容器对注册的注解Bean进行处置惩罚。二、通过扫描指定的包及其子包下的全部类扫描其实同上,也是两种方法,初始化的时候扫描,和初始化之后再扫描下面进入spring容器初始化源码分析


  • (1) AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext();
public class AnnotationConfigApplicationContext extends GenericApplicationContext/*** 这个类顾名思义是一个reader,一个读取器 * 读取什么呢?照旧顾名思义AnnotatedBeanDefinition意思是读取一个被加了注解的bean * 这个类在构造方法中实例化的 */private final AnnotatedBeanDefinitionReader reader;/** * 同意顾名思义,这是一个扫描器,扫描全部加了注解的bean *  同样是在构造方法中被实例化的 */private final ClassPathBeanDefinitionScanner scanner;/** * 初始化一个bean的读取和扫描器 * 何谓读取器和扫描器参考上面的属性注释 * 默认构造函数,如果直接调用这个默认构造方法,需要在稍后通过调用其register() * 去注册配置类(javaconfig),并调用refresh()方法刷新容器, * 触发容器对注解Bean的载入、解析和注册过程 */public AnnotationConfigApplicationContext() {        /**         * 父类的构造方法         * 创建一个读取注解的Bean界说读取器         * 什么是bean界说?BeanDefinition         */        this.reader = new AnnotatedBeanDefinitionReader(this);        //可以用来扫描包或者类,继而转换成bd        //但是实际上我们扫描包工作不是scanner这个对象来完成的        //是spring自己new的一个ClassPathBeanDefinitionScanner        //这里的scanner仅仅是为了步伐员能够在外部调用AnnotationConfigApplicationContext对象的scan方法        this.scanner = new ClassPathBeanDefinitionScanner(this);}这里创建一个AnnotationConfigApplicationContext对象,重要是做了3个重要的操纵。 1.创建一个new DefaultListableBeanFactory() 是一个Bean工厂容器 2.创建一个new AnnotatedBeanDefinitionReader(this),是Bean的读取器 3.创建一个new ClassPathBeanDefinitionScanner(this),是Bean的扫描器
为什么这里会创建一个DefaultListableBeanFactory()实例的beanFactory? 1.这个beanFactory重要是用来存放Spring管理的Bean对象,一个Bean存放的工厂。 2.怎么会调用了这步new DefaultListableBeanFactory()?
因为AnnotationConfigApplicationContext继承了GenericApplicationContext,即在创建AnnotationConfigApplicationContext对象,会先执行父类GenericApplicationContext的构造方法。所以这里是在父类的构造方法中,执行了new DefaultListableBeanFactory()创建了一个beanFactory对象。 public GenericApplicationContext() { this.beanFactory = new DefaultListableBeanFactory(); }
AnnotationConfigApplicationContext 继承了GenericApplicationContext GenericApplicationContext 实现了 BeanDefinitionRegistry
即有:AnnotationConfigApplicationContext 也实现了BeanDefinitionRegistry,AnnotationConfigApplicationContext 也是一个registry类。这个registry比力重要,registry有registerBeanDefinition(注册一个bean界说到bean工厂)、getBeanDefinition(从bean工厂获取一个Bean界说)等功能。所以AnnotationConfigApplicationContext 也是有可以往bean工厂中注册bean的能力。
//创建一个bean读取器过程分析:this.reader = new AnnotatedBeanDefinitionReader(this);public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {        this(registry, getOrCreateEnvironment(registry));}public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {        this.registry = registry;  //将registry赋值        this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);        AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);}public static void registerAnnotationConfigProcessors(BeanDefinitionRegistry registry) {    //重要方法        registerAnnotationConfigProcessors(registry, null);}public static Set registerAnnotationConfigProcessors(BeanDefinitionRegistry registry, @Nullable Object source) {        //获取到刚创建完的DefaultListableBeanFactory对象,然后给这个对象的某些属性赋值。        DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);        if (beanFactory != null) {                if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {                        //AnnotationAwareOrderComparator重要能解析@Order注解和@Priority                        beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);                }                if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {                        //ContextAnnotationAutowireCandidateResolver提供处置惩罚延迟加载的功能                        beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());                }        }        //给Spring容器添加Spring内部的特殊Bean对象(7个)        //1.往BeanDefinitionMap注册一个ConfigurationClassPostProcessor        Set beanDefs = new LinkedHashSet(8);        //BeanDefinitio的注册,这里很重要,需要理解注册每个bean的类型        if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {                //需要注意的是ConfigurationClassPostProcessor的类型是BeanDefinitionRegistryPostProcessor                //而 BeanDefinitionRegistryPostProcessor 最终实现BeanFactoryPostProcessor这个接口                RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);                def.setSource(source);                beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));        }        //2.往BeanDefinitionMap注册一个AutowiredAnnotationBeanPostProcessor        if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {                //AutowiredAnnotationBeanPostProcessor 实现了 MergedBeanDefinitionPostProcessor                //MergedBeanDefinitionPostProcessor 最终实现了 BeanPostProcessor                RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);                def.setSource(source);                beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));        }        //3.往BeanDefinitionMap注册一个RequiredAnnotationBeanPostProcessor        if (!registry.containsBeanDefinition(REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {                RootBeanDefinition def = new RootBeanDefinition(RequiredAnnotationBeanPostProcessor.class);                def.setSource(source);                beanDefs.add(registerPostProcessor(registry, def, REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME));        }        //4.往BeanDefinitionMap注册一个CommonAnnotationBeanPostProcessor        // Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.        if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {                RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);                def.setSource(source);                beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));        }        //5.往BeanDefinitionMap注册一个PersistenceAnnotationBeanPostProcessor        // Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.        if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {                RootBeanDefinition def = new RootBeanDefinition();                try {                        def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,                                        AnnotationConfigUtils.class.getClassLoader()));                }                catch (ClassNotFoundException ex) {                        throw new IllegalStateException(                                        "Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);                }                def.setSource(source);                beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));        }        //6.往BeanDefinitionMap注册一个EventListenerMethodProcessor        if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {                RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);                def.setSource(source);                beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));        }        //7.往BeanDefinitionMap注册一个DefaultEventListenerFactory        if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {                RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);                def.setSource(source);                beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));        }        return beanDefs;}//将**Processor类型的对象,注册到bean工厂中private static BeanDefinitionHolder registerPostProcessor(BeanDefinitionRegistry registry, RootBeanDefinition definition, String beanName) {        definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);        //这里重要的代码,将bean界说注册到bean工厂当中        registry.registerBeanDefinition(beanName, definition);        return new BeanDefinitionHolder(definition, beanName);}复制代码这里创建一个AnnotatedBeanDefinitionReader对象,重要是做了2个重要的操纵: 1.给在GenericApplicationContext()刚创建的beanFactory对象的某些属性赋值:
beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);(重要能解析@Order注解和@Priority) beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());(提供处置惩罚延迟加载的功能)
2.往bean工厂中注册6个spring内部对象,重要是**BeanPostProcessor类型的对象。(Spring的扩展点之一)
这里特殊重要的类是ConfigurationClassPostProcessor,这个类完成bean的扫描。

  • (2)ac.register(AppConfig.class);
/** * 注册单个bean给容器 * 好比有新加的类可以用这个方法 * 但是注册之后需要手动调用refresh方法去触发容器解析注解 * * 有两个意思: * 他可以注册一个配置类 * 他还可以单独注册一个bean */public void register(Class... annotatedClasses) {        this.reader.register(annotatedClasses);}public void register(Class... annotatedClasses) {        for (Class annotatedClass : annotatedClasses) {                registerBean(annotatedClass);        }}public void registerBean(Class annotatedClass) {        //真正的注册bean的方法        doRegisterBean(annotatedClass, null, null, null);} void doRegisterBean(Class annotatedClass, @Nullable Supplier instanceSupplier, @Nullable String name,                        @Nullable Class

精彩评论3

nihao23166967 发表于 2021-8-8 17:30:35 | 显示全部楼层
转发了
cluo爱编程 发表于 2021-8-8 07:12:46 | 显示全部楼层
转发了
通往大数据的地铁 发表于 2021-8-7 23:28:34 | 显示全部楼层
转发了
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

猜你喜欢
在线客服邮箱
wxcy#wkgb.net

邮箱地址#换为@

Powered by 创意电子 ©2018-现在 专注资源实战分享源码下载站联盟商城