spring|spring ioc源码分析
【spring|spring ioc源码分析】清晰图或者源码可以加我Q群:940577921 获取
文章图片
图片1.png
Spring IOC介绍
IoC也称为依赖注入(dependency injection, DI)。它是一个对象定义依赖关系的过程,也就是说,对象只通过构造函数参数、工厂方法的参数或对象实例构造或从工厂方法返回后在对象实例上设置的属性来定义它们所使用的其他对象。然后容器在创建bean时注入这些依赖项。这个过程基本上是bean的逆过程,因此称为控制反转(IoC)。
在Spring中,构成应用程序主干并由Spring IoC容器管理的对象称为bean。bean是由Spring IoC容器实例化、组装和管理的对象。
IoC容器理念:通过容器将对象的构建方式统一,并且自动维护对象的依赖关系。由 IoC 容器帮对象找相应的依赖对象并注入,而不是由对象主动去找。
回顾Bean的使用
bean的配置
// 注册一个bean
registry.registerBeanDefinition("fox",new RootBeanDefinition(Fox.class));
1.xml
ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
2.实现FactoryBean
FactoryBean和BeanFactory的区别,什么情况下返回FactoryBean,什么情况返回调用getObject()的结果
3.@Component ,扫描包
@ComponentScan("com.jiagouedu")
@Configuration
public class AppConfig {
}
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
4.@Bean
5.@Import
@Import(value = https://www.it610.com/article/{MyImportBeanDefinitionRegistrar.class,MyImportSelector.class})
?ImportBeanDefinitionRegistrar
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
BeanDefinition beanDefinition = new RootBeanDefinition(UserServiceImpl.class);
registry.registerBeanDefinition("userServiceImpl",beanDefinition);
}
}
?ImportSelector
public class MyImportSelector implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
return new String[]{"com.jiagouedu.bean.Cat"};
}
}
bean的生命周期
bean的生命周期: bean的创建 初始化 销毁
1.bean的注册原理
bean是如何注册到容器中的?
BeanDefinition 承载bean的信息,并注册到BeanDefinitionRegistry注册器中,bean工厂获取到注册器中对应bean的信息,才能生产bean
BeanDefinition (Bean定义) 承载bean的属性信息
BeanDefinitionRegistry(Bean注册器) bean的id作为key注册
AliasRegistry (别名注册器) bean的name作为key注册
BeanDefinitionReader(Bean定义读取) 读取配置文件
Beanfactory (bean工厂) 生产bean
示例
//创建一个简单注册器
//BeanDefinitionRegistry register = new SimpleBeanDefinitionRegistry();
//实现注册器的工厂
BeanDefinitionRegistry registry = new DefaultListableBeanFactory();
//创建bean定义读取器
BeanDefinitionReader reader = new XmlBeanDefinitionReader(register);
// 创建资源读取器
//DefaultResourceLoader resourceLoader = new DefaultResourceLoader();
// 获取资源
//Resource xmlResource = resourceLoader.getResource("spring.xml");
reader.loadBeanDefinitions("spring.xml");
// 装载Bean的定义
reader.loadBeanDefinitions(xmlResource);
// 打印构建的Bean 名称
System.out.println(Arrays.toString(register.getBeanDefinitionNames());
// 工厂调用getBean方法
((DefaultListableBeanFactory) registry).getBean("user")
// 注册一个bean
registry.registerBeanDefinition("fox",new RootBeanDefinition(Fox.class));
2.bean的创建流程
Bean创建时序图
文章图片
图片2.png Debug跟踪流程:
AbstractApplicationContext#finishBeanFactoryInitialization
ConfigurableListableBeanFactory#preInstantiateSingletons
AbstractBeanFactory#getBean(java.lang.String)
AbstractBeanFactory#doGetBean
markBeanAsCreated(beanName);
//标记Bean正要创建
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
是不是抽象的
String[] dependsOn = mbd.getDependsOn();
有没有依赖,先实例化依赖bean
创建bean实例 DefaultSingletonBeanRegistry#getSingleton
通过工厂获取对象 singletonObject = singletonFactory.getObject();
AbstractAutowireCapableBeanFactory#createBean
Instantiate the bean. AbstractAutowireCapableBeanFactory#doCreateBean
# 包装的bean BeanWrapper
instanceWrapper=createBeanInstance(beanName, mbd, args);
AbstractAutowireCapableBeanFactory#createBeanInstance
调用无参构造器 AbstractAutowireCapableBeanFactory#instantiateBean
#反射
beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
//填充bean由 IoC 容器帮对象找相应的依赖对象并注入,而不是由对象主动去找。
populateBean(beanName, mbd, instanceWrapper);
// 初始化bean
exposedObject = initializeBean(beanName, exposedObject, mbd);
文章图片
image.png
推荐阅读
- Activiti(一)SpringBoot2集成Activiti6
- SpringBoot调用公共模块的自定义注解失效的解决
- 解决SpringBoot引用别的模块无法注入的问题
- Android事件传递源码分析
- 2018-07-09|2018-07-09 Spring 的DBCP,c3p0
- Quartz|Quartz 源码解析(四) —— QuartzScheduler和Listener事件监听
- [源码解析]|[源码解析] NVIDIA HugeCTR,GPU版本参数服务器---(3)
- ffmpeg源码分析01(结构体)
- spring|spring boot项目启动websocket
- Java程序员阅读源码的小技巧,原来大牛都是这样读的,赶紧看看!