spring中有多少种ioc容器:spring源码解析-IOC容器的基本实现
spring中有多少种ioc容器:spring源码解析-IOC容器的基本实现->各种配置抽象为Resource资源->多种配置方式配置Bean(xml 注解Component java config)spring 与其他框架整合 通过 spring 提供的扩展点 把其他框架的对象交给 spring 管理 对象交给 spring 管理是想要避免手动创建对象 也可以通过@Autowired 等注解实现属性注入 让我们使用对象起来更加方便//1 xml 方式配置spring Bean <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-insta
大纲
- 容器的基本用法
- spring启动过程分析(Spring生命周期)
- bean 的生命周期
- IOC核心类总结
- 常用扩展点
spring 是企业级开发框架 主要功能有 IOC AOP Web ORM等
spring IOC专门用于管理bean对象 管理对象的创建 属性注入等
spring AOP 给予动态代理 实现了切面编程 动态实现对象功能扩展
spring 与其他框架整合 通过 spring 提供的扩展点 把其他框架的对象交给 spring 管理 对象交给 spring 管理是想要避免手动创建对象 也可以通过@Autowired 等注解实现属性注入 让我们使用对象起来更加方便
- spring xml 方式配置示例
//1 xml 方式配置spring Bean
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 配置spring bean -->
<bean id="petStore" class="cn.javabus.PetStoreService.class"> </bean>
</beans>
//2 初始化 IOC容器
ApplicationContext context = new ClassPathXmlApplicationContext("services.xml" "daos.xml");
PetStoreService service = context.getBean("petStore" PetStoreService.class);
spring启动过程分析(spring生命周期)
spring生命周期与bean生命周期
- spring启动过程描述
1 BeanDefinition 解析注册
->多种配置方式配置Bean(xml 注解Component java config)
->各种配置抽象为Resource资源
->通过BeanDefinitionReader 解析BeanDefinition 注册到 BeanDefinitionRegistry
2 PostProcessor 各种处理器注册调用
->获取BeanFactory
->注册和调用BeanFactoryPostProcessor(bean工厂后置处理器)
->注册BeanFactoryPostProcessors
3 bean 生命周期处理
->实例化对象
->依赖注入
->bean 初始化
-> 存放到SpringContext容器
- 以AbstractApplicationContext中的refresh()方法为起点进行源码分析
public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
this(); //创建BeanDefinitionReader BeanDefinitionScanner对象
//BeanDefinition解析和注册 (DefaultListableBeanFactory.beanDefinitionMap)
register(componentClasses);
refresh();
}
public void refresh() throws BeansException IllegalStateException {
synchronized(this.startupShutdownMonitor) {
StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
//记录容器开始时间startupDate 设置活跃状态为true 设置environment对象
this.prepareRefresh();
//1 创建beanFactory实例对象 一般是DefaultListableBeanFactory
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);
StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
// Invoke factory processors registered as beans in the context.
//2 按照顺序注册BeanFactoryPostProcessors 并且按照顺序调用
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
//3 按照顺序注册BeanPostProcessors
registerBeanPostProcessors(beanFactory);
beanPostProcess.end();
// 注册国际化相关内容 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.
//4 调用getBean()方法对非延迟加载的bean进行实例化 (最重要 涉及bean生命周期)
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
finishRefresh();
}
}
}
spring bean的生命周期
Spring中每个Bean的生命周期如下:
图片来源于网络
- spring bean 生命周期 (Bean 解析和注册)
实例化 -> 属性赋值 -> 初始化 -> 销毁
实例化 Instantiation
属性赋值 Populate
初始化 Initialization
销毁 Destruction
class
->构造器->反射创建对象
-> 依赖注入(@Autowired)
-> 初始化前(@PostConstruct)->初始化(InitializingBean)->初始化后(AOP)
-> 代理对象->bean
- spring bean生命周期代码入口 finishBeanFactoryInitialization(beanFactory)
//真正逻辑在 AbstractAutowireCapableBeanFactory.doCreateBean()
finishBeanFactoryInitialization()
DefaultListableBeanFactory#preInstantiateSingletons()
getBean(beanName)
AbstractBeanFactory.doGetBean()
AbstractAutowireCapableBeanFactory#createBean()
//1
Object bean = resolveBeforeInstantiation(beanName mbdToUse);
//2 对象实例化 AbstractAutowireCapableBeanFactory.doCreateBean()
Object beanInstance = doCreateBean(beanName mbdToUse args);
BeanWrapper instanceWrapper = null;
//doCreateBean-1 通过反射创建对象实例 (调用构造器创建对象)
instanceWrapper = createBeanInstance(beanName mbd args);
//doCreateBean-2 给后置BDpost-processors 一个修改 BeanDefinition的机会
applyMergedBeanDefinitionPostProcessors(mbd beanType beanName);
//doCreateBean-3 通过提前暴露一个单例工厂方法 从而使得其他 bean 能够引用到该 bean (解决单例 bean循环依赖)
addSingletonFactory(beanName () -> getEarlyBeanReference(beanName mbd bean));
//doCreateBean-4 DI 依赖注入 (对象属性初始化 各个属性值注入 其中可能注入其他 bean 的属性 这时候会递归初始化依赖 bean)
populateBean(beanName mbd instanceWrapper);
//doCreateBean-5 调用初始化方法 比如 init-method
exposedObject = initializeBean(beanName exposedObject mbd);
//initializeBean-1 调用 Aware接口实现类
invokeAwareMethods(beanName bean);
//initializeBean-2 bean前置处理 beanProcessor.postProcessBeforeInitialization();
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean beanName);
//initializeBean-3 调用初始化方法((InitializingBean) bean).afterPropertiesSet();
invokeInitMethods(beanName wrappedBean mbd);
//initializeBean-4 bean后置处理 beanProcessor.postProcessAfterInitialization()
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean beanName);
return exposedObject;
//3
return beanInstance;
//然后回到AbstractBeanFactory.doGetBean() 执行getSingleton() 注册 bean到容器
sharedInstance = getSingleton(beanName () -> {
//todo 2.2 创建 单实例bean (ctrl T)
return createBean(beanName mbd args);
}
- spring bean 生命周期核心代码逻辑
// AbstractBeanFactory.doGetBean()
protected <T> T doGetBean(final String name ...) {
// 1 提取对应的 beanName (传入的 name 可能是别名 FactoryBean(name="&aa"))
final String beanName = transformedBeanName(name);
Object bean;
// 2 尝试直接从缓存获取 或者singletonFactories 中的 objectFactory中获取
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
//该条件一般为二次获取 bean 才会进入
}else {
//lambda 方式调用 DefaultSingletonBeanRegistry.getSingleton(beanName ObjectFactory<?>)
//获取createBean()创建的bean对象后 走getSingleton()逻辑添加bean 到bean容器(DefaultSingletonBeanRegistry.singletonObjects
sharedInstance = getSingleton(beanName () -> {
//todo 2.2 调用createBean()方法创建对象
return createBean(beanName mbd args);
}
bean = getObjectForBeanInstance(sharedInstance name beanName mbd);
}
}
//...
return (T) bean;
}
//AbstractAutowireCapableBeanFactory.doCreateBean()
//spring bean 生命周期核心代码逻辑(bean 实例化 依赖注入 以及初始化)
protected Object doCreateBean(final String beanName final RootBeanDefinition mbd final @Nullable Object[] args){
// Instantiate the bean. (装饰模式)
BeanWrapper instanceWrapper = null;
if (instanceWrapper == null) {
//todo 1 根据指定的 bean 使用对应的策略来创建 bean 如:工厂方法 构造函数注入 简单初始化
instanceWrapper = createBeanInstance(beanName mbd args);
}
// Initialize the bean instance.
try {
//todo 2 DI 依赖注入 (对象属性初始化 各个属性值注入 其中可能注入其他 bean 的属性 这时候会递归初始化依赖 bean)
populateBean(beanName mbd instanceWrapper);
//todo 3 调用初始化方法 比如 init-method
exposedObject = initializeBean(beanName exposedObject mbd);
}
// ...Register bean as disposable.
return exposedObject;
}
Bean生命周期-常用扩展点
- 第一大类:容器级生命周期接口方法(影响多个Bean的接口)
容器级生命周期接口方法:包含了InstantiationAwareBeanPostProcessor和BeanProcessor这两个接口实现,称他们的实现类为“后处理器”。
实现了这些接口的Bean会切入到多个Bean的生命周期中。因此,这些接口的功能非常强大,Spring内部扩展也经常使用这些接口,例如自动注入以及AOP的实现都和他们有关。
1 BeanPostProcessor 作用于初始化阶段的前后
2 InstantiationAwareBeanPostProcessor 作用于实例化阶段的前后,
这两兄弟可能是Spring扩展中最重要的两个接口!
工厂后处理器接口方法:包含了AspectJWeavingEnabler、ConfigurationClassPostProcessor、CustomAutowreConfigure等非常有用的工厂后处理器接口的方法,会在应用上下文装配配置文件后立即调用。
- 第二大类:Bean级别生命周期接口方法(每个 bean调用一次的接口)
1 Aware类型的接口
2 Bean生命周期接口 包含了BeanNameAware、BeanFactoryAware、initialzingBean和DiposableBean这些接口的方法
3 Bean的自身方法: 这个包括了init-method和destory-method方法
Aware类型的接口的作用就是让我们能够拿到Spring容器中的一些资源。
基本都能够见名知意,Aware之前的名字就是可以拿到什么资源,例如BeanNameAware可以拿到BeanName,以此类推。
调用时机需要注意:所有的Aware方法都是在初始化阶段之前调用的!
- 各个接口调用时机演示
//1 BeanFactoryPostProcessor 工厂后处理器接口
@Component
public class CustomBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
public CustomBeanFactoryPostProcessor() {
System.out.println("==[BeanFactoryPostProcessor 接口]调用了 CustomBeanFactoryPostProcessor 构造器");
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("==[BeanFactoryPostProcessor 接口]调用了 CustomBeanFactoryPostProcessor.postProcessBeanFactory() 修改bean定义");
//BeanDefinition beanDefinition = beanFactory.getBeanDefinition("person");
//beanDefinition.setScope(BeanDefinition.SCOPE_PROTOTYPE);
beanFactory.registerSingleton("newobjr" new Object());
}
}
// 2 BeanPostProcessor bean处理器
@Component
public class CustomBeanPostProcessor implements BeanPostProcessor {
public CustomBeanPostProcessor() {
System.out.println("==[BeanPostProcessor 接口]调用了 CustomBeanPostProcessor 构造器");
}
@Override
public Object postProcessBeforeInitialization(Object bean String beanName) throws BeansException {
System.out.println("==4 [BeanPostProcessor 接口]调用了 " beanName ".postProcessBeforeInitialization()");
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean String beanName) throws BeansException {
System.out.println("==6 [BeanPostProcessor 接口]调用了 " beanName ".postProcessAfterInitialization()");
return bean;
}
}
// 3Bean级别生命周期接口方法
@Component
public class Person implements BeanFactoryAware BeanNameAware InitializingBean DisposableBean {
public Person() {
System.out.println("==1 [Person]调用了构造器 进行对象实例化");
}
@Override
public void setBeanName(String s) {
System.out.println("==2 [BeanNameAware 接口]调用了 BeanNameAware.setBeanName()");
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println("==3 [BeanFactoryAware 接口]调用了 BeanFactoryAware.setBeanFactory()");
}
//==4 BeanPostProcessor.postProcessBeforeInitialization()...
@PostConstruct//@PostConstruct是一种 BeanPostProcessor
public void demo() {
System.out.println("==5.1 [@PostConstruct]调用了 Person.demo()");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("==5.2 [InitializingBean 接口]调用了 InitializingBean.afterPropertiesSet()");
}
//==6 BeanPostProcessor.postProcessAfterInitialization()...
@Override
public void destroy() throws Exception {
System.out.println("==7 [DisposableBean 接口]调用了 DisposableBean.destroy()");
}
}
@ComponentScan(basePackages = "spring")
public class SpringTest {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringTest.class);
System.out.println("spring 容器初始化成功");
Person person1 = context.getBean(Person.class);
//Person person2 = context.getBean(Person.class);
//boolean r = person1 == person2;
//System.out.println("person1 == person2 结果为:" r); //结果为:false 在BeanFactoryPostProcessor 中修改了bean scope
context.registerShutdownHook();
System.out.println("main结束");
}
}
==[BeanFactoryPostProcessor 接口]调用了 CustomBeanFactoryPostProcessor 构造器
==[BeanFactoryPostProcessor 接口]调用了 CustomBeanFactoryPostProcessor.postProcessBeanFactory() 修改bean定义
==[BeanPostProcessor 接口]调用了 CustomBeanPostProcessor 构造器
==4 [BeanPostProcessor 接口]调用了 springTest.postProcessBeforeInitialization()
==6 [BeanPostProcessor 接口]调用了 springTest.postProcessAfterInitialization()
//通过以下输出可以观察到person对象 生命周期接口方法调用顺序
==1 [Person]调用了构造器 进行对象实例化
==2 [BeanNameAware 接口]调用了 BeanNameAware.setBeanName()
==3 [BeanFactoryAware 接口]调用了 BeanFactoryAware.setBeanFactory()
==4 [BeanPostProcessor 接口]调用了 person.postProcessBeforeInitialization()
==5.1 [@PostConstruct]调用了 Person.demo()
==5.2 [InitializingBean 接口]调用了 InitializingBean.afterPropertiesSet()
==6 [BeanPostProcessor 接口]调用了 person.postProcessAfterInitialization()
spring 容器初始化成功
person1 == person2 结果为:true
main结束
==7 [DisposableBean 接口]调用了 DisposableBean.destroy()
Spring IOC核心类总结
1 BeanDefinition 用于封装 spring bean 的配置信息
2 BeanDefinitionRegistry 用于存放解析后的BeanDefinition对象 spring 提供了扩展机制 允许用户在 spring 框架启动时动态的往BeanDefinitionRegistry容器中注册对象
3 BeanFactory 是 Spring 的Bean 工厂 负责 Bean 创建和属性注入(DefaultListableBeanFactory)
4 BeanFactoryPostProcessor BeanFactory的后置处理器; 是 spring 提供的扩展机制;
允许在所有 BeanDefinition配置信息解析完成后 修改 BeanFactory(Bean工厂)信息.例如向BeanDefinitionRegistry注册BeanDefinition对象
在BeanFactory创建完成后会调用BeanFactoryPostProcessor实现类的 postProcessBeanFactory() 方法
5 ImportBeanDefinitionRegistrar接口作用于 Spring 解析 Bean 的配置阶段 当解析@Configuration 注解时调用. 需要配合@Import 注解使用
6 BeanPostProcessor 是Bean的后置处理器.在 Bean 初始化方法(init-method 属性指定的方法或者 afterPropertiesSet()方法)调用前后 会执行 BeanPostProcessor的拦截逻辑
7 ClassPathBeanDefinitionScanner 是BeanDefinition扫描器 能够对象指定包下的 Class 进行扫描 将 Class 转换为BeanDefinition对象注册到BeanDefinitionRegistry 容器中
8 FactoryBean 是 Spring 中的工厂 bean 通常用于处理 spring 中配置较为复杂或者由动态代理生成的 Bean 实例.
实现了该接口的 Bean 不能作为普通的 Spring bean 使用而是作为单个对象的工厂.
当通过 Bean 名称获取 FactoryBean 实例时 获取到的并不是FactoryBean对象本身 而是FactoryBean对象 getObject()方法返回的对象
BeanFactory:定义获取bean及bean的各种属性。
HierarchicalBeanFactory:继承BeanFactory,也就是在BeanFactory定义的功能的基础上增加了对parentFactory的支持。
SingletonBeanRegistry:定义对单例的注册及获取。
DefaultSingletonBeanRegistry:对接口SingletonBeanRegistry各函数的实现。
AutowireCapableBeanFactory:提供创建bean、自动注入、初始化以及应用bean的后处理器。
spring IOC 常用类介绍
DefaultListableBeanFactory继承关系图
ApplicationContext 接口继承关系图
BeanPostProcessor 注册时机与执行顺序BeanPostProcessor有很多个,而且每个BeanPostProcessor都影响多个Bean,其执行顺序至关重要,必须能够控制其执行顺序才行。关于执行顺序这里需要引入两个排序相关的接口:PriorityOrdered、Ordered
PriorityOrdered、Ordered接口作为Spring整个框架通用的排序接口,在Spring中应用广泛,也是非常重要的接口。
1 PriorityOrdered是一等公民,首先被执行,PriorityOrdered公民之间通过接口返回值排序
2 Ordered是二等公民,然后执行,Ordered公民之间通过接口返回值排序
3 都没有实现是三等公民,最后执行
//在以下源码中,可以很清晰的看到Spring注册各种类型BeanPostProcessor的逻辑,
//根据实现不同排序接口进行分组。优先级高的先加入,优先级低的后加入。
// 首先,加入实现了PriorityOrdered接口的BeanPostProcessors,顺便根据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();
// 然后,加入实现了Ordered接口的BeanPostProcessors,顺便根据Ordered排了序
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class true false);
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName Ordered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
sortPostProcessors(currentRegistryProcessors beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors registry);
currentRegistryProcessors.clear();
// 最后加入其他常规的BeanPostProcessors
boolean reiterate = true;
while (reiterate) {
reiterate = false;
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class true false);
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
reiterate = true;
}
}
sortPostProcessors(currentRegistryProcessors beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors registry);
currentRegistryProcessors.clear();
}
//根据排序接口返回值排序,默认升序排序,返回值越低优先级越高。
PriorityOrdered、Ordered接口作为Spring整个框架通用的排序接口,在Spring中应用广泛,也是非常重要的接口。
参考文档:
Spring生命周期_Jason snow的博客-CSDN博客_spring生命周期
Spring Bean 生命周期 (实例结合源码彻底讲透) - SegmentFault 思否
Spring 的生命周期_鼠标垫和鼠标的博客-CSDN博客_spring生命周期