Spring ioc分析,以及编码实现
程序员文章站
2022-07-12 13:09:11
...
1. 什么是IOC
控制反转(Inversion of Control,缩写为IoC),是面向对象编程中的一种设计原则,可以用来减低计算机代码之间的耦合度。其中最常见的方式叫做依赖注入(Dependency Injection,简称DI),还有一种方式叫“依赖查找”(Dependency Lookup)。通过控制反转,对象在被创建的时候,由一个调控系统内所有对象的外界实体,将其所依赖的对象的引用传递给它。也可以说,依赖被注入到对象中。
他能够帮助我们管理所有类的创建,销毁,是否是单例模式,类与类之间的多层依赖关系
2. IOC 解决了什么问题?
IOC 解决了类与类之间的依赖关系。将控制类与类之间依赖的权利交给了IOC
3. IOC 的原理是什么?
其实 IOC 的原理很简单,底层就是java的反射。给定一个字符串能创建一个实例,利用set方法对实例的依赖进行注入。
public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException,
InstantiationException, NoSuchMethodException, InvocationTargetException {
String className="com.bean.User";
Class clazz = Class.forName(className);
User user = (User)clazz.newInstance();
Method method = clazz.getMethod("setTest", String.class);
method.invoke(user,"hello");
user.work();
}
在真正的开发中,我们只需要在配置文件给定一个类名字符串,就什么都不用管了,对象就会创建出来,系统启动完毕之后,我们只需要直接使用该对象就好了,不必自己去new。解决了我们的对象创建问题。我们通过反射调用该方法的setText方法,完成了依赖注入。我们不再需要去new,然后去set,IOC 已经为我们做好了一切。
- BeanFactory:这是IOC容器的接口定义,如果将IOC容器定位为一个水桶,那么BeanFactory 就定义了水桶的基本功能,能装水,有把手。这是最基本的,他的实现类可以拓展水桶的功能。
- ApplicationContext:这是我们最常见的,上面我们说水桶,BeanFactory是最基本的水桶,而 ApplicationContext 则是扩展后的水桶,它通过继承 MessageSource,ResourceLoader,ApplicationEventPublisher 接口,在BeanFactory 简单IOC容器的基础上添加了许多对高级容器的支持。
- BeanDefinition:我们知道,每个bean都有自己的信息,各个属性,类名,类型,是否单例,这些都是bena的信息,spring中如何管理bean的信息呢?对,就是 BeanDefinition, Spring通过定义 BeanDefinition 来管理基于Spring的应用中的各种对象以及他们直接的相互依赖关系。BeanDefinition 抽象了我们对 Bean的定义,是让容器起作用的主要数据类型。对 IOC 容器来说,BeanDefinition 就是对依赖反转模式中管理的对象依赖关系的数据抽象。也是容器实现依赖反转功能的核心数据结构。
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// 为刷新准备上下文
prepareRefresh();
// 告诉子类刷新内部的bean工厂,在子类中启动refreshBeanFactoty的地方,创建bean工厂,根据配置生成bean的定义
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 在本上下文中可以使用beanFactory
prepareBeanFactory(beanFactory);
try {
// beanFactory的后置处理器
postProcessBeanFactory(beanFactory);
// 调用beanFactory的后置处理器,在bean定义中,向容器注册
invokeBeanFactoryPostProcessors(beanFactory);
// 后置处理器注册
registerBeanPostProcessors(beanFactory);
// 对上线web的消息源进行初始化
initMessageSource();
// 初始化上下文中的事件机制
initApplicationEventMulticaster();
// 初始化其它特殊的bean
onRefresh();
// 检查监听Bean并且将这些bean向容器注册
registerListeners();
// 实例化所有的non-lazy-init
finishBeanFactoryInitialization(beanFactory);
// 发布容器事件,结束refresh过程 Last step: publish corresponding event.
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// 为防止bean资源占用,在异常处理中,销毁已经在前面过程中生成的单件bean
destroyBeans();
// 重置“active”标志
cancelRefresh(ex);
throw ex;
}
finally {
resetCommonCaches();
}
}
}
- 构建BeanFactory,以便于产生所需的 Bean。
- 注册可能感兴趣的事件。
- 常见Bean实例对象。
- 触发被监听的事件。
@Override
protected final void refreshBeanFactory() throws BeansException {
//如果存在,就销毁
if (hasBeanFactory()) {
destroyBeans();
closeBeanFactory();
}
try {
//重新创建
DefaultListableBeanFactory beanFactory = createBeanFactory();
//序列化
beanFactory.setSerializationId(getId());
// 定制的BeanFactory
customizeBeanFactory(beanFactory);
// 使用BeanFactory加载bean定义 AbstractXmlApplicationContext
loadBeanDefinitions(beanFactory);
synchronized (this.beanFactoryMonitor) {
this.beanFactory = beanFactory;
}
}
catch (IOException ex) {
throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
}
}
- 资源(Resource)定位;
- BeanDefinition 的载入和 BeanFactory 的构造.
- 想 IOC 容器(BeanFactory)注册 BeanDefinition.
- 根据 lazy-init 属性初始化 Bean 实例和依赖注入.
IOC的自定义实现:
下一篇: 二、Spring IoC
推荐阅读
-
Spring Cloud动态配置实现原理与源码分析
-
[Spring cloud 一步步实现广告系统] 16. 增量索引实现以及投送数据到MQ(kafka)
-
Spring Cloud动态配置实现原理与源码分析
-
spring AOP的After增强实现方法实例分析
-
spring AOP的Around增强实现方法分析
-
spring-data-jpa实现增删改查以及分页操作方法
-
Spring源码分析之IoC容器初始化
-
详解Spring IOC 容器启动流程分析
-
深入源码分析Spring注解的实现原理---@Import
-
[Spring cloud 一步步实现广告系统] 16. 增量索引实现以及投送数据到MQ(kafka)