IOC是Spring核心思想
关键字
控制反转、工厂模式、建造者模式、DI依赖注入、解耦、XML、反射、Spring-beans.jar、Spring-context.jar
控制反转
spring将java 对象的创建权交由spring框架管理
工厂模式
将对象的创建交由Factory类创建对象,主要思想,将实现同一个接口或继承同一个类的类对象交由工厂类创建。
建造者模式
将复杂类的创建权交由bulider类
通过接口和多态思想进行动态创建
创建的返回类型是继承了统一对象类型
创建的工厂类实现了同一个接口。根据实际需求返回对象
DI依赖注入
构造函数注入、属性注入、接口注入
不在关注对象的创建、实现动态的将依赖对象注入到Bean组件
spring通过容器完成依赖关系的注入
解耦
IOC的核心就是解耦,将对象的关系变得不再紧密可言,具有更强的扩展性
减少依赖度
耦合是指两个或两个以上的体系或两种运动形式间通过相互作用而彼此影响以至联合起来的现象。
反射
通过ClassLoader类加载器创建对象
ClassLoader loader = Thread.currentThread().getContextClassLoader();
Class clazz = loader.loaderClass("java.util.HashMap");
Object obj = clazz.newInstance();
Field field = clazz.getDeclaredField("param");
field.setAccessible(true);
field.set(obj, "");
XML技术
Spring-beans.jar
AbstractBeanFactory:BeanFactory接口的抽象实现类,提供了ConfigurableBeanFactory完整SPI。通过DefultSingletonBeanRegistry实现了单例缓存(singleton
cache).实现了通过FactoryBean判断bean类型(singleton/prototype)功能,处理,别名和合并bean
definition功能,创建,获取和销毁bean对象功能,内部应用了parentBeanFactory对象,实现了BeanFactory的双亲委派结构。
核心方法:
1、createBean
整体流程如下:
resloveBeanClass具体实现:返回RootBeanDefinition对象的beanClass属性或者其他的classloader根据RootBeanDefinition对象的beanClassName属性解析出的Class<?>
resloveBeforeInstantiation具体实现:遍历beanFactory对象的beanPostProcessors列表两次,对当前bean分别递归调用beanPostProcessor接口的postProcessBeforeInstantiation(转化为InstantiationAwareBeanPostProcessor类型)和 postProcessAfterInitialization方法(上一次接口调用的返回值作为下一次接口调用的请求)
doCreateBean具体实现:
createBeanInstance具体实现如下:
-
如果RootBeanDefinition对象定义了instanceSupplier属性,返回instanceSupplier.get()
-
如果RootBeanDefinition对象的factoryMethodName属性不为空,返回通过factoryMethod方法构造的实例
-
如果RootBeanDefinition对象的resolvedConstructorOrFactoryMethod属性不为空,返回通过特定方式构造的实例
-
遍历beanPostProcessor(转化为SmartInstantiationAwareBeanPostProcessor)列表,使用determineCandidateConstructors(beanClass, beanName)获取特定构造器,返回特定构造器返回的实例
-
返回无参构造器
AbstractApplicationContext:
org.springframework.context.ApplicationContext接口的抽象实现,用于创建或者刷新IOC容器
核心方法:
1. refresh
创建或者刷新IOC容器
执行流程如下:
1.1 prepareBeanFactory详解
流程如下:
1.2 invokeBeanFactoryPostProcessors详解
流程如下:
备注:如果beanFactory是BeanDefinitionRegistry类型的话,在beanFactoryPostProcessors和beanFactory查找BeanDefinitionRegistryPostProcessor类型,并执行相应方法
1.3 登记ApplicationListener对象
ApplicationListener类型UML结构图如下:
类型名 | 描述 | 具体实现 |
---|---|---|
ContextRefreshListener | 只接收WebApplicationContext发出的消息,提供了扩展点供子类使用 | 委托给FrameworkServlet对象调用onApplicationEvent方法 |
ApplicationListenerMethodTransactionalAdapter | 调用添加了TransactionalEventListener注解的spring bean对象方法(提供了如何实现灵活调用系统扩展点的思路) | |
ApplicationListenerMethodAdapter | 调用添加了EventListener注解的spring bean对象方法 | |
GenericApplicationListenerAdapter | 代理模式实现事件类型和监听器匹配 |
1.4 初始化BeanFactory中定义的singleton对象
AbstractRefreshableApplicationContext:默认使用DefaultListableBeanFactory类型
AbstractRefreshableWebApplicationContext:面向web环境的ApplicationContext,主要涉及到ServletContext和ServletConfig
ServletContextAwareProcessor:
备注:将bean转换为ServletContextAware类型,并设置对应ServletContext和ServletConfig参数XmlWebApplicationContext:使用xml配置加载bean对象
笔记
通过ClassPathXmlApplicationContext 创建的对象,可以使用别名获取对象或则使用class对象创建,但是都会使用xml中的配置文件进行创建
Spring-context.jar
核心类
ClassPathXmlApplicationContext.class
1、简单的用 ApplicationContext 做测试的话 , 获得 Spring 中定义的 Bean 实例(对象) 可以用:
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
2、如果是两个以上 , 可以使用字符串数组 :
ApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"applicationContext.xml","SpringTest.xml"});
3、使用通配符
ApplicationContext context = new ClassPathXmlApplicationContext("classpath:/*.xml");
对于 ClassPathXmlApplicationContext 的使用:
classpath: 前缀是可加可不加的 , 默认就是指项目的 classpath 路径下面。 如果要使用绝对路径 , 需要加上 " file: ", 前缀表示这是绝对路径。 对于 FileSystemXmlApplicationContext 的使用:
没有盘符的是项目工作路径 , 即项目的根目录。 有盘符表示的是文件绝对路径 ,file: 可加可不加。 如果要使用 classpath 路径
, 需要前缀 classpath:。