Spring核心思想
# Spring 核心思想
Spring的核心思想:IoC & AOP。IoC和AOP不是Spring提出的,在Spring之前就已经存在,只不过更偏向于理论化的思想,Spring在技 术层次把这两个思想做了⾮常好的实现(Java).
# IoC
IOC,Inversion of Control,控制反转是一个概念,是一种思想。指将传统上由程序代码直接操控的对象调用权交给容器,通过容器来实现对对象的装配和管理。即对象控制权的转移,从程序代码本身反转到了外部容器,主要解决开发领域对象的创建,管理的问题。
传统开发⽅式:⽐如类A依赖于类B,往往会在类A中new⼀个B的对象。而IoC思想下的开发⽅式:我们不⽤⾃⼰去new对象了,⽽是由IoC容器(Spring框架)去帮助我们实例化对象并且管理它,当我们需要使⽤哪个对象,去问IoC容器要即可。IoC解决对象之间的耦合问题。
为什么叫做控制反转?
- 控制:指的是对象实例化、管理的权利
- 反转:控制权交给外部环境(Spring框架、IoC容器)
# IoC的实现
IOC的实现方式多种多样。当前比较流行的实现方式有两种:依赖注入和依赖查找。
- 依赖查找:Dependency Lookup,DL,容器提供回调接口和上下文环境给组件,程序代码则需要提供具体的查找方式。比较典型的是依赖于JNDI系统的查找。
- 依赖注入:Dependency Injection,DI,程序代码不做定位查询,这些工作由容器自行完成。即在程序运行过程中,若需要调用另一个对象协助时,无须在代码中创建被调用者,而是依赖于外部容器,由外部容器创建后传递给程序。
DI是目前最优秀的解耦方式。依赖注入让Spring的Bean之间以配置文件的方式组织在一起,而不是以硬编码的方式耦合在一起。
# IoC和DI的区别
从上面的描述,我们可以发现IoC和DI描述的是同⼀件事情:对象实例化和依赖关系维护,只不过⻆度不⼀样。
- IoC是站在对象的角度,对象实例化及其管理的权利交给了IoC容器。
- DI是站在了容器的角度,容器会把对象依赖的其他对象注入,比如A对象实例化过程中因为声明了一个B类型的属性,那么容器会把B对象注入给A。
# AOP
AOP,Aspect oriented Programming,⾯向切⾯编程。AOP是OOP((Object Oriented Programming,面向对象编程)的延续。
OOP是⼀种垂直继承体系,它的三大特征是封装、继承和多态。例如:
它能够解决⼤多数的代码重复问题,但是有⼀些情况是处理不了的,⽐如下⾯的在顶级⽗类Animal中的多个⽅法中相同位置出现了重复代码,OOP就解决不了:
public class Animal {
private String height;
private float weight;
public void eat(){
// 性能监控代码
long start = System.currentTimeMillis();
// 业务逻辑代码
System.out.println("I can eat...");
// 性能监控代码
long end = System.currentTimeMillis();
System.out.printf("执行时长:%ss%n", (end - start) / 1000f);
}
public void run(){
// 性能监控代码
long start = System.currentTimeMillis();
// 业务逻辑代码
System.out.println("I can run...");
// 性能监控代码
long end = System.currentTimeMillis();
System.out.printf("执行时长:%ss%n", (end - start) / 1000f);
}
}
# 横切逻辑代码
性能监控的代码在多个纵向流程出现相同的代码,我们称之为横切逻辑代码:
横切逻辑代码使用场景通常很有限,一般是事务控制、权限校验、日志。横切逻辑代码有两点问题:
- 逻辑不纯净。横切代码与业务逻辑代码混杂,代码臃肿,不方便维护。
- 横切逻辑代码重复,没有完全剥离出来做到复用。
我们可以把日志、安全、事务管理等服务理解成一个切面,如果这些服务之前是直接写在业务逻辑代码中的,可以完全剥离出来做到复用。AOP就是这些问题的解决方案,可以把这些服务剥离出来形成一个切面,以期复用,然后将“切面”动态的“织入”到业务逻辑中,让业务逻辑能够享受到此“切面”的服务。
从这里可以看出AOP解决的问题是:在不改变原有业务逻辑情况下,增强横切逻辑代码,根本上解耦合,避免横切逻辑代码重复。
# 为什么叫做⾯向切⾯编程?
- 「切」:指的是横切逻辑,原有业务逻辑代码我们不能动,只能操作横切逻辑代码,所以可以理解叫⾯向横切逻辑。
- 「⾯」:横切逻辑代码往往要影响的是很多个⽅法,每⼀个⽅法都如同⼀个点,多个点构成⾯。