美文网首页springspring
spring源码分析

spring源码分析

作者: 念䋛 | 来源:发表于2021-08-14 13:22 被阅读0次

    从AnnotationConfigApplicationContext切入分析源码,

    public class SpringAnnotation {
        public static void main(String[] args) {
            //查找配置类.配置类有扫描类的路径,满足条件的放到容器中
            AnnotationConfigApplicationContext configApplicationContext = new AnnotationConfigApplicationContext (MyConfiguration.class);
            //获取bean
            MySpringBean mySpringBean = (MySpringBean)configApplicationContext.getBean ("mySpringBean");
            System.out.println (mySpringBean.getName ());
            configApplicationContext.close ();
        }
    
    }
    

    AnnotationConfigApplicationContext的类图,其中继承了GenericApplicationContext,也继承了BeanDefinitionRegistry


    image.png
    public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
    //调用了无参构造函数,要先加载父类的无参构造函数,
       this();
       register(componentClasses);
       refresh();
    }
    
    

    分析这三个重要的方法

    1. 首先调用this()方法 无参构造函数
      首先调用父类的无参构造函数,赋值beanFacroty


      image.png

      AnnotationConfigApplicationContext无参构造函数,赋值了reder和scanner

    public AnnotationConfigApplicationContext() {
       StartupStep createAnnotatedBeanDefReader = this.getApplicationStartup().start("spring.context.annotated-bean-reader.create");
       this.reader = new AnnotatedBeanDefinitionReader(this);
       createAnnotatedBeanDefReader.end();
       this.scanner = new ClassPathBeanDefinitionScanner(this);
    }
    
    

    this.scanner = new ClassPathBeanDefinitionScanner(this);
    实例化了扫面类,但是不是用这个类去扫面要加载的类,那这个类的作用是什么,是我们手动的扫面,看下面的例子
    spring源码中会自动的扫描包下的类,比如标注了@Component @Configuration等注解的类,自动扫描的时候,会重新有从新new了一个ClassPathBeanDefinitionScanner(this);后续的文章会分析,那我们想手动的扫描呢,用的就是这个scanner

    AnnotationConfigApplicationContext configApplicationContext = new AnnotationConfigApplicationContext ();
    //this.scanner = new ClassPathBeanDefinitionScanner(this);的作用手动的扫面bean 并将bean放到BeanDefinition中
    //如果new AnnotationConfigApplicationContext ("springlearn.springlearn"),使用包名,调用的也是scan方法,并且refresh
    //像本例子, new AnnotationConfigApplicationContext ();无参构造函数,手动的调用scan方法,那就需要再手动的调用refresh()方法
    configApplicationContext.scan ("springlearn.springlearn");
    //一定要refresh,初始化bean
    configApplicationContext.refresh ();
    MySpringBean mySpringBean = (MySpringBean)configApplicationContext.getBean ("mySpringBean");
    System.out.println (mySpringBean.getName ());
    configApplicationContext.close ();
    
    

    主要是读取配置类这里就是MyConfiguration.class,要注意的是只是将配置类加载到beanDefinitionMap中,不会去解析,通过refresh()方法解析的 ,并注入了很多的BeanFacrotyPostProcessor
    this.reader = new AnnotatedBeanDefinitionReader(this);

    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);
    // this.registry是AnnotationConfigApplicationContext本身,上面的类图可以看到//AnnotationConfigApplicationContext实现BeanDefinitionRegistry
       AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
    }
    
    

    AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
    最终调用AnnotatedBeanDefinitionReader的有参构造器

    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);
    //重点方法,将重要的BeanFactoryPostProcessor放到BeanDefinitionMap中,此方法有返回值,但是这里并没有使用其返回值
       AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
    }
    
    

    registerAnnotationConfigProcessors方法

    public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
          BeanDefinitionRegistry registry, @Nullable Object source) {
    
       DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
       if (beanFactory != null) {
          if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
             beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
          }
          if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
             beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
          }
       }
    
       Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
    // 将ConfigurationClassPostProcessor放到BeanDefinitionMap中,registry是AnnotationConfigApplicationContext本身, AnnotationConfigApplicationContext继承了
    GenericApplicationContext, 成员变量DefaultListableBeanFactory,就是bean工厂,bean工厂里维护了beanDefinitionMap成员变量. beanDefinitionMap的key为类的全类名,value为对应的BeanDefinition
    下面的if判断就是将很多的BeanFacrotyPostProcessor放到beanDefinitionMap中,再后续的代码会使用到, 其中ConfigurationClassPostProcessor比较重要,后续会分析到
       if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
    //将  BeanFacrotyPostProcessor包装进RootBeanDefinition中
        RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
          def.setSource(source);
          beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
       }
    
       if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
          RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
          def.setSource(source);
          beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
       }
    
       // 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));
       }
    
       // 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));
       }
    
       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));
       }
    
       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;
    }
    
    
    1. register(componentClasses);
      将自己的配置类存放到BeanDefinitionMap中,上面提到过BeanDefinitionMap的key为全类名,value为对应的BeanDefinition ,上面向BeanDefinitionMap存放的是RootBeanDefinition,这回因为是自己的类,所以要自定义BeanDefinition,

    AnnotationConfigApplicationContext构造函数的register(componentClasses);
    -->AnnotatedBeanDefinitionReader#register的this.reader.register(componentClasses);
    -->AnnotatedBeanDefinitionReader#doRegisterBean

    <pre style="background:#2B2B2B">private <T> void doRegisterBean(Class<T> beanClass, @Nullable String name, @Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier, @Nullable BeanDefinitionCustomizer[] customizers) {
    
    //定义的是AnnotatedGenericBeanDefinition
    
     AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
    
     if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) { return; }
    
    //查看作用域常见的单例和多例,还有request session等 就是@Scope这个注解, abd.setInstanceSupplier(supplier); ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd); abd.setScope(scopeMetadata.getScopeName()); String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
    
    //判断注解是否 Primary和Lazy  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)); }
    
     }
    
     } if (customizers != null) { for (BeanDefinitionCustomizer customizer : customizers) {
    
     customizer.customize(abd); } 
    
     }
    
    //如果作用域的proxyMode属性值,判断放入beanDefinitionMap的是proxyDefinition还是adb, proxyDefinition将来解析成bean的时候,不是bean的实现类,而是一个代理bean的类.</pre>
    
    <pre style="background:#2B2B2B">可能是jdk代理也能是cglib代理 BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName); definitionHolder = AnnotationConfigUtils.*applyScopedProxyMode*(scopeMetadata, definitionHolder, this.registry);</pre>
    
    <pre style="background:#2B2B2B">// BeanDefinitionReaderUtils.*registerBeanDefinition*(definitionHolder, this.registry); }</pre>
    
    

    就是最重要的refresh();方法,再后续的文章分析

    相关文章

      网友评论

        本文标题:spring源码分析

        本文链接:https://www.haomeiwen.com/subject/rvtebltx.html