作者:京东科技 韩国凯

通过本文,读者能够0源码根底的初步学习spring源码,并可能触类旁通从此进入源码世界的大米!
因为是第一次浏览源码,文章之中不免存在一些问题,还望包涵斧正!
文章demo源码:http://xingyun.jd.com/codingR...

一、 @Autowired与@Resource的区别

用一句话总结两者的区别就是: @Autowired会先通过类型注入,即byType,当存在有多个类型时会通过名称注入。@Resource则相同,会先通过名称注入,即byName,当名称不存在或有多个名称时会通过类型注入。

那么通过名称注入与通过类型注入有什么区别呢?

//创立接口interface StuService{    String getName();}@Service//Stu2实现接口并注册beanclass Stu2 implements StuService{    @Override    public String getName() {        return "stu2";    }}@Service//Stu3实现接口并注册beanclass Stu3 implements StuService{    @Override    public String getName() {        return "stu3";    }}

1.1 @Autowired

那么此时如果咱们对 StuService注入, @Autowired能够抉择注入的类型就有两个,别离是 Stu2与 Stu3

须要留神的是,类型有很多种抉择:

  1. 当注册bean与获取bean为同一个类时,类型只有这个类自身。

例如,咱们有获取session的工具类,须要将其注入到spring之中,

@Componentclass SessionUtil{    public String getSession(){        return "session";    }}

只有一个类,间接注册bean,应用时能够任意抉择

@AutowiredSessionUtil sessionUtil;

此时@Autowired只有一个注册类型,间接注入。

  1. 当注册bean有多个时,类型为所有注册的bean,实现形式有:实现接口、继承、通过其余形式,例如xml配置注册bean。

例如上述 StuService有多个实现类,每个实现类都注册了bean,因而@Autowired能够抉择的类型就有两个。

@AutowiredStuService stu;

根据上述的@Autowired逻辑,此时有多个类型,那么会依据bean name查找,(即类名首字母小写的),发现 stu没有对应的实现类,

此时会报错:

Field stu in com.example.demo.spring.Stu1 required a single bean, but 2 were found:

只须要将 stu 替换成 stu2或 stu3即可实现注入。

继承和其余形式同时有多个bean注入时同理。

因而,@Autowired中类型的定义能够归结为:当注册bean有多个时,类型为所有注册的bean,实现形式有:实现接口、继承、通过其余形式,例如xml配置注册bean或者@Bean注册。

1.2 @Resource

  1. 当只有一个bean时,能够间接注册
@AutowiredSessionUtil sessionUtil;
  1. 当有多个bean注册时,如果未指定名称,则bean name为类名首字母小写,指定了bean名称则注册名称为该名称。

例如上文中 Stu1 Stu2都未指定bean名称,因而两者的bean名称别离为 stu1 stu2

当应用@Bean在办法上注册bean,此时名称为办法名称。

@Bean()public Student getStudent(){    Student student = new Student();    student.setName("bob");    student.setId(26);    return student;}

此时该bean名称为 getStudent

同样,咱们也能够注册bean时自定义bean名称

@Bean("stu1")public Student getStudent(){    Student student = new Student();    student.setName("bob");    student.setId(26);    return student;}@Service("stu2")class Stu2 implements StuService{    @Override    public String getName() {        return "stu2";    }}@Component("stu3")class Stu3 implements StuService{    @Override    public String getName() {        return "stu3";    }}

在援用时指定bean:

@Resource(name = "stu2")private StuService stu1;

1.3 @Autowired

当咱们应用@Resource时,会依据名称也就是 stu2去查问,此时bean名称只有一个,查到返回

@Resourceprivate Stu3 stu2;

然而在执行时却发现报错:

Bean named 'stu2' is expected to be of type 'com.example.demo.spring.Stu3' but was actually of type 'com.example.demo.spring.Stu2'

这是因为只依据了bean名称去查问,却没有依据bean类型,查到的是Stu2类型的bean,然而冀望的却是Stu3,因而会产生类型不匹配。

二、SpringIOC的Bean注入流程

spring的注册流程次要蕴含两个局部:

  1. 容器的启动阶段及预热工作
  2. Bean的注入流程

先理解一下几个概念:

2.1 概念介绍

2.1.1 配置元数据

存在于磁盘上的我的项目中用于形容一个bean的数据,能够是xml、properties、yaml等动态文件,也能够是各种注解形容的对应信息,例如@Service、@Component形容的一个bean的信息。

<bean id="role" class="com.wbg.springxmlbean.entity.Role">    <property name="id" value="1"/>    <property name="roleName" value="高级工程师"/>    <property name="note" value="重要人员"/></bean>

以上就是一个由xml定义的配置元数据。

2.1.2 BeanDefinition与BeanDefinitionReader

在spring中,无论是那种配置元数据,最终都会转换为BeanDefinition,由BeanDefinition形容要生成并被援用的对象,能够了解为BeanDefinition就是bean的生成模板,或者是bean的说明书,依照BeanDefinition生成bean。

而将配置元数据转换为BeanDefinition的工作就是由BeanDefinitionReader实现的,对于不同的的配置元数据有不同的Reader实现对应的工作,例如有XmlBeanDefinitionReader读取xml配置信息,PropertiesBeanDefinitionReader读取properties配置信息,AnnotatedBeanDefinitionReader读取注解的配置信息。

BeanDefinitionReader的作用就是将磁盘上的文件信息或注解信息转化为内存中用于形容bean的BeanDefinition。

2.1.3 BeanFactoryPostProcessor

BeanFactoryPostProcessor是容器启动阶段Spring提供的一个扩大点,次要负责对注册到BeanDefinitionRegistry中的一个个的BeanDefinition进行肯定水平上的批改与替换。例如咱们的配置元信息中有些可能会批改的配置信息散落到各处,不够灵便,批改相应配置的时候比拟麻烦,这时咱们能够应用占位符的形式来配置。例如配置Jdbc的DataSource连贯的时候能够这样配置:
<bean id="dataSource"      class="org.apache.commons.dbcp.BasicDataSource"      destroy-method="close">      <property name="maxIdle" value="${jdbc.maxIdle}"></property>      <property name="maxActive" value="${jdbc.maxActive}"></property>      <property name="maxWait" value="${jdbc.maxWait}"></property>      <property name="minIdle" value="${jdbc.minIdle}"></property>        <property name="driverClassName"          value="${jdbc.driverClassName}">      </property>      <property name="url" value="${jdbc.url}"></property>        <property name="username" value="${jdbc.username}"></property>      <property name="password" value="${jdbc.password}"></property>  </bean> 

BeanFactoryPostProcessor就会对注册到BeanDefinitionRegistry中的BeanDefinition做最初的批改,替换$占位符为配置文件中的实在的数据。

2.1.4 BeanDefinitionRegistry

一个存储BeanDefinition的中央,存储形式为KV值,key为beanName,value为BeanDefinition。

2.1.5 容器启动阶段

容器的启动阶段绝对比较简单,首先会将存在于各处的磁盘上的配置元信息由各自的Reader读取到内存之中,转换成BeanDefinition,而后注册到BeanDefinationRegistry之中,最初由BeanFactoryPostProcessor进行批改与替换。

2.1.6 BeanFactory与FactoryBean

BeanFactory与FactoryBean的名字很像,然而的确两个不同的货色。

依据命名规定来看,BeanFactory是一个Factory,也就是一个寄存bean的工厂,在创立bean实现后放到其中,应用是从其中获取。

而FactoryBean则是一个bean,只不过与不同的的bean不同的是他不仅能够创立自身类型的bean,也能够相似于Factory一样创立一层有包装的新的bean。这个Bean能够返回一个新的类型的bean,在返回之前也能够对其进行加工。

@Componentclass FactoryBeanDemo implements FactoryBean<Student>{    @Override    public Student getObject() {        return new Student();    }    @Override    public Class<?> getObjectType() {        return Student.class;    }}

创立一个FactoryBean只须要实现其接口,并实现其中的两个办法。当咱们获取FactoryBean时,会返回其中 getObject()办法返回的对象。而如果想要获取FactoryBean自身,只须要在bean name前加一个"&"符号即可。

@Resource()private Object factoryBeanDemo;@GetMapping("/getStu")private String getBean(){        System.out.println(factoryBeanDemo.getClass());    return stu2.getName();}
//输入后果class com.example.demo.domain.Student

能够看到获取到的是Student类型。

class com.example.demo.spring.FactoryBeanDemo

将获取bean名称假“&”符号:

@Resource(name = "&factoryBeanDemo")private Object factoryBeanDemo;
class com.example.demo.spring.FactoryBeanDemo

能够看到获取到的对象变成了FactoryBeanDemo自身。

2.2 Bean注入流程

在容器启动阶段,曾经实现了bean的注册。如果该对象是配置成懒加载的形式,那么直到咱们向Spring要依赖对象实例之前,其都是以BeanDefinitionRegistry中的一个个的BeanDefinition的模式存在,也就是Spring只有在咱们第一次依赖对象的时候才开启相应对象的实例化阶段。而如果咱们不是抉择懒加载的形式,容器启动阶段实现之后,其中有一个步骤finishBeanFactoryInitialization(),在这一步将立刻启动Bean实例化阶段,通过隐式的调用所有依赖对象的getBean办法来实例化所有配置的Bean,实现类的加载。

doGetBean():获取并返回bean

doGetBean()的次要流程有两个:

  • 尝试从缓存中获取bean,如果获取到间接返回。
  • 如果没有获取到则尝试加载bean。
protected <T> T doGetBean(      String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)      throws BeansException {   String beanName = transformedBeanName(name);   Object beanInstance;   // Eagerly check singleton cache for manually registered singletons.   // 1、查问缓存中是否存在,存在的话间接返回   Object sharedInstance = getSingleton(beanName);   if (sharedInstance != null && args == null) {      if (logger.isTraceEnabled()) {         if (isSingletonCurrentlyInCreation(beanName)) {            logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +                  "' that is not fully initialized yet - a consequence of a circular reference");         }         else {            logger.trace("Returning cached instance of singleton bean '" + beanName + "'");         }      }      // 依据缓存中的bean获取实例,次要是检测如果是FactoryBean类型,则获取其外部的getObject()的bean。(须要先理解FactoryBean的作用)      beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, null);   }   //2、不存在则创立bean   else {      // Fail if we're already creating this bean instance:      // We're assumably within a circular reference.      if (isPrototypeCurrentlyInCreation(beanName)) {         throw new BeanCurrentlyInCreationException(beanName);      }      // Check if bean definition exists in this factory.      // 2.1 尝试从父类的Factory加载bean      BeanFactory parentBeanFactory = getParentBeanFactory();      if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {         // Not found -> check parent.         String nameToLookup = originalBeanName(name);         if (parentBeanFactory instanceof AbstractBeanFactory) {            return ((AbstractBeanFactory) parentBeanFactory).doGetBean(                  nameToLookup, requiredType, args, typeCheckOnly);         }         else if (args != null) {            // Delegation to parent with explicit args.            return (T) parentBeanFactory.getBean(nameToLookup, args);         }         else if (requiredType != null) {            // No args -> delegate to standard getBean method.            return parentBeanFactory.getBean(nameToLookup, requiredType);         }         else {            return (T) parentBeanFactory.getBean(nameToLookup);         }      }      if (!typeCheckOnly) {         markBeanAsCreated(beanName);      }      StartupStep beanCreation = this.applicationStartup.start("spring.beans.instantiate")            .tag("beanName", name);      try {         if (requiredType != null) {            beanCreation.tag("beanType", requiredType::toString);         }         /*         * 2.2 获取RootBeanDefinition:首先会依据beanName获取BeanDefinition,而后将BeanDefinition转换为RootBeanDefinition         * BeanDefinition 接口的实现类有很多,通过不同形式注册到 BeanDefinitionRegistry 中的 BeanDefinition 的类型可能都不太雷同。           最终,在通过 BeanDefinition 来创立 bean 的实例时,通常都会调用 getMergedBeanDefinition 来获取到一个 RootBeanDefinition。           所以,RootBeanDefinition 实质上是 Spring 运行时对立的 BeanDefinition 视图。         * */         RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);         checkMergedBeanDefinition(mbd, beanName, args);         // Guarantee initialization of beans that the current bean depends on.         // 2.3 初始化依赖的bean         String[] dependsOn = mbd.getDependsOn();         if (dependsOn != null) {            for (String dep : dependsOn) {               if (isDependent(beanName, dep)) {                  throw new BeanCreationException(mbd.getResourceDescription(), beanName,                        "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");               }               registerDependentBean(dep, beanName);               try {                  getBean(dep);               }               catch (NoSuchBeanDefinitionException ex) {                  throw new BeanCreationException(mbd.getResourceDescription(), beanName,                        "'" + beanName + "' depends on missing bean '" + dep + "'", ex);               }            }         }         // Create bean instance.         // 2.4 创立实例         if (mbd.isSingleton()) {            sharedInstance = getSingleton(beanName, () -> {               try {                  //返回真正的bean                  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;               }            });            beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);         }   }   return adaptBeanInstance(name, beanInstance, requiredType);}

2.2.1 mbd = getMergedLocalBeanDefinition(beanName)获取BeanDefinition

RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);

BeanDefinition 接口的实现类有很多,通过不同形式注册到 BeanDefinitionRegistry 中的 BeanDefinition 的类型可能都不太雷同。
最终,在通过 BeanDefinition 来创立 bean 的实例时,通常都会调用 getMergedBeanDefinition 来获取到一个 RootBeanDefinition。所以,RootBeanDefinition 实质上是 Spring 运行时对立的 BeanDefinition 视图。

此处就是将各种BeanDefinition对立转换为spring能辨认的RootBeanDefinition。

2.2.2 getSingleton(String beanName, ObjectFactory<?> singletonFactory) 获取创立好的对象

sharedInstance = getSingleton(beanName, () -> {   try {      //返回真正的bean      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;   }});

getSingleton()办法中获取创立好的对象

//获取singletonFactory返回的后果singletonObject = singletonFactory.getObject();

getSingleton()办法中最次要的一次调用也就是从singletonFactory中获取对象,而获取对象的后果就是下面代码中传入的匿名工厂返回的后果,也就是 createBean(beanName, mbd, args)

2.2.3 createBean(beanName, mbd, args) 创立bean

protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)      throws BeanCreationException {   if (logger.isTraceEnabled()) {      logger.trace("Creating instance of bean '" + beanName + "'");   }   RootBeanDefinition mbdToUse = mbd;   // Make sure bean class is actually resolved at this point, and   // clone the bean definition in case of a dynamically resolved Class   // which cannot be stored in the shared merged bean definition.   // 1.解析bean class   Class<?> resolvedClass = resolveBeanClass(mbd, beanName);   if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {      mbdToUse = new RootBeanDefinition(mbd);      mbdToUse.setBeanClass(resolvedClass);   }   // Prepare method overrides.   // 2.筹备笼罩的办法   try {      mbdToUse.prepareMethodOverrides();   }   catch (BeanDefinitionValidationException ex) {      throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),            beanName, "Validation of method overrides failed", ex);   }   try {      // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.      // 3.尝试返回代理创立的Bean,这个作用就是查找bean中所有实现前置和后置处理器的接口,有没有手工创立而后返回的,代替了spring的创立bean的流程      Object bean = resolveBeforeInstantiation(beanName, mbdToUse);      if (bean != null) {         return bean;      }   }   catch (Throwable ex) {      throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,            "BeanPostProcessor before instantiation of bean failed", ex);   }   try {      //4.真正创立bean      Object beanInstance = doCreateBean(beanName, mbdToUse, args);      if (logger.isTraceEnabled()) {         logger.trace("Finished creating instance of bean '" + beanName + "'");      }      return beanInstance;   }   catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {      // A previously detected exception with proper bean creation context already,      // or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.      throw ex;   }   catch (Throwable ex) {      throw new BeanCreationException(            mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);   }}

创立bean次要有以下几步:

  1. 解析bean的class文件,为前面的依据class文件通过反射创建对象做筹备。
  2. 预处理bean的Override属性,预处理的形式也比较简单,就是在办法prepareMethodOverride中判断一下,如果lookup-method标签或者replaced-method标签中配置了bean中须要笼罩的办法,就将MethodOverride中的overload属性值设置为false。
  3. 尝试通过反射获取被代理的bean。
  4. 真正创立bean的过程

2.2.4 Object beanInstance = doCreateBean(beanName, mbdToUse, args) 开始创立bean

以上流程都是获取bean前的流程或获取bean的筹备,doCreateBean是真正的创立并填充bean的流程(去掉了一些不重要的代码)。

protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)      throws BeanCreationException {   // Instantiate the bean.   BeanWrapper instanceWrapper = null;   if (mbd.isSingleton()) {      instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);   }   if (instanceWrapper == null) {      //1.通过反射创立实例化对象,并将其放入wraaper中。wraaper能够了解为bean的包装对象,外面是bean实例的,还有一些其余bean的属性方便使用      instanceWrapper = createBeanInstance(beanName, mbd, args);   }   Object bean = instanceWrapper.getWrappedInstance();   Class<?> beanType = instanceWrapper.getWrappedClass();   if (beanType != NullBean.class) {      mbd.resolvedTargetType = beanType;   }   // Allow post-processors to modify the merged bean definition.   //2.容许后处理处理器批改合并后的bean定义,这里只是解析这些@Autowired @Value @Resource @PostConstruct等这些注解,并没有产生理论属性注入的动作   synchronized (mbd.postProcessingLock) {      if (!mbd.postProcessed) {         try {            applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);         }         mbd.postProcessed = true;      }   }   // Eagerly cache singletons to be able to resolve circular references   // even when triggered by lifecycle interfaces like BeanFactoryAware.   //3.是否须要提前曝光,用来解决循环依赖时应用   boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&         isSingletonCurrentlyInCreation(beanName));   if (earlySingletonExposure) {      if (logger.isTraceEnabled()) {         logger.trace("Eagerly caching bean '" + beanName +               "' to allow for resolving potential circular references");      }      addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));   }   // Initialize the bean instance.   Object exposedObject = bean;   //4.将实例化实现成的bean填充属性   populateBean(beanName, mbd, instanceWrapper);   //5.调用初始化办法,例如 init-method   exposedObject = initializeBean(beanName, exposedObject, mbd);       //6.循环依赖查看   if (earlySingletonExposure) {      Object earlySingletonReference = getSingleton(beanName, false);      if (earlySingletonReference != null) {         if (exposedObject == bean) {            exposedObject = earlySingletonReference;         }         else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {            String[] dependentBeans = getDependentBeans(beanName);            Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);            for (String dependentBean : dependentBeans) {               if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {                  actualDependentBeans.add(dependentBean);               }            }         }      }   }   // Register bean as disposable.   //7.注册bean   try {      registerDisposableBeanIfNecessary(beanName, bean, mbd);   }   catch (BeanDefinitionValidationException ex) {      throw new BeanCreationException(            mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);   }   return exposedObject;}

从上述流程中能够看到,咱们创立一个bean次要有以下几个流程:

  1. 首先通过class依据反射创建对象,此时该对象的所有的属性都为空,能够了解为咱们new出的空属性对象。
  2. 解析@Autowired @Value @Resource @PostConstruct这些注解,但并没有产生属性注入的行为。
  3. 是否须要提前曝光,用来解决循环依赖时应用,次要作用是如果须要代理会返回代理对象,如果不须要代理,返回后面创立的对象
  4. 将第一步实例化实现的空属性对象填充属性,其中如果该bean依赖了其余bean,也会在此步骤将依赖的bean拆卸,如果bean曾经被创立,则间接属性注入,如果不存在,则创立bean,创立形式跟本bean雷同,能够了解为递归。
  5. 将实例化实现的bean对象初始化,次要查看bean是否实现了一些前置或后置或初始化的办法,如果是的话就执行。
  6. 循环依赖查看。
  7. 依据scope注册bean。

能够看到,通过以上的几个步骤,咱们就获取到了一个实例bean。

其中最重要的三个办法:

  1. 实例化bean
  2. 拆卸属性
  3. 初始化bean

2.2.5 总结

总结来说,创立bean的流程就是先依据反射获取对象,而后填充对象的属性,初始化,最初将bean注册。

2.3 创立bean流程深刻了解

上文咱们只粗略的解说了创立bean的过程,并没有深刻的查看源码是如何实现的,例如通过反射获取对象是怎么获取的,填充属性是如何填充的,下文将具体论述2.2.5过程中在源码层面是如何构建的。

2.3.1 instanceWrapper = createBeanInstance(beanName, mbd, args) 获取实例化对象

该办法通过反射获取实例化的空属性对象。

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {   // Make sure bean class is actually resolved at this point.   //1.1解析class   Class<?> beanClass = resolveBeanClass(mbd, beanName);   //1.2确认public权限   if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {      throw new BeanCreationException(mbd.getResourceDescription(), beanName,            "Bean class isn't public, and non-public access not allowed: " + beanClass.getName());   }   //2.如果存在 Supplier 回调,则调用 obtainFromSupplier() 进行初始化,因为反射获取对象的效率比拟低   Supplier<?> instanceSupplier = mbd.getInstanceSupplier();   if (instanceSupplier != null) {      return obtainFromSupplier(instanceSupplier, beanName);   }   if (mbd.getFactoryMethodName() != null) {      return instantiateUsingFactoryMethod(beanName, mbd, args);   }   // Shortcut when re-creating the same bean...   boolean resolved = false;   boolean autowireNecessary = false;   if (args == null) {      synchronized (mbd.constructorArgumentLock) {         /*         * 3.如果args为空且办法曾经被resolved,则会间接抉择对应的构造方法         * mbd.resolvedConstructorOrFactoryMethod的赋值在下方【1】【2】的代码中赋值         * */         if (mbd.resolvedConstructorOrFactoryMethod != null) {            resolved = true;            autowireNecessary = mbd.constructorArgumentsResolved;         }      }   }   if (resolved) {      if (autowireNecessary) {         return autowireConstructor(beanName, mbd, null, null);      }      else {         return instantiateBean(beanName, mbd);      }   }   // Candidate constructors for autowiring?   //4.主动拆卸的构造方法   Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);   if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||         mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {      return autowireConstructor(beanName, mbd, ctors, args);   }   // Preferred constructors for default construction?   //5.是否有首选构造方法   ctors = mbd.getPreferredConstructors();   if (ctors != null) {      return autowireConstructor(beanName, mbd, ctors, null);   }   // No special handling: simply use no-arg constructor.   //6.通过默认的无参构造函数   return instantiateBean(beanName, mbd);}
  1. 首先解析class文件与确认public权限。
  2. 如果存在 Supplier 回调,则调用 obtainFromSupplier() 进行初始化,因为反射获取对象的效率比拟低。
  3. 如果args为空且应用那个构造函数曾经被确定了,则进行标记,后续间接抉择应用那种构造方法。
  4. 如果args不为空或没有被解析过,则抉择应用那种构造方法来结构实例化的对象:

Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);

Constructor<?>[] ctors = bp.determineCandidateConstructors(beanClass, beanName);

抉择AutowiredAnnotationBeanPostProcessor实现类:

其中重要的代码已贴出:

//1.遍历所有的构造方法for (Constructor<?> candidate : rawCandidates) {   if (!candidate.isSynthetic()) {      nonSyntheticConstructors++;   }   else if (primaryConstructor != null) {      continue;   }   //2.查看以后构造方法是否有@Autowired注解   MergedAnnotation<?> ann = findAutowiredAnnotation(candidate);   if (ann == null) {      Class<?> userClass = ClassUtils.getUserClass(beanClass);      if (userClass != beanClass) {         try {            Constructor<?> superCtor =                  userClass.getDeclaredConstructor(candidate.getParameterTypes());            ann = findAutowiredAnnotation(superCtor);         }         catch (NoSuchMethodException ex) {            // Simply proceed, no equivalent superclass constructor found...         }      }   }   //3.如果有@Autowired注解   if (ann != null) {      //4.如果曾经有一个@Autowired注解,则阐明存在多个@Autowired注解,则抛出异样      if (requiredConstructor != null) {         throw new BeanCreationException(beanName,               "Invalid autowire-marked constructor: " + candidate +               ". Found constructor with 'required' Autowired annotation already: " +               requiredConstructor);      }      boolean required = determineRequiredStatus(ann);      if (required) {         if (!candidates.isEmpty()) {            throw new BeanCreationException(beanName,                  "Invalid autowire-marked constructors: " + candidates +                  ". Found constructor with 'required' Autowired annotation: " +                  candidate);         }         requiredConstructor = candidate;      }      candidates.add(candidate);   }   //5无参构造函数   else if (candidate.getParameterCount() == 0) {      //将其设置为默认构造函数      defaultConstructor = candidate;   }}//对下面的处理过程进行判断//6.1先查看是否有@Autowired注解if (!candidates.isEmpty()) {   // Add default constructor to list of optional constructors, as fallback.   if (requiredConstructor == null) {      if (defaultConstructor != null) {         candidates.add(defaultConstructor);      }      else if (candidates.size() == 1 && logger.isInfoEnabled()) {         logger.info("Inconsistent constructor declaration on bean with name '" + beanName +               "': single autowire-marked constructor flagged as optional - " +               "this constructor is effectively required since there is no " +               "default constructor to fall back to: " + candidates.get(0));      }   }  //返回@Autowired注解的构造方法   candidateConstructors = candidates.toArray(new Constructor<?>[0]);}//6.2如果只有一个有参构造函数,则返回该有参函数else if (rawCandidates.length == 1 && rawCandidates[0].getParameterCount() > 0) {   candidateConstructors = new Constructor<?>[] {rawCandidates[0]};}//6.3对于非Kotlin类只会返回null,所以这里不会进入else if (nonSyntheticConstructors == 2 && primaryConstructor != null &&      defaultConstructor != null && !primaryConstructor.equals(defaultConstructor)) {   candidateConstructors = new Constructor<?>[] {primaryConstructor, defaultConstructor};}else if (nonSyntheticConstructors == 1 && primaryConstructor != null) {   candidateConstructors = new Constructor<?>[] {primaryConstructor};}else {   //6.4对于不能辨认的场景会进入到这里,例如有多个构造函数然而并没有指定@Autowired注解或者没有构造函数(java会帮咱们生成一个无参的构造函数),返回null   candidateConstructors = new Constructor<?>[0];}

2-5步会对所有的构造函数进行查看,并在查看完进行标记,并会在第6步对标记的后果进行返回,依照ifelse判断程序次要分为以下几种状况:

  • 如果有@Autowired注解的办法则返回该构造方法
  • 如果只有一个有参构造函数则会返回该有参构造函数
  • 对于不能辨认的场景会进入到这里,例如有多个构造函数然而并没有指定@Autowired注解或者没有构造函数(java会帮咱们生成一个无参的构造函数)会返回null

在获取到须要的构造函数后,会进行标记,下次不必再次解析能够间接选用那个构造函数,即上文的第4步

  1. 是否有首选的构造函数
  2. 如果都没有的话,通过默认的无参构造函数创建对象。

咱们查看代码发现,无论第4步返回什么后果,最终会执行以下两个办法:

autowireConstructor()与instantiateBean()

两者都会调用

instantiate()办法

最终都会执行以下这个办法

BeanUtils.instantiateClass(constructorToUse)

也就是如下的代码

for (int i = 0 ; i < args.length; i++) {   if (args[i] == null) {      Class<?> parameterType = parameterTypes[i];      argsWithDefaultValues[i] = (parameterType.isPrimitive() ? DEFAULT_TYPE_VALUES.get(parameterType) : null);   }   else {      argsWithDefaultValues[i] = args[i];   }}return ctor.newInstance(argsWithDefaultValues);

其中最重要的一句:

return ctor.newInstance(argsWithDefaultValues);

能够发现,也就是这里通过反射的形式创立了一个空属性对象,并一层层返回,直到前面的属性拆卸等过程,能够说这里就是bean加载过程的源头。

2.3.2 applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName) 解析各种注解

该办法次要解析该bean所相干的注解,例如属性有@Resource,bean中@PostConstruct注解都会被解析。

for (MergedBeanDefinitionPostProcessor processor : getBeanPostProcessorCache().mergedDefinition) {   processor.postProcessMergedBeanDefinition(mbd, beanType, beanName);}

processor次要有两个实现类:

  1. AutowiredAnnotationBeanPostProcessor 解决@Autowired和@Value注解bean定义信息
  2. CommonAnnotationBeanPostProcessor 解决@Resource、@PostConstruct、@PreDestroy注解的bean定义信息

这里须要留神的是,该办法只是会解析并不会真正的进行注入,因为学习意义不大,并不在赘述。

2.3.3 populateBean(beanName, mbd, instanceWrapper) 对实例化实现的bean进行属性注入

//遍历所有的属性for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {   //对属性进行装填   PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);   if (pvsToUse == null) {      if (filteredPds == null) {         filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);      }      pvsToUse = bp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);      if (pvsToUse == null) {         return;      }   }   pvs = pvsToUse;}

其中 bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName)有几个实现办法,比拟重要的是:

  1. AutowiredAnnotationBeanPostProcessor,次要拆卸属性是@Autowired与@Value的属性
  2. CommonAnnotationBeanPostProcessor,次要拆卸属性是@Resource的属性

两者最终都会进入如下办法:

//判断要注入的是属性还是办法if (this.isField) {   Field field = (Field) this.member;   ReflectionUtils.makeAccessible(field);   //如果是属性的话则间接注入   field.set(target, getResourceToInject(target, requestingBeanName));}else {   if (checkPropertySkipping(pvs)) {      return;   }   try {      Method method = (Method) this.member;      ReflectionUtils.makeAccessible(method);      //否则通过反射注入      method.invoke(target, getResourceToInject(target, requestingBeanName));   }   catch (InvocationTargetException ex) {      throw ex.getTargetException();   }}

了解起来比较简单,判断是办法注入还是属性注入,在注入时注入的对象为:

getResourceToInject(target, requestingBeanName)

找到ResourceElement的实现办法中getResource()办法:

返回了 autowireResource(this.resourceFactory, element, requestingBeanName)

if (factory instanceof AutowireCapableBeanFactory) {   AutowireCapableBeanFactory beanFactory = (AutowireCapableBeanFactory) factory;   DependencyDescriptor descriptor = element.getDependencyDescriptor();   if (this.fallbackToDefaultTypeMatch && element.isDefaultName && !factory.containsBean(name)) {      autowiredBeanNames = new LinkedHashSet<>();      resource = beanFactory.resolveDependency(descriptor, requestingBeanName, autowiredBeanNames, null);      if (resource == null) {         throw new NoSuchBeanDefinitionException(element.getLookupType(), "No resolvable resource object");      }   }   else {      resource = beanFactory.resolveBeanByName(name, descriptor);      autowiredBeanNames = Collections.singleton(name);   }}else {   resource = factory.getBean(name, element.lookupType);   autowiredBeanNames = Collections.singleton(name);}

在这个办法中,无论是if还是else,最终都会调用

getBean(name, element.lookupType)

也就是咱们bean注入的入口,这个过程很像递归,在咱们创立bean时,如果发现咱们有依赖的其余bean,那么就会去创立依赖的bean,如果依赖的bean还有其依赖的属性则又会去创立被依赖的属性,只到最终全副创立实现,返回一开始想要创立的bean。

2.3.4 exposedObject = initializeBean(beanName, exposedObject, mbd)初始化bean

在该办法中,会对曾经填充过属性的bean进行初始化:

Object wrappedBean = bean;if (mbd == null || !mbd.isSynthetic()) {   //对bean的前置解决,其中@PostConstruct就在此步骤中   wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);}try {   //调用初始化办法如果bean实现了InitializingBean接口,则先执行InitializingBean接口的afterPropertiesSet办法,而后执行xml或注解设置的init-method办法。   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()) {   //对bean进行后置解决,对象的代理产生在此步骤中   wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);}

在初始化bean的时候,次要分为三个局部,别离是applyBeanPostProcessorsBeforeInitialization、invokeInitMethods、applyBeanPostProcessorsAfterInitialization,别离对应于初始化的前置解决、自定义init办法、后置解决。

applyBeanPostProcessorsBeforeInitialization、applyBeanPostProcessorsAfterInitialization两个办法的大略逻辑就是获取获取所有实现其接口的类,而后执行其中被笼罩的办法。

罕用的注解执行程序如下:

  1. @PostConstruct注解润饰的办法
  2. InitializingBean接口的afterPropertiesSet()办法
  3. init-method指定的办法
  4. @PreDestroy注解润饰的办法
  5. DisposableBean接口的destroy()办法
  6. destory-method指定的办法

并且在代码中能够看到,前置解决与后置解决都能够扭转bean。

在容器启动阶段咱们讲到BeanFactoryPostProcessor,这里咱们讲到BeanPostProcessor,那么BeanFactoryPostProcessor 和 BeanPostProcessor 有什么区别呢?

BeanFactoryPostProcessor存在于容器启动阶段,而BeanPostProcessor存在于对象实例化阶段,BeanFactoryPostProcessor关注对象被创立之前那些配置的批改,而BeanPostProcessor阶段关注对象曾经被创立之后的性能加强,替换等操作,这样就很容易辨别了。
BeanPostProcessor与BeanFactoryPostProcessor都是Spring在Bean生产过程中强有力的扩大点。Spring中驰名的AOP(面向切面编程),其实就是依赖BeanPostProcessor对Bean对象性能加强的。

BeanFactoryPostProcessor次要用于解决实例化之前,对实例的属性进行拓展,而BeanPostProcessor是在实例化之后对对象做的拓展。

2.4 总结

用简略的话形容一下,创立一个bean的过程大略包含三局部:

  1. 通过反射实例化bean
  2. 属性拆卸以及填充
  3. 初始化,包含init-method、以及其前后三个步骤。其中AOP加强就是产生在初始化之后的applyBeanPostProcessorsAfterInitialization的步骤中。

通过以上的步骤,就能够取得咱们能够失常应用的一个bean。