先看看普通的实例化过程

spring framework的源码有必要看吗_spring

Spring bean的实例化简图

spring framework的源码有必要看吗_spring_02


可以看出spring的实例化是非常复杂的,接下来就去简单描述一下这个过程

Spring容器

  1. Spring IOC容器就是一个org.springframework.context.ApplicationContext的实例化对象
  2. 容器负责了实例化,配置以及装配一个bean

从代码层次来看:Spring容器就是一个实现了ApplicationContext接口的对象,
从功能上来看: Spring 容器是 Spring 框架的核心,是用来管理对象的。容器将创建对象,把它们连接在一起,配置它们,并管理他们的整个生命周期从创建到销毁。

如何实例化一个Bean?

官网介绍

spring framework的源码有必要看吗_spring_03

  1. 构造方法
  2. 通过静态工厂方法
  3. 通过实例工厂方法

这里记录一下源码分析过程吧*

首先这是AnnotationConfigApplicationContext的UML图

spring framework的源码有必要看吗_java_04


涉及到几个比较关键的类:GenericApplicationContext,AbstractApplicationContext,DefaultResourceLoader ,先放着

  1. 第一步当然是构造函数,AnnotationConfigApplication的初始化必然会先初始化父类
public AnnotationConfigApplicationContext(Class... annotatedClasses) {
        this();
        this.register(annotatedClasses);
        this.refresh();
    }

2.点击this();这个午餐构造方法进去,发现创建了 AnnotationBeanDefinitionReader
和 ClasspathBeanDefinitionScanner 这两个类各自去创建bean生成的环境。

public AnnotationConfigApplicationContext() {
        this.reader = new AnnotatedBeanDefinitionReader(this);
        this.scanner = new ClassPathBeanDefinitionScanner(this);
    }

3.进入 register方法 ,这里面主要是初始化Ban的各种注解

@SuppressWarnings("unchecked")
public void registerBean(Class<?> annotatedClass, String name, Class<? extends Annotation>... qualifiers) {
   AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);
   if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {//跳过处理
      return;
   }

   ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);//获取@scope注解
   abd.setScope(scopeMetadata.getScopeName());
   String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));//取得bean名字
   AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);//处理Lazy primary等注解,仅仅是设置属性。
   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));
         }
      }
   }

   BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
   definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);//进入
   BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}
static BeanDefinitionHolder applyScopedProxyMode(
      ScopeMetadata metadata, BeanDefinitionHolder definition, BeanDefinitionRegistry registry) {

   ScopedProxyMode scopedProxyMode = metadata.getScopedProxyMode();
   if (scopedProxyMode.equals(ScopedProxyMode.NO)) {//不需要代理直接返回
      return definition;
   }
   boolean proxyTargetClass = scopedProxyMode.equals(ScopedProxyMode.TARGET_CLASS);//默认是cglib的方式代理
   return ScopedProxyCreator.createScopedProxy(definition, registry, proxyTargetClass);
}

所以,register方法主要作用就是把bean上的注解扫描一遍。想是别名,懒加载,代理模式,scope等,将其注册到beanDefinitionRegistry(这个registry其实就是AnnotationConfigApplicationContext)中。

4. 很重要refresh();方法,这是AbstractApplicationContext种定义的方法。所有的AbstractApplicationContext容器的子类初始化都会经过这条路。

@Override
public void refresh() throws BeansException, IllegalStateException {
   synchronized (this.startupShutdownMonitor) {
      // 1.Prepare this context for refreshing.
      prepareRefresh();

      // 2.Tell the subclass to refresh the internal bean factory.
      ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

      // 3.Prepare the bean factory for use in this context.
      prepareBeanFactory(beanFactory);

      try {
         //4. Allows post-processing of the bean factory in context subclasses.
         postProcessBeanFactory(beanFactory);

         // 5.Invoke factory processors registered as beans in the context.
         invokeBeanFactoryPostProcessors(beanFactory);

         // 6.Register bean processors that intercept bean creation.
         registerBeanPostProcessors(beanFactory);

         // 7.Initialize message source for this context.
         initMessageSource();

         // 8.Initialize event multicaster for this context.
         initApplicationEventMulticaster();

         // 9.Initialize other special beans in specific context subclasses.
         onRefresh();

         // 10.Check for listener beans and register them.
         registerListeners();

         // 11.Instantiate all remaining (non-lazy-init) singletons.
         finishBeanFactoryInitialization(beanFactory);

         // 12.Last step: publish corresponding event.
         finishRefresh();
      }

      catch (BeansException ex) {
         if (logger.isWarnEnabled()) {
            logger.warn("Exception encountered during context initialization - " +
                  "cancelling refresh attempt: " + ex);
         }

         // Destroy already created singletons to avoid dangling resources.
         destroyBeans();

         // Reset 'active' flag.
         cancelRefresh(ex);

         // Propagate exception to caller.
         throw ex;
      }

      finally {
         // Reset common introspection caches in Spring's core, since we
         // might not ever need metadata for singleton beans anymore...
         //13.
      resetCommonCaches();
      }
   }
}

注意这个方法是加锁的,一共13个方法,分别来看下 每一步都干了什么。

// 1.Prepare this context for refreshing.
prepareRefresh();
顾名思义,是准备工作,这个和前面初始化的准备工作不同。这个是进行参数配置的。placeholder解析和校验工作,但是主要针对web项目的。暂时先不看。

// 2.Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
得到beanfactory

// 3.Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
下面展示一些 内联代码片

/**
 * Configure the factory's standard context characteristics,
 * such as the context's ClassLoader and post-processors.
 * @param beanFactory the BeanFactory to configure
 */
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
   // Tell the internal bean factory to use the context's class loader etc.
  首先,设置了类加载器
   beanFactory.setBeanClassLoader(getClassLoader());

  添加对spel的支持,
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
  添加一个默认的properties的处理工具
   beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

   // Configure the bean factory with context callbacks.
  //设置需要忽略的类,这些类实现了如下的接口需要在bean创建的阶段在beanFactory的容器级别对自动装配进行忽略,而交由context容器进行callback注入。
   beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
   beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
   beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
   beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
   beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
   beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
   beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);

   // BeanFactory interface not registered as resolvable type in a plain factory.
   // MessageSource registered (and found for autowiring) as a bean.
  设置扩展点,对于这些扩展点接口的实现bean需要走特殊的callback流程,特殊装备规则。
   beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
   beanFactory.registerResolvableDependency(ResourceLoader.class, this);
   beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
   beanFactory.registerResolvableDependency(ApplicationContext.class, this);

   // Register early post-processor for detecting inner beans as ApplicationListeners.
   beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

   // Detect a LoadTimeWeaver and prepare for weaving, if found.
   if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
      beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
      // Set a temporary ClassLoader for type matching.
      beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
   }

   // Register default environment beans.
注册特殊的基础bean 如 environment systemEnvironment,systemProperties

   if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
      beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
   }
   if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
      beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
   }
   if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
      beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
   }
}

//4. Allows post-processing of the bean factory in context subclasses. 给web项目使用,通常不会与自定义产生交集。
postProcessBeanFactory(beanFactory);

/* 5 … 扩展点开始,调用BeanFactoryPostProcessors接口的 postProcessBeanFactory 方法。这里有些细节,会有处理的优先级。
首先处理 BeanDefinitionRegistryPostProcessor 中带有PriorityOrdered ,Ordered 这些接口的实现,
然后处理 实现了BeanDefinitionRegistryPostProcessor接口不带order的类。
再然后处理 实现了 BeanFactoryPostProcessor 中带有PriorityOrdered ,Ordered 这些接口的实现。
最后处理 实现了 BeanFactoryPostProcessor 但没有order 接口的实现类。

这里也会进入 beanFactory获取Bean的关键方法 doGetBean();方法位于AbstractBeanFactory中。
getbean的实现比较简单,检查依赖 getDependsOn ,检查是否有循环依赖,有依赖的话先load依赖,AbstractAutowireCapableFactory 的 createBean();方法进行bean的创建。
最后是在SimpleInstantiationStrategy 调用 Beanutils.instantiateClass()通过调用无参构造函数newinstance();创建得到bean实例。如果是单例会被缓存一份。

//6.invokeBeanFactoryPostProcessors

主要是通过BeanDefinitionRegistry把实例对象的属性设置好放在map集合里面

spring framework的源码有必要看吗_java_05