Spring
Spring 启动过程中的扩展点
- BeanFactoryAware,可在bean中获取BeanFactory实例
- ApplicationContextAware ,可在bean中获取ApplicationAware实例
- BeanNameAware, 可在Bean中获取它在IOC容器中的Bean实例的名字
- ApplicationListener. 可监听ContextRefershedEvent等
- CommandLineRunner ,整个项目启动完成之后,自动执行
- SmartLifecycle#start 在Spring bean实例化之后,执行start方法
- 使用@PostConstruct 注解,用于Bean实例初始化
- 实现InitializingBean. 接口,用于bean实例初始化
- xml中声明init-method方法,用于Bean实例化
- Configuration 配置类,通过@Bean注解,注册Bean到spring
- BeanPostProcessor 在bean的初始化前后,植入扩展点
- BeanFactoryPostProcessor 在BeanFactory创建后植入扩展点
spring扩展点
- 参考 https://cloud.tencent.com/developer/article/2175801
-
[1]ApplicationContextInitializer 这个是整个spring容器在刷新之前初始化ConfigurableApplicationContext的回调接口,容器刷新之前调用此类的initialize方法,这个点允许用户进行扩展,可以在整个spring还没有初始化之前做一些事情,因为这时候spring容器还没有被初始化,想要自己的扩展生效,需要一下三种方式 1、在启动类中。SpringApplication.addInitializers(new TestApplicationContextInitializer()); 2、配置文件 配置。context.initializer.classes=扩展累路径 3、Spring spi扩展,在spring.factories中加入. org.springframework.context.ApplicationContextInitializer=类路径
-
[2]BeanDefinitionRegistryPostProcessor 这个接口在读取项目中的beanDefinition之后执行,提供一个补充的扩展点 可以动态注册自己的beanDefinition,可以加载classpath之外的bean
-
[3]BeanFactoryPostProcessor 这个接口是BeanFactory的扩展接口,调用时机在spring读取beanDefinition信息之后,实例话bean之前 这个时机,用户可以通过实现这个扩展接口来自行处理一些东西,比如修改已经注册的beanDefinition的元信息
- [4]InstantiationAwareBeanPostProcessor 这个接口继承了BeanPostProcesso接口,区别如下: BeanPostProcess接口只在bean的初始化阶段进行扩展(注入spring上下文前后),而InstantiationAwareBeanPostProcessor接口在此基础上增加了3个方法,把可扩展的范围增加了实例化阶段和属性注入阶段。
该类主要的扩展点有以下5个方法,主要在bean生命周期的两大阶段:实例化阶段和初始化阶段,下面一起进行说明,按调用顺序为: 该类主要的扩展点有以下5个方法,主要在bean生命周期的两大阶段:实例化阶段和初始化阶段,下面一起进行说明,按调用顺序为:
postProcessBeforeInstantiation:实例化bean之前,相当于new这个bean之前 postProcessAfterInstantiation:实例化bean之后,相当于new这个bean之后 postProcessPropertyValues:bean已经实例化完成,在属性注入时阶段触发,@Autowired,@Resource等注解原理基于此方法实现 postProcessBeforeInitialization:初始化bean之前,相当于把bean注入spring上下文之前 postProcessAfterInitialization:初始化bean之后,相当于把bean注入spring上下文之后 使用场景:这个扩展点非常有用 ,无论是写中间件和业务中,都能利用这个特性。比如对实现了某一类接口的bean在各个生命期间进行收集,或者对某个类型的bean进行统一的设值等等。
-
[5]SmartInstantiationAwareBeanPostProcessor 也是在bean实例化过程中
-
[6]BeanFactoryAware 在bean实例化之后,注入属性之前,也就是初始化之前setter之前,在这个时候,可以对每个bean作为特殊化定制,也或者可以把BeanFactory拿到进行缓存
-
[7]ApplicationContextAwareProcessor 在bean实例话之后初始化之前
-
[8]beanNameAware 可以看到,这个类也是Aware扩展的一种,触发点在bean的初始化之前,也就是postProcessBeforeInitialization之前,这个类的触发点方法只有一个:setBeanName
使用场景为:用户可以扩展这个点,在初始化bean之前拿到spring容器中注册的的beanName,来自行修改这个beanName的值。
-
[9]@PostConstruct 在bean的初始化阶段,如果有这个注解,回西安调用这个方法,这个触发点是在postProcessBeforeInitialization之后,InitializingBean.afterPropertiesSet之前 用户可以对某一个方法进行标注,来进行初始化某个属性
-
[10]InitializingBean 这个类,顾名思义,也是用来初始化bean的。InitializingBean接口为bean提供了初始化方法的方式,它只包括afterPropertiesSet方法,凡是继承该接口的类,在初始化bean的时候都会执行该方法。这个扩展点的触发时机在postProcessAfterInitialization之前。
使用场景:用户实现此接口,来进行系统启动的时候一些业务指标的初始化工作。
- [11]FactoryBean
一般情况下,Spring通过反射机制利用bean的class属性指定支线类去实例化bean,在某些情况下,实例化Bean过程比较复杂,如果按照传统的方式,则需要在bean中提供大量的配置信息。配置方式的灵活性是受限的,这时采用编码的方式可能会得到一个简单的方案。Spring为此提供了一个org.springframework.bean.factory.FactoryBean的工厂类接口,用户可以通过实现该接口定制实例化Bean的逻辑。FactoryBean接口对于Spring框架来说占用重要的地位,Spring自身就提供了70多个FactoryBean的实现。它们隐藏了实例化一些复杂bean的细节,给上层应用带来了便利。从Spring3.0开始,FactoryBean开始支持泛型,即接口声明改为FactoryBean
的形式
使用场景:用户可以扩展这个类,来为要实例化的bean作一个代理,比如为该对象的所有的方法作一个拦截,在调用前后输出一行log,模仿ProxyFactoryBean的功能。
- [12]SmartInitializingSingleton 这个接口中只有一个方法afterSingletonsInstantiated,其作用是是 在spring容器管理的所有单例对象(非懒加载对象)初始化完成之后调用的回调接口。其触发时机为postProcessAfterInitialization之后。
使用场景:用户可以扩展此接口在对所有单例对象初始化完毕后,做一些后置的业务处理。
- [13]CommandLineRunner 这个接口也只有一个方法:run(String… args),触发时机为整个项目启动完毕后,自动执行。如果有多个CommandLineRunner,可以利用@Order来进行排序。
使用场景:用户扩展此接口,进行启动项目之后一些业务的预处理。
-
[14]DisposableBean 这个扩展点也只有一个方法:destroy(),其触发时机为当此对象销毁时,会自动执行这个方法。比如说运行applicationContext.registerShutdownHook时,就会触发这个方法。
-
[15]ApplicationListener
Spring源码
https://doocs.github.io/source-code-hunter/#/docs/Spring/IoC/1%E3%80%81BeanDefinition%E7%9A%84%E8%B5%84%E6%BA%90%E5%AE%9A%E4%BD%8D%E8%BF%87%E7%A8%8B
spring原理
https://doocs.github.io/source-code-hunter/#/docs/Spring/Spring%E6%95%B4%E4%BD%93%E8%84%89%E7%BB%9C/16%E5%BC%A0%E5%9B%BE%E8%A7%A3%E9%94%81Spring%E7%9A%84%E6%95%B4%E4%BD%93%E8%84%89%E7%BB%9C?id=%e5%8d%b0%e8%b1%a1%e4%b8%ad%e7%9a%84-spring
IOC=工厂模式+xml+反射 DI,AOP,事务等也都在xml中表现
BeanDefinition—>BeanFactory—>Bean Bean的解析流程。 xml/properties/Groovy—解析器—>BeanDefinitionReader–>解析–>BeanDefinition—> BeanDefinitionRegistry 注解解析器—>AnnotatedBeanDefinitionReader———->解析—>BeanDefinition—>BeanDefinitionRegistry 重要属性。 beanClass/scope/isLazy/initMethodName/primary/dependsOn—->BeanDefinition————>BeanDefinitionRegistry 就是通过解析器,对xml文件或者注解进行解析,最后将这些信息封装到BeanDefinition类中,并通过BeanDefinitionRegistry将这些信息注册起来,放到beanDefinitionMap变量,key:beanName/value/beanDefinition BeanDefinition:
- beanClass: bean的类型,实例化时使用的
- scope:作用范围有singleton/prototype
- initMethodName: 初始化方法,初始化时调用
- primary: 有多个bean时使用它
- dependsOn:依赖bean,必须等依赖bean创建好才可以创建
@Component,@Bean都会被解析成BeanDefinition
有了原料BeanDefinition之后,再看工厂BeanFactory,这个工厂通过反射创建bean
BeanDefinition—>beanClass–>BeanFactory—反射Constructor
ListableBeanFactory. 遍历bean HierarchicalBeanFactory. 提供父子关系,可以获取上一级的BeanFactory ConfigurableBeanFactory. 实现类SingletonBeanRegistry 主要是单例bean的注册和生成 AutowireCapableBeanFactory. 和自动装配有关的 AbstractBeanFactory: 单例缓存,以及FactoryBean相关的 ConfigurableListableBeanFactory: 预实例化单例bean,分析修改BeanDefinition AbstractAutowireCapableBeanFactory: 创建Bean,属性注入,实例化,调用初始化方法等等 DefaultListaleBeanFactory:支持单例Bean,Bean别名,父子BeanFactory,Bean类型转化,Bean后置处理FactoryBean,自动装配等
FactoryBean,它本身就是个Bean,算是小工厂,归BeanFactory这个大工厂管理 FactoryBean 方法:getObject() 获取对象。isSingleton()单例对象。 getObjectType()返回是bean对象的类型 相比于大工厂BeanFactory少了很多东西,没有严格的Bean声明周期流程 FactoryBean本身也是一个Bean,是一个小工厂,可以生产另外的bean BeanFactory是spring容器的根接口,是大工厂,生产各种各样的Bean beanName就是正常对象 【有&获取FactoryBean本身,没有&获取该接口中的泛型对象】
ApplicationContext 扩展了一些功能,除了BeanFactory,它还可以创建获取Bean,以及处理国际化,事件,获取资源等
- EnvironmentCapable 获取 环境变量 的功能,可以获取到 操作系统变量 和 JVM 环境变量
- ListableBeanFactory 获取所有 BeanNames,判断某个 BeanName 是否存在 BeanDefinition 对象,统计 BeanDefinition 对象,获取某个类型对应的所有 beanNames 等功能
- HierarchicalBeanFactory 获取父 BeanFactory ,判断某个 name 是否存在 bean 对象的功能
- MessageSource 国际化功能,获取某个国际化资源
- ApplicationEventPublisher 事件发布功能(重点)
-
ResourcePatternResolver 加载,获取资源的功能,这里的资源可能是文件,图片 等某个 URL 资源都可以 还有这三个重要的类 👇,就不一一介绍先啦 😄
- ClassPathXmlApplicationContext
- AnnotationConfigApplicationContext
- FileSystemXmlApplicationContext
Bean的初始化
- [1]属性填充,构造器中的参数@Autowire。@Value
- [2]根据Aware接口填充bean 8个xxxAware接口, ++ BeanNameAware. setBeanName ++ BeanClassLoaderAware. setBeanClassLoader ++ BeanFactoryAware. setBeanFactory ++ ResourceLoaderAware. setResourceLoader ++ ApplicationEventPublisherAware. setApplicationEventPublisher ++ MessageSourceAware. setMessageSource ++ ApplicationContextAware. setApplicationContext ++ ServletContextAware. setServletContext
- [3]BeanPostProcessor初始化前方法。postProcessBeforeInitialization
- [4]初始化方法。 @PostConstruct. init-method等方式指定
- [5]BeanPostProcessor初始化后方法。—【AOP】postProcessAfterInitialization
AbstractAutoProxyCreator
参考
http://www.gydblog.com/spring/spi.html#%E4%B8%89%E3%80%81spring%E7%9A%84spi%E8%AE%BE%E8%AE%A1