Spring 源码解析(一)

Spring 源码解析

  • 第一章为源码解析。
  • 第二章为实现一个简单的 IOC 容器。
  • 第三章进阶 Spring 插件开发。

概念

Spring 源码的核心组件:java

  • IOC 容器负责实例化,定位,配置应用程序中的对象及创建这些对象间的依赖。
  • AOP 面向切面编程,经过预编译方式和运行期间动态代理实现功能的统一维护的一种技术。

IOC 容器能够理解为一个 Map,key 就是咱们日常使用 Spring 框架时写的 Bean Id,value 就是对应类的实例化对象。spring

几个重要的类

在开始分析源码以前,咱们先试着了解几个概念,这几个类对于咱们理解源码有着很大的帮助,方便对整个 Spring 源码进行分析。编程

  1. ApplicationContext,BeanFactory 提到 Spring 就一直说容器,这个容器咱们上面也给出了一个直观的解释,能够理解为一个 Map,用来存储实例化的的对象,须要的时候就从容器里面取就能够了。那么在代码中的具体实现是什么那?缓存

    你们最为熟悉的实现可能就是 ApplicationContext,它就是一个容器,而它实现了 BeanFactory 接口,能够说 BeanFactory 就是最基础的容器,ApplicationContext 至关于在 BeanFactory 接口增长了一些功能,它们均可以称为容器。app

    先来看看 BeanFactory 的代码:框架

    public interface BeanFactory {
     String FACTORY_BEAN_PREFIX = "&";
    
     Object getBean(String var1) throws BeansException;
    
     <T> T getBean(String var1, @Nullable Class<T> var2) throws BeansException;
    
     Object getBean(String var1, Object... var2) throws BeansException;
    
     <T> T getBean(Class<T> var1) throws BeansException;
    
     <T> T getBean(Class<T> var1, Object... var2) throws BeansException;
    
     boolean containsBean(String var1);
    
     boolean isSingleton(String var1) throws NoSuchBeanDefinitionException;
    
     boolean isPrototype(String var1) throws NoSuchBeanDefinitionException;
    
     boolean isTypeMatch(String var1, ResolvableType var2) throws NoSuchBeanDefinitionException;
    
     boolean isTypeMatch(String var1, @Nullable Class<?> var2) throws NoSuchBeanDefinitionException;
    
     @Nullable
     Class<?> getType(String var1) throws NoSuchBeanDefinitionException;
    
     String[] getAliases(String var1);
        
    }
    复制代码

    整个接口定义的抽象方法其实很是简单和直接,主要就是各类个样的 getBean 方法和一些判断是不是单例或者原型的方法。异步

    再来看 ApplicationContext。ide

    public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory, MessageSource, ApplicationEventPublisher, ResourcePatternResolver {
     @Nullable
     String getId();
    
     String getApplicationName();
    
     String getDisplayName();
    
     long getStartupDate();
    
     @Nullable
     ApplicationContext getParent();
    
     AutowireCapableBeanFactory getAutowireCapableBeanFactory() throws IllegalStateException;
    }
    复制代码

    不只仅实现了 BeanFactory 接口,并且实现了事件派发器,资源解析器以及环境参数相关的接口,比 BeanFactory 多了许多功能。函数

    下面来看看经常使用的容器,也就是上面接口的实现类。源码分析

    • AnnotationConfigApplicationContext 基于 @Configuration 注解配置类解析的容器。
    • ClassPathXmlApplicationContext 基于类路径下 xml 文件配置解析的容器,若是用 xml 方式配置 Spring 框架,这个容器必定使用的很是多。
    • FileSystemXmlApplicationContext 基于文件系统里的 xml 文件配置解析的容器。
    • GenericApplicationContext 不太经常使用的 ApplicationContext,比上面两个更加灵活,能够读取任意配置方式的 Bean。
  2. BeanDefinition BeanDefinition 按照字面意思理解就是 Bean 的定义信息,咱们从接口的定义来看看这个类到底保存了什么信息。

    public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {
     String SCOPE_SINGLETON = "singleton";
     String SCOPE_PROTOTYPE = "prototype";
     int ROLE_APPLICATION = 0;
     int ROLE_SUPPORT = 1;
     int ROLE_INFRASTRUCTURE = 2;
    
     void setParentName(@Nullable String var1);
    
     @Nullable
     String getParentName();
    
     void setBeanClassName(@Nullable String var1);
    
     @Nullable
     String getBeanClassName();
    
     void setScope(@Nullable String var1);
    
     @Nullable
     String getScope();
    
     void setLazyInit(boolean var1);
    
     boolean isLazyInit();
    
     void setDependsOn(@Nullable String... var1);
    
     @Nullable
     String[] getDependsOn();
    
     void setAutowireCandidate(boolean var1);
    
     boolean isAutowireCandidate();
    
     void setPrimary(boolean var1);
    
     boolean isPrimary();
    
     void setFactoryBeanName(@Nullable String var1);
    
     @Nullable
     String getFactoryBeanName();
    
     void setFactoryMethodName(@Nullable String var1);
    
     @Nullable
     String getFactoryMethodName();
    
     ConstructorArgumentValues getConstructorArgumentValues();
    
     default boolean hasConstructorArgumentValues() {
         return !this.getConstructorArgumentValues().isEmpty();
     }
    
     MutablePropertyValues getPropertyValues();
    
     default boolean hasPropertyValues() {
         return !this.getPropertyValues().isEmpty();
     }
    
     boolean isSingleton();
    
     boolean isPrototype();
    
     boolean isAbstract();
    
     int getRole();
    
     @Nullable
     String getDescription();
    
     @Nullable
     String getResourceDescription();
    
     @Nullable
     BeanDefinition getOriginatingBeanDefinition();
    }
    
    复制代码

    从代码里看,BeanDefintion 里面保存了 Bean 的 Class 类名称,做用域【单例或者原型】,构造函数的参数,属性等等,这些信息也说明这个类是 Spring 用来构建 Bean 的主要的类。

    这个接口的主要实现类有 RootBeanDefinition,ChildBeanDefinition,GenericBeanDefinition等等。其中 RootBeanDefinition 最为经常使用,至关于 xml 文件中的 标签,在 xml 中能够配置 parent 属性,这里的父就是 RootBeanDefinition,子就是 ChildBeanDefinition。

  3. BeanDefinitionRegistry 既然有了材料 BeanDefinition,下面必定须要一个操做它的类,BeanDefinitionRegistry 就是一个用来帮咱们操做 BeanDefinition 的接口,它的里面有许多操做 BeanDefinition 的方法,包括经过 BeanDefinition 注册 Bean 等等。

    public interface BeanDefinitionRegistry extends AliasRegistry {
     void registerBeanDefinition(String var1, BeanDefinition var2) throws BeanDefinitionStoreException;
    
     void removeBeanDefinition(String var1) throws NoSuchBeanDefinitionException;
    
     BeanDefinition getBeanDefinition(String var1) throws NoSuchBeanDefinitionException;
    
     boolean containsBeanDefinition(String var1);
    
     String[] getBeanDefinitionNames();
    
     int getBeanDefinitionCount();
    
     boolean isBeanNameInUse(String var1);
    }
    复制代码

    咱们能够经过 registerBeanDefinition 方法将一个 Bean 注册到容器中。调用 BeanDefinitionRegistry.registerBeanDefinition 手工进行注册。

    BeanDefinitionRegistry registry = context.getRegistry();
    boolean definition = registry.containsBeanDefinition("person");
    复制代码
  4. BeanPostProcessor BeanPostProcessor,bean 的后置处理器,在 bean 初始化先后进行一些处理工做。postProcessBeforeInitialization:在初始化以前 工做。postPorcessAfterInitialization:在初始化以后工做。

    public interface BeanPostProcessor {
     @Nullable
     default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
         return bean;
     }
    
     @Nullable
     default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
         return bean;
     }
    }
    复制代码

    由此衍生出来的后置处理器很是多,处理时机也不同,咱们会在后面的源码分析对这些后置处理器的实现原理和操做时机进行一个总结。 Spring 底层对 BeanPostProcessor 的使用:bean 赋值,注入其余组件,@Autowired,声明周期注解功能,@Async等等。

  5. ApplicationContextAware 自定义组件想要使用 Spring 容器底层的一些组件(ApplicationContext,BeanFactory,xxx)等等,须要自定义组件实现 xxxAware 接口。在建立对象的时候,会调用接口规定的方法注入相关组件。ApplicationContextAware 会将 IOC 容器传入到组件中,BeanNameAware 会讲当前实例在 IOC 容器中 Bean 的名字传入到实例中。这些 Aware 会有对应的 AwareProcessor 来进行逻辑处理。

    public interface ApplicationContextAware extends Aware {
     void setApplicationContext(ApplicationContext var1) throws BeansException;
    }
    复制代码

    若是想往组件中注入容器能够实现 ApplicationContextAware 接口,而后经过 setApplicationContext 保存起来。 咱们对 Spring 功能进行扩展时经常哟昂到这些 Aware。

  6. ApplicationListener 与 ApplicationEventMulticaster 这两个组件是 Spring 事件驱动模型用到的组件,ApplicationListener:事件监听。ApplicationEventMulticaster:事件派发。

Bean 的生命周期

Bean 的声明周期指的是 Bean 的建立-->初始化-->销毁的过程,Spring 把这个过程所有交给容器来管理。咱们能够自定义初始化和销毁方法,容器在 Bean 进行到当前生命周期的时候来调用咱们自定一的初始化和销毁方法。

构造(对象建立) 单实例:在容器启动的时候建立对象。 多实例:在每次获取的时候建立对象,调用 getBean 方法时。

初始化 对象建立完成,并赋值好,调用初始化方法

销毁 单实例:容器关闭的时候。 多实例:容器会建立 Bean, 但不会管理 Bean,容器不会调用销毁方法。

Bean 的生命周期要比上面写的更加复杂,咱们在分析完源码后会对这部分进行一个总结。

几个重要的注解

@Import,快速给容器中导入一个组件,@Import(Color.class) 至关于一个无参构造函数。id 默认是全类名。

@Conditional 知足必定条件才给容器中注册bean,这个能够用来让两个bean造成依赖,能够用在方法上,也能够用在类上。这个注解在 SpringBoot 用的很是多。

最后说说 @Autowired 和 @Resource 的区别: @Autowired 自动注入默认按照 type 注入,即按照 .class 查找。若是找到多个相同类型的组件,在将属性的名称做为组件的 id 去容器中查找。使用 @Qualifier("bookDao") 与 @Autowired 组合能够明确指定须要装配的 Bean,经过 id。 @Autowired(require=false) 有就装配,没有就变为 null。

Spring 还支持 JSR250 和 JSR330 里的 @Resource 和 @Inject 注解。Java 规范的注解。@Resource 和 @Autowired 同样实现自动装配,默认按照属性名称进行自动装配。不支持 @Primary,也不支持 @Autowired(require=false)。 @Inject 须要额外导入包,功能和 @Autowired 同样,不支持 require=false; @Autowired 能够标注在构造器、参数、方法、属性上。

提出问题

有了一些概念后,咱们内心必定会有一些问题,同时带着问题去看源码也有助于咱们更加快速地切入到 Spring 得核心,不墨迹,直给。

  1. 容器时怎么建立得,建立时都要作哪些工做。
  2. Spring 为何要用 BeanDefintion 去构造 Bean。
  3. Spring 用 BeanDefintion 去构建 Bean 得流程是什么?
  4. Spring AOP 在 Spring 框架得基础上作了什么?

下面咱们带着问题去看看源码。

容器建立和初始化过程

仍是从下面这段代码开始

AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContext(Config.class);
复制代码

new 容器的过程到底执行了什么操做那?前两步是预处理和配置类的解析工做,咱们直接看 refresh 方法,这个方法就是容器的建立和刷新以及 Bean 初始化的核心方法。

public AnnotationConfigApplicationContext(Class... annotatedClasses) {
  this();
  this.register(annotatedClasses);
  this.refresh();
}
复制代码

refresh() 核心方法:

public void refresh() throws BeansException, IllegalStateException {
  synchronized(this.startupShutdownMonitor) {
    this.prepareRefresh();
    ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
    this.prepareBeanFactory(beanFactory);

    try {
      this.postProcessBeanFactory(beanFactory);
      this.invokeBeanFactoryPostProcessors(beanFactory);
      this.registerBeanPostProcessors(beanFactory);
      this.initMessageSource();
      this.initApplicationEventMulticaster();
      this.onRefresh();
      this.registerListeners();
      this.finishBeanFactoryInitialization(beanFactory);
      this.finishRefresh();
    } catch (BeansException var9) {
      if (this.logger.isWarnEnabled()) {
        this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
      }

      this.destroyBeans();
      this.cancelRefresh(var9);
      throw var9;
    } finally {
      this.resetCommonCaches();
    }

  }
}
复制代码
  1. prepareRefresh() 刷新前的预处理
  • initPropertySources,字面上理解就是初始化一些属性,可是方法体是空的,留给子类去实现。子类能够自定义个性化属性设置方法。
  • getEnvironment().validateRequiredProperties(),属性校验。
  • earlyApplicationEvents,用来保存容器中的一些早期的事件。等事件派发器初始化好了以后再把它们派发出去。
  1. obtainFreshBeanFactory() 获取 Bean 工厂。
  • refreshBeanFactory(),刷新【建立】 BeanFactory。

    在 GenericApplicationContext 里无参构造器建立一个 BeanFactory 对象。

    this.beanFactory = new DefaultListableBeanFactory();
    复制代码

    设置一个 Id。

  • getBeanFactory(),返回刚才 GenericApplicationContext 建立的 BeanFactory 对象。刚建立,里面都是默认的配置。

  • 将建立的 BeanFactory【DefaultListableBeanFactory】返回。

  1. prepareBeanFactory(),BeanFactory 的预准备工做,BeanFactory 进行一些设置。
  • 设置 BeanFactory 的类加载器、支持表达式解析器。。。

  • 添加 部分的BeanPostProcessor【ApplicationContextAwareProcessor】

  • 设置忽略自动装配的接口,EnvironmentAware、EmbeddedValueResolverAware。。。

  • 注册能够解析的自动装配,咱们能够在任何组件中自动注入,ResourceLoader,BeanFactory,ApplicationContext。

  • 添加 BeanPostProcessor【ApplicationListenerDetector】。

  • 添加编译时的 AspectJ。

  • 给 BeanFactory 中注册一些能用的组件。

    environment

    systemProperties

    systemEnvironment

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
  beanFactory.setBeanClassLoader(this.getClassLoader());
  beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
  beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, this.getEnvironment()));
  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.registerResolvableDependency(BeanFactory.class, beanFactory);
  beanFactory.registerResolvableDependency(ResourceLoader.class, this);
  beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
  beanFactory.registerResolvableDependency(ApplicationContext.class, this);
  beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
  if (beanFactory.containsBean("loadTimeWeaver")) {
    beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
    beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
  }

  if (!beanFactory.containsLocalBean("environment")) {
    beanFactory.registerSingleton("environment", this.getEnvironment());
  }

  if (!beanFactory.containsLocalBean("systemProperties")) {
    beanFactory.registerSingleton("systemProperties", this.getEnvironment().getSystemProperties());
  }

  if (!beanFactory.containsLocalBean("systemEnvironment")) {
    beanFactory.registerSingleton("systemEnvironment", this.getEnvironment().getSystemEnvironment());
  }

}
复制代码
  1. postProcessBeanFactory,BeanFactory 准备工做完成后进行的后置处理工做,子类经过重写这个方法来在 BeanFactory 建立并预备完成之后作进一步的设置。

=============================以上是 BeanFactory 建立及准备================================

  1. invokeBeanFactoryPostProcessors(beanFactory),执行 BeanFactoryPostProcessor。

BeanFactoryProcessor:BeanFactory 的后置处理器,在 BeanFactory 标准初始化执行的 Processor,标准初始化就是以上四部。

两个主要接口,BeanFactoryPostProcessor、BeanDefinitionRegistryPostProcessor(能够用这个来注册一些新的组件 )。

执行 BeanPostProcessor 的方法:

先执行 BeanDefintionRegistryPostProcessor

  • 获取全部的 BeanDefinitionRegistryPostProcessor。

  • 对于实现了 PriorityOrdered 优先级接口的 BeanDefinitionRegistryPostProcessor

    postProcessor.postProcessBeanDefinitionRegistry(registry)

  • 对于实现了 Ordered 顺序接口的 BeanDefinitionRegistryPostProcessor

    postProcessor.postProcessBeanDefinitionRegistry(registry)

  • 最后执行没有实现任何优先级或者是顺序接口的 BeanDefinitionRegistryPostProcessor

    postProcessor.postProcessBeanDefinitionRegistry(registry)

在执行 BeanFactoryPostProcessor 的方法

  • 流程和 BeanDefinitionRegistryPostProcessor 如出一辙。
  1. registerBeanPostProcessors,注册 BeanPostProcessor,Bean 的后置处理器【拦截 Bean 的建立过程】。

不一样接口类型的 BeanPostProcessor,在 Bean 建立先后的执行时机是不同的。

BeanPostProcessor

DestructionAwareBeanPostProcessor

InstantiationAwareBeanPostProcessor

SmartInstantiationAwareBeanPostProcessor

MergedBeanDefinitionPostProcessor【internalPostProcessors】

  • 获取全部的 BeanPostProcessor,后置处理器都默承认以有 PriorityOrdered,Ordered 来指定优先级。

  • 先注册 PriorityOrdered 优先级接口的 BeanPostProcessor,把每个 BeanPostProcessor 添加到 BeanFactory 中。

    beanFactory.addBeanPostProcessor(postProcessor)
    复制代码
  • 再注册 Ordered 接口的。

  • 最后注册没有实现任何优先级接口的。

  • 最终注册,MergedBeanDefinitionPostProcessor。

  • 注册一个 ApplicationListenerDetector,来在 Bean 建立完成后检查是不是 ApplicationListener,若是是

    applicationContext.addApplicationListener((ApplicationListener<?>) bean);
    复制代码
  1. initMessageSource,初始化 MessageSource 组件,作国际化消息,消息绑定,消息解析。
  • 获取 BeanFactory。

  • 判断容器有没有 id 为 messageSource 的,类型是 MessageSource 的组件

    若是有赋值给 messageSource 属性,若是没有本身建立一个 DelegatingMessageSource。

    MessageSource 取出国际化配置文件中的某个 key 值,能按照区域信息获取。

  • 把建立好的 MessageSource 注册到容器中,之后获取国际化配置文件的值的时候,能够自动注入 MessageSource,调用 getMessage 方法就能够获取到了。

    beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource)
    复制代码
  1. initApplicationEventMulticaster,初始化事件派发器。
  • 获取 BeanFactory。
  • 从 BeanFactory 中获取 ID 为 applicationEventMulticaster,类型为 ApplicationEventMulticaster 的派发器。
  • 若是上一步没有配置事件派发器,就建立一个 SimpleApplicationEventMulticaster,为咱们派发事件。
  • 将建立的 ApplicationEventMulticaster 添加到 BeanFactory 中,之后其余组件自动注入便可。
  1. onRefresh,留给子容器(子类),重写 onRefresh 方法,在容器刷新时能够再自定义逻辑。

  2. registerListeners,给容器中把项目里的 ApplicationListener 注册进来。

  • 从容器中拿到全部的 ApplicationListener 组件,将每一个监听器添加到事件派发器中。

    getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName)
    复制代码
  • 派发以前步骤产生的事件,派发器没初始化以前的。

  1. finishBeanFactoryInitialization,初始化全部剩下的单实例 Bean。
//初始化全部剩下的单实例 bean。
beanFactory.preInstantiateSingletons();
复制代码
  • 获取容器中的全部 BeanDefinitions,依次进行初始化和建立对象。

  • 若是 Bean 不是抽象的,是单实例,不是懒加载的,就开始建立单例 Bean。

    判断是不是 FactoryBean,便是否实现了 FactoryBean 接口的 Bean,若是是就用工厂方法建立对象。

    若是不是工厂 Bean,利用 getBean(beanName) 建立对象。

    • getBean(beanName),就是本身写测试类的那个 getBean。

    • 调用 doGetBean(name,null,null,false)。

    • 先获取缓存中保存的单实例 Bean,若是能获取到说明这个 Bean 以前被建立过了(全部建立过的单实例 Bean 都会被缓存起来)。

      //保存单实例 Bean 的
      private final Map<String,Object> singletonObjects = new ConcurrentHashMap<String,Object>(256);
      复制代码
    • 缓存中获取不到,开始 Bean 的建立对象流程。

    • 标记当前 Bean 已经被建立。

    • 获取 Bean 的定义信息。

    • 获取当前 Bean 所依赖的其余 Bean,若是有就按照 getBean() 把依赖的 Bean 先建立出来。

    • 启动单实例 Bean 的建立流程。

      createBean(beanName,mbd,args);
      
      //让 BeanPostProcessor 拦截返回对象。正常的 BeanPostProcessor 是对象建立完成初始化以前执行的,而这个 BeanPostProcessor 要在 Bean 建立以前执行
      
      //InstantiationAwareBeanPostProcessor 提早执行
      //触发 postProcessBeforeInstantiation 方法
      //若是上一步有返回值,在触发 postProcessAfterInitialization 方法
      Object bean = resolveBeforeInstantiation(beanName,mbdToUse);
      复制代码

      若是 InstantiationAwareBeanPostProcessor 没有返回代理对象,调用下面的方法建立 Bean。

      Object beanInstance = doCreateBean(beanName,mbcToUse,args);
      
      //建立 Bean 实例,利用工厂方法或者对象的构造器建立出 Bean 实例。
      createBeanInstance(beanName,mbd,args);
      
      // 建立实例对象后,执行后置处理器
      // 利用 MergedBeanDefintionPostProcessor 
      applyMergedBeanDefintionPostProcessor(mbd,beanType,beanName);
      bdp.postProcessMergedBeanDefinition(mbd,beanType,beanName);
      复制代码

      对 Bean 的属性进行赋值

      populateBean(beanName,mbd,instanceWrapper);
      
      //赋值以前拿到 InstantiationAwareBeanPostProcessor 后置处理器
      //执行 postProcessAfterInstantiation
      
      //再拿 InstantiationAwareBeanPostProcessor 后置处理器
      //执行 postProcessPropertyValues 方法
      
      //最后一步,应用 Bean 属性的值,利用 setter 方法等用反射赋值。
      applyPropertyValues(beanName,mbd,bw,pvs);
      复制代码

      对 Bean 进行初始化

      initializeBean(beanName,exposedObject,mbd);
      
      //执行 Aware 接口的方法
      //判断是不是 BeanNameAware,BeanClassLoaderAware,BeanFactoryAware,利用 invoke 回调接口的方法。
      invokeAwareMethods(beanName,bean);
      
      //执行全部后置处理器初始化以前的方法
      applyBeanPostProcessorsBeforeInitialization(wrapperBean)
      //执行后置处理器的回调方法
      BeanPostProcessor.postProcessBeforeInitialization()
        
      //执行初始化方法
      invokeInitMethods(beanName,wrappedBean,mbd);
      //是不是 InitializingBean 接口实现类,执行接口规定的初始化。
      //是否自定义初始化方法。
      
      //执行初始化以后后置处理器的方法
      applyBeanPostProcessorsAfterInitialization(wrapperBean)
      //执行后置处理器的回调方法
      BeanPostProcessor.postProcessAfterInitialization()
      复制代码

      注册 Bean 的销毁方法。不执行方法,在容器销毁时执行。

    • ·将建立的 Bean 添加到缓存 singletonObjects 中。IOC 容器就能够理解为这些 Map,这些 Map 里面保存了不少单实例 Bean,环境信息。

  • 检查全部 Bean 是否实现了 SmartInitializingSingleton 接口,若是是,就执行回调方法。

  1. finishRefresh 完成 BeanFactory 初始化建立工做,IOC 容器建立完成。
  • 初始化和声明周期有关的后置处理器

    initLifecycleProcessor();
    
    //先从容器中找,找不到 new 一个 Default 的,而且注册在 BeanFactory 中,能够注入到组件中。
    //容许写 LifecycleProcessor, 能够在 BeanFactory 刷新完成或者关闭时调用一些方法。
    void onRefresh();
    void onClose();
    复制代码
  • 拿到前面定义的生命周期处理器,回调 onRefresh 方法。

  • 发布容器刷新完成事件。

    publishEvent(new ContextRefreshedEvent(this));
    复制代码

总结:

Spring 建立 Bean 的时机:

  1. 用到这个 Bean 的时候,利用 getBean 建立 bean 后保存到容器中。
  2. 同一建立全部剩下的 bean 的时候,finishBeanFactoryInitialization();

后置处理器:

每个 Bean 建立完成后,都会使用各类后置处理器进行处理,来加强 Bean 的功能。

  1. AutowiredAnnotationBeanPostProcessor:来处理自动注入。
  2. AnnotationAwareAspectJAutoProxyCreator:来作 AOP 功能。
  3. AsyncAnnotationBeanPostProcessor:加强功能注解。

AOP原理

总体启动流程:

  • 传入配置类,建立 IOC 容器。

  • 注册配置类,调用 refresh() 刷新容器。

  • registerBeanPostProcessors(beanFacotry),注册 Bean 的后置处理器方便拦截 Bean 的建立。

    • 获取 IOC 容器中已经定义了的须要建立对象的全部 BeanPostProcessor,配置类里注册的。

    • 给容器中加其余的 PostProcessor。

    • 优先注册了实现了 PriorityOrdered 接口的 BeanPostProcessor。

    • 再给容器中注册实现了 Ordered 接口的 BeanPostProcessor。

    • 最后注册没实现优先级接口的 BeanPostProcessor。

    • 注册 BeanPostProcessor,实际上就是建立 BeanPostProcessor 的对象并保存在容器中。

    • 建立 internalAutoProxyCreator 的 BeanPostProcessor[AnnotationAwareAspectJAutoProxyCreator]

      • 建立 Bean 的实例
      • populateBean:给 Bean 的属性赋值
      • initializeBean:初始化 Bean
        • invokeAwareMethods():处理 Aware 接口的方法回调。
        • applyBeanPostProcessorsBeforeInitialization():应用后置处理器的 postProcessBeforeInitialization 方法。
        • invokeInitMethods():执行自定义初始化方法。
        • applyBeanPostProcessorsAfterInitialization():执行后置处理器的 PostProcessAfterInitialization 方法。
      • BeanPostProcessor(AnnotationAwareAspectJAutoProxyCreator) 建立成功。调用 initBeanFactory 生成 aspectJAdvisorsBuilder。
    • 把 BeanPostProcessor 注册到 BeanFactory 中:

      beanFactory.addBeanPostProcessor(postProcessor)。

    ==========以上是建立和注册 AnnotationAwareAspectJAutoProxyCreator 的过程=========

    AnnotationAwareAspectJAutoProxyCreator 这个 BeanPostProcessor 作了什么?

    看给容器中注册了什么组件,这个组件何时工做,有什么功能?

    AnnotationAwareAspectJAutoProxyCreator => InstantiationAwareBeanPostProcessor

  • finishBeanFactoryInitialization(beanFactoty),完成 BeanFactory 的初始化工做,建立剩下的单实例 Bean。

    • 遍历获取容器中全部的 Bean,依次建立对象 getBean(beanName)。

    getBean->doGetBean()->getSingleton()

    • 建立 Bean

      【AnnotationAwareAspectJAutoProxyCreator 在全部 Bean 建立以前会有一个拦截,由于实现了InstantiationAwareBeanPostProcessor,会调用 postProcessBeforeInstantiation 方法】

      • 先从缓存中获取当前 Bean,若是能获取到,说明 Bean 是以前被建立过的,直接使用,不然再建立。只要建立好的 Bean 都会被缓存起来。

      • createBean(),建立 Bean。AnnotationAwareAspectJAutoProxyCreator 会在任何 Bean 建立以前尝试返回 Bean 的实例。

        【BeanPostProcessor 是在 Bean 对象建立完成初始化先后调用的】

        【InstantiationAwareBeanPostProcessor 是在建立 Bean 实例以前尝试用后置处理器返回对象的】

        • resolveBeforeInstantiation(beanName,mbdToUse),解析 BeforeInstantiation。但愿后置处理器在此能返回一个代理对象。若是能返回代理对象就使用,若是不能就继续。

        • resolveBeforeInstantiation 方法里,后置处理器先尝试返回对象。

          bean = applyBeanPostProcessorsBeforeInstantiation,拿到全部后置处理器,若是是 InstantiationAwareBeanPostProcessor,就执行后置处理的 postProcessBeforeInstaniation 方法。

          if(bean != null){

          ​ bean = applyBeanPostProcessorsAfterInitialization

          }

        • doCreateBean(beanName,mbdToUse,args),真正的去建立一个 Bean 实例。

第一步

从 @EnableAspectJAutoProxy 开始分析。首先关注 @Import,将 AspectJAutoProxyRegistrar,给容器中导入 AspectJAutoProxyRegistrar。AspectJAutoProxyRegistrar 又实现了 ImportBeanDefinitionRegistrar 接口,这个接口能够自定义注册 Bean。

@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy{}
复制代码

AnnotationMetadata:当前类的注解信息。

BeanDefinitionRegistry:BeanDefinition注册类。

//ImportBeanDefinitionRegistrar
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata,BeanDefinitionRegistry registry){
    //根据class指定BeanDefintion信息
		RootBeanDefinition beanDefinition = new RootBeanDefinition(A.class);
		//注册一个 Bean,指定 bean 名称
		registry.registerBeanDefintion("rainBow",beanDefinition)
}
复制代码

@EnableAspectJAutoProxy 利用 AspectJAutoProxyRegistrar 自定义给容器中注册 Bean。那么它为 AOP 注册了什么 Bean 那?

能够在 AspectJAutoProxyRegistrar 的 registerBeanDefinitions 函数里寻找答案:

//AspectJAutoProxyRegistrar
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
//想容器中注册了一个名为 internalAutoProxyCreator,class 为 AnnotationAwareAspectJAutoProxyCreator 的 Bean。BeanDefinitionRegistry.registerBeanDefinition
        AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
  
//拿到注解相关的信息 
        AnnotationAttributes enableAspectJAutoProxy = AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
//根据拿到的注解的信息判断 proxyTargetClass 和 exposeProxy 属性
        if (enableAspectJAutoProxy != null) {
            if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
                AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
            }

            if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
                AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
            }
        }

    }
复制代码

第一步总结:利用 AspectJAutoProxyRegistrar 给容器中注册了一个 AnnotationAwareAspectJAutoProxyCreator 类型的 Bean。

第二步

既然住了一个 AnnotationAwareAspectJAutoProxyCreator,那么这个组件有什么做用那?字面理解这个 Bean 是注解模式切面自动代理建立器。

先来看这个组件的继承关系:

AnnotationAwareAspectJAutoProxyCreator

​ ->AspectJAwareAdvisorAutoProxyCreator

​ ->AbstractAdvisorAutoProxyCreator

​ ->AbstractAutoProxyCreator

​ implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware

最源头实现了一个 Bean 后置处理器的接口和一个 BeanFactory 的接口。后置处理器在 Bean 初始化完成先后作事情,自动装配 BeanFactory 到实例中。首先看看这两个接口对应的 set 方法在哪里实现的。

AbstractAutoProxyCreator.setBeanFactory()

AbstractAutoProxyCreator.后置处理器相关的逻辑

AspectJAwareAdvisorAutoProxyCreator.setBeanFactory()->initBeanFactory()

AnnotationAwareAspectJAutoProxyCreator.initBeanFactory(),父类调用 setBeanFactory 的时候会调用 initBeanFactory 方法,这个方法又被子类重写了,最后还会调用子类的 initBeanFactory 方法。

AspectJAwareAdvisorAutoProxyCreator【InstantiationAwareBeanPostProcessor】的做用:

  • 每一个 Bean 建立以前,调用 postProcessBeforeInstantiation 方法。

    关心咱们加入切面的 Bean

    • 判断当前 Bean 是否在 advisedBeans 中(保存了全部须要加强的 Bean)。
    • 判断当前 Bean 是不是基础类型,Advice、Pointcut、Advisor、AopInfrastructureBean,或者是不是切面( @Aspect 注解)
    • 判断是否须要跳过,获取候选的加强器(切面里的通知方法),每个封装的通知方法的加强器是 InstantiationModelAwarePointcutAdvisor,判断每个加强器是不是 AspectJPointcutAdvisor 类型。
  • 建立对象。

  • Bean 建立以后,调用 postProcessAfterInitialization 方法。

    return wrapIfNecessary(bean, beanName,cacheKey); //包装若是须要的状况下

    • 获取当前 Bean 的全部加强器(通知方法)。找到能在当前 Bean 使用的加强器(哪些通知方法是要切入当前 Bean 方法的)。而后给加强器排序。

    • 保存当前 Bean 到 advisedBean,表示当前 Bean 已经被加强了。

    • 建立当前 Bean 的代理对象,经过 proxyFactory 建立代理对象。须要传入加强器。经过 proxyFactory 会建立两种动态代理。

      JdkDynamicAopProxy(config); jdk 动态代理。实现了接口就用jdk。

      ObjenesisCglibAopProxy(config); cglib 的动态代理。

    wrapIfNecessary 执行结束,给容器中返回当前组件使用 cglib 加强了的代理对象。之后容器中获取到的就是这个组件的代理对象,执行目标方法的时候,代理对象就会执行通知方法的流程。

  • 目标方法执行。

    容器中保存了组件的代理对象(jdk 或 cglib 加强后的),这个兑现管理保存了详细信息,好比加强器,目标对象。

    • CglibAopProxy.intercept() 方法,拦截目标方法执行。

    • 根据 ProxyFactory 获取对象将要执行的目标方法链接器链 chain。

      List chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);

      List interceptorList 保存全部拦截器,一个默认的 ExposeInvocationInterceptor 和 自定义的加强器

      遍历全部的加强器,将其转为 Interceptor,registry.getIntercepotr(advisor)

      若是是 MethodInterceptor,直接加入集合,若是不是,使用 AdvisorAdapter 将其加强转为 MethodInterceptor。

    • 若是没有拦截器链,直接执行目标方法。

      拦截器链:每个通知方法又被包装为方法拦截器,利用 MethodInterceptor 机制来执行方法。

    • 若是有拦截器链,把须要执行的目标对象,目标方法,链接器链等信息传入建立一个 CglibMethodInvocation 对象,并调用 procceed 方法,返回 retVal。

    • 拦截器链的触发过程

      若是没有拦截器执行目标方法,最后一个拦截器也执行目标方法。

    • 链式获取每个拦截器,拦截器执行 invoke 方法,每个链接器等待下一个拦截器执行完成返回之后再执行,拦截器链的机制,保证通知方法与目标方法的执行顺序。

    • 总结:

      • 使用 @EnableAspectJAutoProxy 开启 AOP 功能。

      • @EnableAspectJAutoProxy 会给容器中注册一个组件 AnnotationAwareAspectJAutoProxyCreator。

      • AnnotationAwareAspectJAutoProxyCreator 是一个后置处理器。

      • 容器的建立过程:

        • registerBeanPostProcessors() 注册后置处理器: 建立 AnnotationAwareAspectJAutoProxyCreator 对象。

        • finishBeanFactoryInitialization() 初始化剩下的单实例 Bean。

          • 建立业务逻辑组件和切面组件。

          • AnnotationAwareAspectJAutoProxyCreator 会拦截组件的建立过程。

          • 组件建立完后,判断组件是否须要加强

            是:切面的通知方法,包装成加强器(Advisor),给业务逻辑建立一个代理对象。

        • 执行目标方法

          • 代理对象执行目标方法

          • 用 CglibAopProxy.intercept 进行拦截。

            • 获得目标方法的拦截器链(加强器包装成拦截器 MethodInterceptor)。

            • 利用拦截器的链式机制,依次进入每个拦截器进行执行。

            • 效果:

              前置通知->目标方法->后置通知->返回通知/异常通知

      Spring 事务

      入口与 AOP 同样,经过 @EnableTransactionManagement 来进行源码分析。

      @Import(TransactionManagementConfigurationSelector.class)
      public @interface EnableTransactionManagement{
            boolean proxyTargetClass() default false;
            AdviceMode mode() default AdviceMode.PROXY;
      }
      复制代码

      这个注解一样有 @Import 注解,咱们来关注 TransactionManagementConfigurationSelector 这个类来看到底为 Spring 事务导入了什么组件。

      protected String[] selectImports(AdviceMode adviceMode) {
        switch(adviceMode) {
          case PROXY:
            return new String[]{AutoProxyRegistrar.class.getName(), ProxyTransactionManagementConfiguration.class.getName()};
          case ASPECTJ:
            return new String[]{"org.springframework.transaction.aspectj.AspectJTransactionManagementConfiguration"};
          default:
            return null;
        }
      }
      复制代码

      从上面这段代码能够看出,这个注解为咱们导入两个组件,AutoProxyRegistrar 和 ProxyTransactionManagementConfiguration。

      咱们依次来看这两个组件就能明白 Spring 事务究竟是怎么实现的了。

      AutoProxyRegistrar

      public class AutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
      
        public AutoProxyRegistrar() {
        }
        public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
                         Object proxyTargetClass = candidate.get("proxyTargetClass");
                      if (mode != null && proxyTargetClass != null && AdviceMode.class == mode.getClass() && Boolean.class == proxyTargetClass.getClass()) {
                          candidateFound = true;
                          if (mode == AdviceMode.PROXY) {
                              AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry);
                              if ((Boolean)proxyTargetClass) {
                                  AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
                                  return;
                              }
                          }
                      }
          }
      }
      
      复制代码

      从代码来看,他实现了 ImportBeanDefinitionRegistrar 接口,功能就不用解释了,调用 registerBeanDefinitions 方法给容器中注册 Bean 的。

      由于 EnableTransactionManagement 里定义的 mode 就是 AdviceMode.PROXY,并且 proxyTargetClass 是false,因此会执行以下代码:

      AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry);
      复制代码

      给容器中注册一个 InfrastructureAdvisorAutoProxyCreator 组件,这个组件也是一个后置处理器。

      做用:利用后置处理器机制,在对象建立之后,包装对象,返回一个代理对象(加强器),代理对象执行方法,利用链接器链进行调用。

      ProxyTransactionManagementConfiguration

      @Configuration
      public class ProxyTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration {
          public ProxyTransactionManagementConfiguration() {
          }
      
          @Bean(
              name = {"org.springframework.transaction.config.internalTransactionAdvisor"}
          )
          @Role(2)
          public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor() {
              BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();
              advisor.setTransactionAttributeSource(this.transactionAttributeSource());
              advisor.setAdvice(this.transactionInterceptor());
              if (this.enableTx != null) {
                  advisor.setOrder((Integer)this.enableTx.getNumber("order"));
              }
      
              return advisor;
          }
      
          @Bean
          @Role(2)
          public TransactionAttributeSource transactionAttributeSource() {
              return new AnnotationTransactionAttributeSource();
          }
      
          @Bean
          @Role(2)
          public TransactionInterceptor transactionInterceptor() {
              TransactionInterceptor interceptor = new TransactionInterceptor();
              interceptor.setTransactionAttributeSource(this.transactionAttributeSource());
              if (this.txManager != null) {
                  interceptor.setTransactionManager(this.txManager);
              }
      
              return interceptor;
          }
      }
      
      复制代码

      首先 ProxyTransactionManagementConfiguration 也是一个配置类,利用 @Bean 给容器中注册了一些组件。

      首先注册了一个 BeanFactoryTransactionAttributeSourceAdvisor 事务加强器。事务加强器须要注解里面信息。

      咱们关注代码中注册时须要传入一个事务属性,这个属性在下面也是注入的一个 Bean。

      advisor.setTransactionAttributeSource(this.transactionAttributeSource());
      
      @Bean
      @Role(2)
      public TransactionAttributeSource transactionAttributeSource() {
        return new AnnotationTransactionAttributeSource();
      }
      复制代码

      AnnotationTransactionAttributeSource 注册了好多的注解解析器来支持各类类型的注解,包扩 Spring 注解,Jta 注解,Ejb3 注解等等。

      public AnnotationTransactionAttributeSource(boolean publicMethodsOnly) {
        this.publicMethodsOnly = publicMethodsOnly;
        this.annotationParsers = new LinkedHashSet(2);
        this.annotationParsers.add(new SpringTransactionAnnotationParser());
        if (jta12Present) {
          this.annotationParsers.add(new JtaTransactionAnnotationParser());
        }
      
        if (ejb3Present) {
          this.annotationParsers.add(new Ejb3TransactionAnnotationParser());
        }
      
      }
      复制代码

      接下来看事务加强器的第二个属性,事务拦截器,这个属性也是下面注册的一个 Bean。

      advisor.setAdvice(this.transactionInterceptor());
      
      @Bean
      @Role(2)
      public TransactionInterceptor transactionInterceptor() {
        TransactionInterceptor interceptor = new TransactionInterceptor();
        interceptor.setTransactionAttributeSource(this.transactionAttributeSource());
        if (this.txManager != null) {
          interceptor.setTransactionManager(this.txManager);
        }
      
        return interceptor;
      }
      复制代码

      扩展组件

      BeanFactoryPostProcessor

      咱们之前了解过 BeanPostProcessor,它们之间有什么区别那?

      BeanPostProcessor:bean 后置处理器,bean 建立对象初始化先后进行拦截工做的。

      BeanFactoryPostProcessor:beanFactory 的后置处理器,在 BeanFactory 标准初始化以后调用,全部的 BeanDefifnition 都已经保存加载到 beanFactory 中,可是 bean 的实例还未建立。

      • IOC 容器建立对象

      • invokeBeanFactoryPostProcessors(beanFactory)。

      如何找到全部的 BeanFactoryPostProceessor 并执行它们的方法:

      • 直接在 BeanFactory 中找到全部类型是 BeanFactoryPostProcessor 的组件,并执行它们的方法。
      • 在初始化建立其余组件前面执行。

      BeanDefinitionRegistryPostProcessor

      能够将 BeanDefinitionRegistry 理解为 BeanDefinition 的保存中心,之后 BeanFactory 按照 BeanDefinitionRegistry 里面保存的每个 bean 定义信息建立 bean 的实例。

      下面咱们来看 BeanFactoryPostProcessor 的子接口:

      public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {
          void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry var1) throws BeansException;
      }
      复制代码

      额外定义了一个 postProcessBeanDefinitionRegistry 方法,在全部 bean 的定义信息将要被加载,bean 实例还未被建立时执行,在 BeanFactoryPostProceessor 以前执行,由于 BeanFactoryPostProceessor 是在 bean 的定义信息已经被加载后执行。

      能够利用 BeanDefinitionRegistryPostProcessor 给容器中额外添加一些组件。

      原理:

      • IOC 建立对象
      • refresh()->invokeBeanFactoryPostProcessors(beanFactory);
      • 先从容器中获取到全部的 BeanDefinitionRegistryPostProcessors 组件,依次触发全部的 postProcessBeanDefinitionRegistry() 方法,再触发 BeanFactoryPostProcessor。
      • 再来从容器中找到 BeanFactoryPostProcessor 组件,一次触发 postProcessBeanFactory() 方法。

      ApplicationListener

      监听容器中发布的事件,完成事件驱动模型的开发。

      public interface ApplicationListener<E extends ApplicationEvent> 复制代码

      监听 ApplicationEvent 及其子类。

      基于事件开发的步骤:

      • 写一个监听器来监听某个事件,ApplicationEvent 及其子类。

      • 或者使用 @EventListener 注解让任意组件都能监听事件,使用 EventListenerMethodProcessor 这个处理器来解析这个注解。

        • 实现了 SmartInitializingSingleton。
      • 把监听器加入到容器。

      • 只要容器中有相关事件的发布,咱们就能监听到这个事件。

        ContextRefreshedEvent:容器刷新完成(全部 Bean 都建立完成)会发布这个事件。

        ContextCloseEvent:关闭容器会发布这个事件。

      • 发布一个事件:applicationContext.pushlishEvent。

      原理:

      ContextRefreshEvent 事件

      • 容器建立对象:refresh()

      • finishRefresh(),容器刷新完成

      • publishEvent(new ContextRefreshedEvent(this))

        【发布流程】

        • 获取事件多播器(派发器):getApplicaitonEvnetMulticaster()

        • multicastEvent 派发事件

        • 获取到全部的 ApplicationListener

          若是 Listener 里有 Executor,能够支持使用 Executor 进行异步派发。

          Executor executor = getTaskExecutor();
          复制代码

          不然同步的方式直接执行 listener 方法,里面经过 listener 回调 onApplicationEvent(envet) 方法。

          invokeListener(listener, event);
          复制代码

      SmartInitializingSingleton

      全部单实例 Bean 建立完成以后触发。

      // 全部的单实例 Bean 建立完后执行
      public interface SmartInitializingSingleton{
        void afterSingletonsInstantiated();
      }
      复制代码

      过程:

      • IOC 容器建立对象并 refresh 容器
      • finishBeanFactoryInitialization(beanFactory),初始化剩下的单实例 Bean。
        • 建立全部的单实例 Bean,for 循环 + getBean() .
        • 获取建立好的单实例 Bean,判断是不是 SmartInitializingSingleton,若是是就调用 afterSingletonsInstantiated 方法。
相关文章
相关标签/搜索