一、Spring的核心和设计思想
1、Spring是什么?
Spring 是指 Spring Famework (Spring 框架),他是一个开源的 Java 开发框架,旨在简单化企业应用程序发开。
概括一下就是
Spring 是包含了众多工具方法的 IoC 容器。
1.1 什么是 IoC?
IoC : Inversion of Control ------控制反转。先解释一下单纯的 IoC 是一种设计思想,不是一种工具。它于降低程序的耦合度,提高代码的灵活性和可维护性。且 IoC 是Spring的核心思想,是难点,也是重点。
字都认识,放到一起就很抽象。直接举例子
1.1.1 传统程序开发
假设我们要制造一台汽车,我们简化一下流程,造汽车需要车身,车身需要地盘,地盘需要轮胎,是这么个依赖关系。
那么用程序应该怎么写出来呢。可以这样写
java
public class CarExample {
public static void main(String[] args) {
Car car = new Car();
}
}
//汽车
class Car {
private Body body;
public Car() {
body = new Body();
}
}
//车身
class Body {
private Bottom bottom;
public Body() {
bottom = new Bottom();
}
}
//底盘
class Bottom {
private Tire tire;
public Bottom() {
tire = new Tire();
}
}
//轮胎
class Tire {
//轮胎类型
private String type = "雪地胎";
public Tire() {
System.out.println(type);
}
}
肯定有同志是和我写的一样,尤其是在刚学代码的时候。然后就会发现,我想修改一下轮胎的类型是很困难的,必须将所有类种都添加一下type这个属性,然后在创建Car的时候传过去。修改后如下面代码
java
public class CarExample {
public static void main(String[] args) {
Car car = new Car("雪地胎");
}
}
//汽车
class Car {
private Body body;
public Car(String type) {
body = new Body(type);
}
}
//车身
class Body {
private Bottom bottom;
public Body(String type) {
bottom = new Bottom(type);
}
}
//底盘
class Bottom {
private Tire tire;
public Bottom(String type) {
tire = new Tire(type);
}
}
//轮胎
class Tire {
//轮胎类型
private String type;
public Tire(String type) {
this.type = type;
System.out.println(type);
}
}
这就是高耦合,就是牵一发而动全身。IoC 的思想就是降低耦合。实现控制反转就能降低耦合,上面的代码是我们在创建汽车的时候需要同时 创建车身,创建车身又需同时 创建底盘......其实这个同时也代表他们之间的依赖程度很高,那么我们怎么实现控制反转呢?
不同时可不可以?车身是依赖于地盘,我必须先造出车身才能造地盘?我就一身反骨,先造地盘,再造车身,制作出来先放那呗,你用你就过来拿。所以我们修改此处的代码,将制作零件这部分代码提出来放到外面,我想什么时候制作就什么时候制作,你要用,我就给你不就完事了。
1.1.2 IoC思想实现程序开发
java
public class CarExample {
public static void main(String[] args) {
//创建完放着,用的时候直接传
Tire tire = new Tire("普通胎");
Bottom bottom = new Bottom(tire);
Body body = new Body(bottom);
Car car = new Car(body);
}
}
//汽车
class Car {
private Body body;
public Car(Body body) {
this.body = body;
}
}
//车身
class Body {
private Bottom bottom;
public Body(Bottom bottom) {
this.bottom = bottom;
}
}
//底盘
class Bottom {
private Tire tire;
public Bottom(Tire tire) {
this.tire = tire;
}
}
//轮胎
class Tire {
//轮胎类型
private String type;
public Tire(String type) {
this.type = type;
System.out.println(type);
}
}
如上代码,我们将造零件的步骤全部移到外面,这样如果我们想再给轮胎加一个尺寸的时候,直接修改一个类就好,并不会影响到其他的类。这就是控制反转。
总结一下传统程序开发和IoC思想实现的程序开发,如下图
1.2 讲解Spring IoC、DI
在文章开头就说了,Spring 是包含了众多工具方法的 IoC 容器 。我们先理解 Spring 是 IoC 容器这段话,一个容器的作用就是能放东西,还能取出来。所以学习Spring IoC就是学习如何将对象
放入其中,然后再取出来,这个对象就叫做 Bean
,那如何放进去呢?这个放入其实就是配置xml文件,将你需要的库写入其中就可以了(后面细讲)。
这时候就有同志问了,听起来和 Java 差不多啊,都是调用库中的对象。其实不然, Java 中的对象都是管理员手动实例化的,也就是new一个对象。但是在 Spring IoC 就不同了,它不需要你进行实例化,你是需要将依赖关系写好,对象实例化这件事是由他来自动完成的,不需要管理员手动进行new对象。
拿我们上面的代码举例子
java
public class CarExample {
public static void main(String[] args) {
//创建完放着,用的时候直接传
Tire tire = new Tire("普通胎");
Bottom bottom = new Bottom(tire);
Body body = new Body(bottom);
Car car = new Car(body);
}
}
//汽车
class Car {
private Body body;
public Car(Body body) {
this.body = body;
}
}
//车身
class Body {
private Bottom bottom;
public Body(Bottom bottom) {
this.bottom = bottom;
}
}
//底盘
class Bottom {
private Tire tire;
public Bottom(Tire tire) {
this.tire = tire;
}
}
//轮胎
class Tire {
//轮胎类型
private String type;
public Tire(String type) {
this.type = type;
System.out.println(type);
}
}
这个代码中main函数中的对象都是我们自己实例化的,而如果使用Spring,main函数可以怎么写呢?
我先叠甲,下面写的都是部分代码,为了更直观的表达意思。
此时如果我们Spring容器中已经有上述的所有对象(Car、Body......)
java
public static void main(String[] args) {
// 创建Spring容器
ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
// 从容器中获取Car实例
Car car = context.getBean(Car.class);
}
就不需要再创建那么多对象了,为什么?因为依赖注入(Dependency Injection,DI), Car car = context.getBean(Car.class);这行代码执行的时候,会先得到Car对象,Car类依赖的是Body对象,所以当执行到Car类中的private Body body;这行代码,DI 就会自动的从框架中取出Body对象,然后赋值给body。bottom、tire都是同理,这就是依赖注入。
这时候再说它的定义:在代码执行时,将依赖的某个对象注入到其中。
大白话再讲一遍:我需要这个对象,你把他从容器中拿给我。
这里为什么要强调你,因为这件事不需要我们做,是DI帮我们做的。
所以IoC和DI是绑定在一起的,只有两个同时存在,才能实现这件事。