前言
前几天Spring框架曝出RCE 0day漏洞,可导致远程代码执行 (RCE),使用JDK9及以上版本都有可能受到影响,还好博主用的是稳定的JDK8(JDK8真的是yyds)。本篇文章主要介绍一下spring核心之一的IOC/DI以及他们是如何通过XML和注解的方式实现Bean管理。天不生我小码农,码道万古如长夜,码字不易,感谢支持,当然可能有一些理解不到位的地方,欢迎指正。
一、Spring的核心
Spring是轻量级的开源JavaEE框架,Spring主要用到的设计模式有工厂模式和代理模式,一般而言,工厂模式分为三类:简单工厂模式(Simple Factory)、工厂方法模式(Factory Method)、抽象工厂模式(Abstract Factory)。所有的框架主要用于解耦和快速开发,可以理解为框架=注解+反射+设计模式。Spring 有两个核心部分:IOC和AOP(这也是Spring面试常问的两个东西)。
1、IOC:控制反转,把对象创建和对象之间的调用过程交给Spring进行管理(DI和IOC是同一个概念的不同角度描述,控制反转是一种编程思想,依赖注入是实现控制反转的典型方法或者说DI是IOC的具体实现,DI需要在创建对象的基础上实现,给对象的属性进行赋值)。控制:包括对象的创建,属性的赋值以及对象之间关系的管理。反转:把原来由开发人员创建、管理对象的权限交给第三方即代码之外的spring容器进行实现,在JavaSE中,当我们缺少对象时,我们可以用关键字new一个对象,这也可以称为正转。
2、AOP:面向切面,不修改源代码的情况下增强功能(原理:动态代理技术,设计模式就是代理加装饰器)。
二、Spring的特点
1、方便解耦,简化开发
2、AOP编程支持
3、方便程序的测试(可以使用Junit测试单元)
4、方便和其他优秀的框架进行整合(比如博主以前所写的SSM集成框架,就是Spring集成了Mybatis等优秀框架,当然还有过时的SSH框架:Spring + Struts +Hibernate,以前老会开玩笑说学完春天学冬天,现在也用不上冬天了)
5、方便进行事务的操作
6、降低API的开发难度
三、Spring5的主要内容
博主用的是5.2.5版本的,但官网已经更新到了5.3.18版本了
1、IOC容器
2、AOP
3、jdbcTemplate
4、事务管理
5、Spring 5新特性:Webflux(响应式编程及函数式编程)、函数式注册对象、Nullable注解等。
四、IOC底层
1、IOC底层的技术
IOC思想是基于IOC容器完成的,IOC容器的底层就是Object Factories(对象工厂,工厂顾名思义是用来生产产品的,利用对象工厂,我们创建对象时就可以得到解脱)。IOC底层技术包括xml解析、工厂模式、反射、注解。
2、IOC接口
Spring提供IOC容器的实现有两种方式(两个接口)
BeanFactory:IOC容器的基本实现,是Spring内部的使用接口,不提供开发人员进行使用。加载配置文件时不会创建对象,只有在获取或者使用对象时才去加载对象(懒汉式)。
ApplicationContext:继承了BeanFactory接口,是Beanactory接口的子接口,它提供了更多更强大的功能,一般由开发人员使用,在加载配置文件的时候就会对对象进行创建。(饿汉式)
ApplicationContext接口有实现类,其中有两种是加载配置文件的具体实现类
对比源码会发现两者在前面的代码基本一致,主要是体现在后面加载配置文件的方式上,FileSystemXmlApplicationContext加载绝对路径的配置文件,ClassPathXmlApplicationContext加载类路径的配置文件。
protected Resource getResourceByPath(String path) { if (path.startsWith("/")) { path = path.substring(1); } return new FileSystemResource(path); }
public ClassPathXmlApplicationContext(String path, Class<?> clazz) throws BeansException { this(new String[]{path}, clazz); } public ClassPathXmlApplicationContext(String[] paths, Class<?> clazz) throws BeansException { this(paths, clazz, (ApplicationContext)null); } public ClassPathXmlApplicationContext(String[] paths, Class<?> clazz, @Nullable ApplicationContext parent) throws BeansException { super(parent); Assert.notNull(paths, "Path array must not be null"); Assert.notNull(clazz, "Class argument must not be null"); this.configResources = new Resource[paths.length]; for(int i = 0; i < paths.length; ++i) { this.configResources[i] = new ClassPathResource(paths[i], clazz); } this.refresh(); } @Nullable protected Resource[] getConfigResources() { return this.configResources; }