爱看不看之 Spring源码理解

声明:本文主要针对的是已注解来配置的 本人是一个菜鸡有错的请指出来。

spring(AnnotationConfigApplicationContext)spring的启动及bean的实例化等IOC和AOP都是在这个类的构造函数里面实现的。

public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
   this();
   register(annotatedClasses);
   refresh();
}

它会去调用它的无参构造方法和父类的构造方法

主要的内容就是实例化出一个beanfactory、reader、scanner。

public GenericApplicationContext() {
   this.beanFactory = new DefaultListableBeanFactory();
}

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

最主要的是实例化出一个bean工厂,和在调用reader的构造方法中在会生成六个RootBeanDefinition(这里最主要的是把internalConfigurationAnnotationProcessor也放进去了),并把它们放到BeanDefinitionMap。而scanner基本是不会用到的,后面再扫描的时候用并的不是这个scanner

接下来就是

register(annotatedClasses):会把我们传过去的类也生产beanDefinition并放到BeanDefinitionMap里

refresh():是构造函数里面方法的重中之重,里面就包含了扫描,bean的生命周期,工厂属性填充等等

里面有9个方法,其中我们叫几个重要的方法

// Prepare this context for refreshing.
prepareRefresh();

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

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

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

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

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

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

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

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

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

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

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

prepareBeanFactory(beanFactory):这个方法主要是往spring工厂里面填充所需要的属性,以及往BeanPostProcessors里面添加ApplicationListenerDetector和ApplicationContextAwareProcessor后置处理器。

invokeBeanFactoryPostProcessors(beanFactory):这个方法可以说是最重要的方法之一,没有它spring就没法完成bean的生成。它完成了把我们想要交给spring管理的类扫描出来例如加了@Scanner注解@Improt注解等等。并且spring提供了扩展点,让我们可以去修改放到BeanDefinitionMap里的BeanDefinition。(记住我们的bean生产是通过BeanDefinition来实现的,而不是通过类的本身!!!)

List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
String[] postProcessorNames =
      beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
   if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
      currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
      processedBeans.add(ppName);
   }
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();


invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);

首先它会去判断我们是否有手动给它添加一个BeanFactoryPostProcessor后置处理器,有的话就先执行它(一般是没有的),然后再从beanFactory.getBeanNamesForType (BeanDefinitionRegistryPostProcessor.class, true, false)这个方法到BeanDefinitionMap拿出BeanFactoryPostProcessor的后置处理器也就是internalConfigurationAnnotationProcessor。去执行它的processConfigBeanDefinitionMap方法

首先它回去便利map中的BeanDefinition,如果是@Configuration注解就把它的一个属性设置为full,如果不是就设置成lite。这个蛮重要的,因为这涉及到我们会要@Configuration来配置,其实如果你试过不加Configuration注解spring照样可以完成它的配置。

parser.parse(candidates);

这里完成了包的扫描,import的扫描,bean的扫描并把包扫描出来的类生成BeanDefinition放到BeanDefinitionMap中

try {
   if (bd instanceof AnnotatedBeanDefinition) {
      parse(((AnnotatedBeanDefinition) bd).getMetadata(), holder.getBeanName());
   }
   else if (bd instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) bd).hasBeanClass()) {
      parse(((AbstractBeanDefinition) bd).getBeanClass(), holder.getBeanName());
   }
   else {
      parse(bd.getBeanClassName(), holder.getBeanName());
   }

不同类型的类扫描方法都不同

processConfigurationClass方法里调用doProcessConfigurationClass

doProcessConfigurationClass方法中

Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(
      sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);
if (!componentScans.isEmpty() &&
      !this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) {
   for (AnnotationAttributes componentScan : componentScans) {
      // The config class is annotated with @ComponentScan -> perform the scan immediately
      Set<BeanDefinitionHolder> scannedBeanDefinitions =
            this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());
      // Check the set of scanned definitions for any further config classes and parse recursively if needed
      for (BeanDefinitionHolder holder : scannedBeanDefinitions) {
         if (ConfigurationClassUtils.checkConfigurationClassCandidate(
               holder.getBeanDefinition(), this.metadataReaderFactory)) {
            parse(holder.getBeanDefinition().getBeanClassName(), holder.getBeanName());
         }
      }
   }
}

        Set<BeanDefinitionHolder> scannedBeanDefinitions = this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());

这里就是包扫描里得到的BeanDefinition

// Process any @Import annotations
processImports(configClass, sourceClass, getImports(sourceClass), true);

这里就是用来得到import的BeanDefinition,

if (candidate.isAssignable(ImportSelector.class)) {
   // Candidate class is an ImportSelector -> delegate to it to determine imports
   Class<?> candidateClass = candidate.loadClass();
   ImportSelector selector = BeanUtils.instantiateClass(candidateClass, ImportSelector.class);
   ParserStrategyUtils.invokeAwareMethods(
         selector, this.environment, this.resourceLoader, this.registry);
   if (this.deferredImportSelectors != null && selector instanceof DeferredImportSelector) {
      this.deferredImportSelectors.add(
            new DeferredImportSelectorHolder(configClass, (DeferredImportSelector) selector));
   }
   else {
      String[] importClassNames = selector.selectImports(currentSourceClass.getMetadata());
      Collection<SourceClass> importSourceClasses = asSourceClasses(importClassNames);
      processImports(configClass, currentSourceClass, importSourceClasses, false);
   }
}
else if (candidate.isAssignable(ImportBeanDefinitionRegistrar.class)) {
   // Candidate class is an ImportBeanDefinitionRegistrar ->
   // delegate to it to register additional bean definitions
   Class<?> candidateClass = candidate.loadClass();
   ImportBeanDefinitionRegistrar registrar =
         BeanUtils.instantiateClass(candidateClass, ImportBeanDefinitionRegistrar.class);
   ParserStrategyUtils.invokeAwareMethods(
         registrar, this.environment, this.resourceLoader, this.registry);
   configClass.addImportBeanDefinitionRegistrar(registrar, currentSourceClass.getMetadata());
}
else {
   // Candidate class not an ImportSelector or ImportBeanDefinitionRegistrar ->
   // process it as an @Configuration class
   this.importStack.registerImport(
         currentSourceClass.getMetadata(), candidate.getMetadata().getClassName());
   processConfigurationClass(candidate.asConfigClass(configClass));
}

这里会解析improt的三种实现ImportBeanDefinitionRegistrar,ImportSelector和普通类。其中要注意的是spring会认为你improt的类里面有加@Import所以它会去判断,如果是的就再调用processImports方法来解析一边。如果是普通类那么它会去调用processConfigurationClass方法去解析这个类是否有加@SCanner等等再走一边之前的扫描的流程,然后把它放到configurationClasses里面。这也是spring精彩的地方。

回到后置处理器的方法种,要记住improt的类并不在parse方法里面放到BeanDefinitionMap里的。而是再this.reader.loadBeanDefinitions(configClasses)方法中,把我们放到configurationClasses里的类生成BD放到BD容器中。

讲到这invokeBeanDefinitionRegistryPostProcessors方法就讲的差不多了,接下来它往下走就回去调用它后置处理器的方法invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);这里就讲了我们为什么要用@Configuration。enhanceConfigurationClasses方法中会去判断BD的属性是否是full如果是的会就用Cglib来生成代理对象。为什么要用cglib来代理而不用动态代理,是因为再配置@Bean的时候可能会调用该类其他方法。如果使用动态代理来实现的话,就拿下图来说 那么dataSource的构造方法就会被调用两次!!!
在这里插入图片描述

registerBeanPostProcessors(beanFactory)方法里主要是把我们的后置处理器放到beanPostProcessors里面去,在bd里的类被实现化出来后会调用这些后置处理器。

public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
   Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null");
   this.beanPostProcessors.remove(beanPostProcessor);
   this.beanPostProcessors.add(beanPostProcessor);
   if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) {
      this.hasInstantiationAwareBeanPostProcessors = true;
   }
   if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) {
      this.hasDestructionAwareBeanPostProcessors = true;
   }
}

finishBeanFactoryInitialization:这个方法可以算是最重要的方法了,从微观上来讲bean的生命周期就是在这个方法开始和完成的,首先会先把bd都拿出来,并去判断他们是FactoryBean,各自getbean的方法不用,FactoryBean会生成两个bean一个是它本身,另一个是FactoryBean下的getObject下的类

List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

// Trigger initialization of all non-lazy singleton beans...
for (String beanName : beanNames) {
   RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
   if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
      if (isFactoryBean(beanName)) {
         final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);
         boolean isEagerInit;
         if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
            isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>) () ->
                  ((SmartFactoryBean<?>) factory).isEagerInit(),
                  getAccessControlContext());
         }
         else {
            isEagerInit = (factory instanceof SmartFactoryBean &&
                  ((SmartFactoryBean<?>) factory).isEagerInit());
         }
         if (isEagerInit) {
            getBean(beanName);
         }
      }
      else {
         getBean(beanName);
      }
   }
}

getBean里是一个空壳方法,里面会调用doGetBean这里才是我们拿到bean的主要内容。首先它会调用getSingleton方法,

final String beanName = transformedBeanName(name);
Object bean;

// Eagerly check singleton cache for manually registered singletons.
Object sharedInstance = getSingleton(beanName);

这里首先回去singletonObjects里去拿,看看是否有生成bean有的话直接返回。如果为空就走接下来的判断,是否正在创建这里肯定为空的,因为它是在后面创建的时候才放到这个集合SingletonCurrentlyInCreation里面的,这样就返回空出去。

protected Object getSingleton(String beanName, boolean allowEarlyReference) {
   Object singletonObject = this.singletonObjects.get(beanName);
   if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
      synchronized (this.singletonObjects) {
         singletonObject = this.earlySingletonObjects.get(beanName);
         if (singletonObject == null && allowEarlyReference) {
            ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
            if (singletonFactory != null) {
               singletonObject = singletonFactory.getObject();
               this.earlySingletonObjects.put(beanName, singletonObject);
               this.singletonFactories.remove(beanName);
            }
         }
      }
   }
   return singletonObject;
}

往下走又会遇到getSingleton方法,但是这和之前的不是用一个方法。我们bean的创建就是在这个方法里面

if (mbd.isSingleton()) {
   sharedInstance = getSingleton(beanName, () -> {
      try {
         return createBean(beanName, mbd, args);
      }
      catch (BeansException ex) {
         // Explicitly remove instance from singleton cache: It might have been put there
         // eagerly by the creation process, to allow for circular reference resolution.
         // Also remove any beans that received a temporary reference to the bean.
         destroySingleton(beanName);
         throw ex;
      }
   });
   bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}

在beforeSingletonCreation中就是把我们beanname 放到SingletonCurrentlyInCreation集合里面去,然后再调用getObject它会跳转到createBean这个方法,从这个方法拿到bean然后再finally里判断是否为新的,如果是的话就添加到singletonObjects集合里面去。

public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
   Assert.notNull(beanName, "Bean name must not be null");
   synchronized (this.singletonObjects) {
      Object singletonObject = this.singletonObjects.get(beanName);
      if (singletonObject == null) { 
         beforeSingletonCreation(beanName);
         boolean newSingleton = false;
      
         try {
            singletonObject = singletonFactory.getObject();
            newSingleton = true;
         }
         catch (IllegalStateException ex) {      
         }
         finally {
            if (recordSuppressedExceptions) {
               this.suppressedExceptions = null;
            }
            afterSingletonCreation(beanName);
         }
         if (newSingleton) {
            addSingleton(beanName, singletonObject);
         }
      }
      return singletonObject;
   }
}

在调用doCreateBean

try {
   Object beanInstance = doCreateBean(beanName, mbdToUse, args);
   if (logger.isDebugEnabled()) {
      logger.debug("Finished creating instance of bean '" + beanName + "'");
   }
   return beanInstance;
}

首先会创建一个BeanWrapper局部变量,它并不是bean你可以把它看成是从db中实例出来的类但是它还封装了其他信息,通过createBeanInstance方法我们的类就被new出来了

BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
   instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
   instanceWrapper = createBeanInstance(beanName, mbd, args);
}

在createBeanInstance方法中会在determineConstructorsFromBeanPostProcessors方法中拿出构造方法,这里面的逻辑蛮复杂的它有可能因为构造方法过多无法判断用哪个拿不出构造方法。如果ctors不为空就用autowireConstructor来实例化对象,如果为空就用instantiateBean来实例化对象。

Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null ||
      mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
      mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args))  {
   return autowireConstructor(beanName, mbd, ctors, args);
}

// No special handling: simply use no-arg constructor.
return instantiateBean(beanName, mbd);

接着往doCreateBean走它会去判断是否正在创建是否单例等如果是的话会走addSingeletonFactory方法

boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
      isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
   if (logger.isDebugEnabled()) {
      logger.debug("Eagerly caching bean '" + beanName +
            "' to allow for resolving potential circular references");
   }
   addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}

该方法主要是把它放到singletonFactories里面去,这里是解决循环依赖的关键地方。

protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
   Assert.notNull(singletonFactory, "Singleton factory must not be null");
   synchronized (this.singletonObjects) {
      if (!this.singletonObjects.containsKey(beanName)) {
         this.singletonFactories.put(beanName, singletonFactory);
         this.earlySingletonObjects.remove(beanName);
         this.registeredSingletons.add(beanName);
      }
   }
}

接下来就是重中之重的属性填充和使用后置处理器

Object exposedObject = bean;
try {
   populateBean(beanName, mbd, instanceWrapper);
   exposedObject = initializeBean(beanName, exposedObject, mbd);
}

populateBean中会把该类的变量都拿出来并且判断他们是什么方式注入的 一般是默认AUTOWIRE_BY_NO

PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);

if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
      mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
   MutablePropertyValues newPvs = new MutablePropertyValues(pvs);

   // Add property values based on autowire by name if applicable.
   if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
      autowireByName(beanName, mbd, bw, newPvs);
   }

   // Add property values based on autowire by type if applicable.
   if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
      autowireByType(beanName, mbd, bw, newPvs);
   }

   pvs = newPvs;
}

首先它会在filterPropertyDescriptorsForDependencyCheck方法里把类的成员变量的都拿出来。

然后在CommonAnnotationBeanPostProcessor后置处理器的postProcessPropertyValues方法中的inject方法里便利成员变量把属性都注入进去,例如A类依赖B类,那么这里就会调用getbean方法得到bean(B类)完成bean的生命周期。然后才回到A类的postProcessPropertyValues,继续完成A类的声明周期。但是如果B类也依赖了A类那么当它走到postProcessPropertyValues方法时候会在去调用getbean得到bean(A类)。这就形成了循环依赖的问题。

if (hasInstAwareBpps || needsDepCheck) {
   if (pvs == null) {
      pvs = mbd.getPropertyValues();
   }
   PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
   if (hasInstAwareBpps) {
      for (BeanPostProcessor bp : getBeanPostProcessors()) {
         if (bp instanceof InstantiationAwareBeanPostProcessor) {
            InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
            pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
            if (pvs == null) {
               return;
            }
         }
      }
   }

这时候A类的getbean方法去调getSingleton方法,这时this.singletonObjects.get(beanName)肯定是空的因为我们A类的还没有生成Bean,只走到属性注入这一步。接下来 会去earlySingletonObjects中拿,但是我们从上面的操作来看并没有放入到earlySingletonObjects中。这时候就会从singletonFactories里拿,因为我们之前把他放到集合里面拿到了,那么下面的判断就能进去。在这里才把SingletonObject放到earlySingletonObjects里面。这样我们就拿到了A类的bean,然后回到B的属性注入,当B类完成生命周期,这时候又回到A的属性注入中。

  protected Object getSingleton(String beanName, boolean allowEarlyReference) {
  Object singletonObject = this.singletonObjects.get(beanName);
   if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
    synchronized (this.singletonObjects) {
     singletonObject = this.earlySingletonObjects.get(beanName);
     if (singletonObject == null && allowEarlyReference) {
        ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
        if (singletonFactory != null) {
           singletonObject = singletonFactory.getObject();
           this.earlySingletonObjects.put(beanName, singletonObject);
           this.singletonFactories.remove(beanName);
        }
     }
  }
    }
return singletonObject;

}

接下来就是走到执行后置处理器中initializeBean(beanName, exposedObject, mbd);

这个方法首先会拿到beanPostProcessors的后置处理器并调用他们的postProcessBeforeInitialization方法,然后再调用init-method方法,然后再遍历后置处理器调用postProcessAfterInitialization,这里要记住,我们的Aop动态代理就是再AnnotationAwareAspectJAutoProxyCreator后置处理器中postProcessAfterInitialization方法中实在的,这时候才生成了我们所说的bean。它会拿到我们配置好的切点,再代理的前后执行要执行的逻辑!!!

Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
   wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}

try {
   invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
   throw new BeanCreationException(
         (mbd != null ? mbd.getResourceDescription() : null),
         beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
   wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}

return wrappedBean;

到这里bean的生命周期就完成的差不多了,就剩下销毁时执行destroy方法了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值