Spring容器启动(上)

导读:本篇文章讲解 Spring容器启动(上),希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

在Bean的生命周期中,尤其是在初始化的过程中,会用到大量的BeanProcessor实现类的方法,对Bean实例进行一系列的操作,其中包括查找注入点、依赖注入、AOP等等,而这其中用到的BeanProcessor实现类的实例正是在Spring容器启动的过程中创建的,在启动的过程中不仅会创建BeanProcessor的实例,也会设置BeanFactory的类加载器、SpringEL表达式解析器、类型转化注册器,扫描类文件生成BeanDefinition以及初始化事件监听器,同时非懒加载单例Bean的实例化过程也是在Spring启动的过程中创建的

下面将简单介绍Spring启动过程中,都具体做了哪些工作?以AnnotationConfigApplicationContext容器为例

一、构造创建

通过AnnotationConfigApplicationContext并指定配置文件来创建Spring容器,而在有参构造方法内部,首先会去调用无参的构造方法,完成基本的初始化

AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
@ComponentScan("com.lizhi")
@EnableAsync
public class AppConfig {

   @Bean
   public UserService userService(){
      return new UserService();
   }
}
public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
   // 构造DefaultListableBeanFactory、AnnotatedBeanDefinitionReader、ClassPathBeanDefinitionScanner
   this();
   register(componentClasses);
   refresh();
}

1.1 构造DefaultListableBeanFactory实例

AnnotationConfigApplicationContext继承自GenericApplicationContext,所以会去调用GenericApplicationContext的无参构造方法,而在该无参构造方法中,会实例化一个DefaultListableBeanFactory对象作为beanFactory的实例

// 构造DefaultListableBeanFactory、AnnotatedBeanDefinitionReader、ClassPathBeanDefinitionScanner
public AnnotationConfigApplicationContext() {
   StartupStep createAnnotatedBeanDefReader = this.getApplicationStartup().start("spring.context.annotated-bean-reader.create");
   // 额外会创建StandardEnvironment
   this.reader = new AnnotatedBeanDefinitionReader(this);
   createAnnotatedBeanDefReader.end();
   this.scanner = new ClassPathBeanDefinitionScanner(this);
}
public GenericApplicationContext() {
   this.beanFactory = new DefaultListableBeanFactory();
}

在DefaultListableBeanFactory的无参构造方法中,会调用父类AbstractAutowireCapableBeanFactory的无参构造方法,在该方法中会设置依赖注入时需要忽略的接口的方法,对于BeanNameAware这些回调接口,都提供了回调的set方法,如果某个实例实现了这些接口,同时又是通过ByType或ByName来进行属性注入的,那么在进行属性注入时,如果没有ignoreDependencyInterface缓存,这些set方法也会被用作解析依赖注入,但当这些接口被加入到ignoreDependencyInterface中,依赖注入时就可以跳过这些方法

同时设置实例化的策略,一般都是Cglib策略

public AbstractAutowireCapableBeanFactory() {
   super();
   ignoreDependencyInterface(BeanNameAware.class);
   ignoreDependencyInterface(BeanFactoryAware.class);
   ignoreDependencyInterface(BeanClassLoaderAware.class);
   if (NativeDetector.inNativeImage()) {
      this.instantiationStrategy = new SimpleInstantiationStrategy();
   }
   else {
      this.instantiationStrategy = new CglibSubclassingInstantiationStrategy();
   }
}

1.2 构造AnnotatedBeanDefinitionReader实例

AnnotatedBeanDefinitionReader实例中主要包含了BeanDefinitionRegistry(注册BeanDefinition)、beanNameGenerator(beanName生成器)以及ConditionEvaluator(解析@Conditional注解)

// 额外会创建StandardEnvironment
this.reader = new AnnotatedBeanDefinitionReader(this);

在调用AnnotatedBeanDefinitionReader的双参构造方法时,会去获取或创建Environment的缓存

public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
   this(registry, getOrCreateEnvironment(registry));
}
  • 缓存环境变量

    如果ApplicationContext实现了EnvironmentCapable接口,则调用getEnvironment()方法得到Environment实例对象,否则生成一个StandardEnvironment实例对象

    如果EnvironmentCapable是第一次来Environment获取,那么会去调用createEnvironment()方法,也是实例化一个StandardEnvironment对象

    private static Environment getOrCreateEnvironment(BeanDefinitionRegistry registry) {
       Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
       if (registry instanceof EnvironmentCapable) {
          return ((EnvironmentCapable) registry).getEnvironment();
       }
       return new StandardEnvironment();
    }
    

    StandardEnvironment实例化的时候,会去调用它父类AbstractEnvironment的无参构造方法

    在AbstractEnvironment的单参构造方法中,会去获取操作系统的环境变量和程序的环境变量

    public AbstractEnvironment() {
       this(new MutablePropertySources());
    }
    
    protected AbstractEnvironment(MutablePropertySources propertySources) {
       this.propertySources = propertySources;
       this.propertyResolver = createPropertyResolver(propertySources);
       //获取并缓存操作系统的环境变量以及程序运行的环境变量
       customizePropertySources(propertySources);
    }
    
  • 注册核心BeanDefinition

    AnnotatedBeanDefinitionReader的单参构造方法中调用了如下的构造方法,而在这个构造方法中,创建了用来解析@Conditional注解的的ConditionEvaluator实例对象,同时注册各种配置处理器的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;
       // 用来解析@Conditional注解的
       this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
       // 注册
       AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
    }
    

    设置当前beanFactory的依赖比较器(依赖注入时会用到),设置候选Bean的解析器(用于判断某个Bean能不能用于依赖注入)

    同时生成ConfigurationClassPostProcessor、AutowiredAnnotationBeanPostProcessor、CommonAnnotationBeanPostProcessor、PersistenceAnnotationBeanPostProcessor、EventListenerMethodProcessor以及DefaultEventListenerFactory的BeanDefinition

    public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
          BeanDefinitionRegistry registry, @Nullable Object source) {
    
       DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
       if (beanFactory != null) {
    
          // 设置beanFactory的OrderComparator为AnnotationAwareOrderComparator
          // 它是一个Comparator,是一个比较器,可以用来进行排序,比如new ArrayList<>().sort(Comparator);
          if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
             beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
          }
          // 用来判断某个Bean能不能用来进行依赖注入
          if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
             beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
          }
       }
    
       Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
    
       // 注册ConfigurationClassPostProcessor类型的BeanDefinition
       if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
          RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
          def.setSource(source);
          beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
       }
    
       // 注册AutowiredAnnotationBeanPostProcessor类型的BeanDefinition
       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));
       }
    
       // 注册CommonAnnotationBeanPostProcessor类型的BeanDefinition
       // 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));
       }
    
       // 注册PersistenceAnnotationBeanPostProcessor类型的BeanDefinition
       // 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));
       }
    
       // 注册EventListenerMethodProcessor类型的BeanDefinition,用来处理@EventListener注解的
       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));
       }
    
       // 注册DefaultEventListenerFactory类型的BeanDefinition,用来处理@EventListener注解的
       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.3 构造ClassPathBeanDefinitionScanner实例

在创建扫描器的时候,会调用它的多参构造方法

this.scanner = new ClassPathBeanDefinitionScanner(this);

Spring在启动的过程中,会使用默认的includeFilter,所以会通过registerDefaultFilters()来设置默认的includeFilter

public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters,
      Environment environment, @Nullable ResourceLoader resourceLoader) {

   Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
   this.registry = registry;

   if (useDefaultFilters) {
      registerDefaultFilters();
   }
   setEnvironment(environment);
   setResourceLoader(resourceLoader);
}

includeFilters存放的是包含注解类型,也就是说一个Class类上的注解类型,在includeFilters中有,才会去把类解析成一个BeanDefinition,除了Spring提供的Component类型注解,还支持JDK自带的ManagedBean和Named注解

protected void registerDefaultFilters() {

   // 注册@Component对应的AnnotationTypeFilter
   this.includeFilters.add(new AnnotationTypeFilter(Component.class));

   ClassLoader cl = ClassPathScanningCandidateComponentProvider.class.getClassLoader();

   try {
      this.includeFilters.add(new AnnotationTypeFilter(
            ((Class<? extends Annotation>) ClassUtils.forName("javax.annotation.ManagedBean", cl)), false));
      logger.trace("JSR-250 'javax.annotation.ManagedBean' found and supported for component scanning");
   }
   catch (ClassNotFoundException ex) {
      // JSR-250 1.1 API (as included in Java EE 6) not available - simply skip.
   }

   try {
      this.includeFilters.add(new AnnotationTypeFilter(
            ((Class<? extends Annotation>) ClassUtils.forName("javax.inject.Named", cl)), false));
      logger.trace("JSR-330 'javax.inject.Named' annotation found and supported for component scanning");
   }
   catch (ClassNotFoundException ex) {
      // JSR-330 API not available - simply skip.
   }
}

二、注册配置类

完成构造方法的一些初始化工作之后,会将传入的配置类进行注册

会去调用BeanDefinitionReader的doRegisterBean()完成配置类的注册,解析配置类上的注解,生成一个BeanDefinition

private <T> void doRegisterBean(Class<T> beanClass, @Nullable String name,
                                @Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier,
                                @Nullable BeanDefinitionCustomizer[] customizers) {

    AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
    if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
        return;
    }

    abd.setInstanceSupplier(supplier);
    // 解析@Scope注解的结果为ScopeMetadata
    ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
    abd.setScope(scopeMetadata.getScopeName());
    String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));

    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);
        }
    }

    BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
    definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
    BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/112156.html

(0)
Java光头强的头像Java光头强

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!