IoC&DI入门
Spring是什么?
Spring是⼀个开源框架,它让我们的开发更加简单.它⽀持⼴泛的应⽤场景,有着活跃⽽庞⼤的社区,这也是Spring能够⻓久不衰的原因.但是这个概念说起来还是比较抽象的.⽤⼀句更具体的话来概括Spring,那就是:Spring是包含了众多工具方法的IoC容器.
那么,什么是容器?什么是IoC容器?
什么是容器?
容器是⽤来容纳某种物品的(基本)装置 ⸺来⾃:百度百科
⽣活中的⽔杯,垃圾桶,冰箱等等这些都是容器.
我们想想,之前课程我们接触的容器有哪些?
List/Map -> 数据存储容器
Tomcat -> Web容器
什么是IoC?
IoC是Spring的核心思想.
其实IoC我们在前⾯已经使⽤了,我们在前⾯讲到,在类上⾯添加@RestController 和
@Controller 注解,就是把这个对象交给Spring管理,Spring框架启动时就会加载该类.把对象交给Spring管理,就是IoC思想.
IoC:Inversion of Control(控制反转),也就是说Spring是⼀个"控制反转"的容器.这里的控制指控制权,比如对象的创建权,原先是掌握在开发者手中,想让对象在哪里创建就在那里创建,IoC就是将这些权力交给Spring处理,如何创建对象由Spring掌控.
IoC介绍
接下来通过一个案例来了解什么是Ioc.
传统程序开发
制造一辆汽车:先设计轮⼦(Tire),然后根据轮⼦的⼤⼩设计底盘(Bottom),接着根据底盘设计⻋⾝(Framework),最后根据车身设计好整个汽⻋(Car)。这⾥就出现了⼀个"依赖"关系:汽⻋依赖⻋⾝,⻋⾝依赖底盘,底盘依赖轮⼦.代码如下:
public class Main {
public static void main(String[] args) {
Car car = new Car(17);
car.run();
}
}
public class Car {
private Framework framework;
public Car(int size) {
framework = new Framework(size);
System.out.println("Car init....");
}
public void run() {
System.out.println("Car run...");
}
}
public class Framework {
private Bottom bottom;
public Framework(int size) {
bottom = new Bottom(size);
System.out.println("Framework init...");
}
}
public class Bottom {
private Tire tire;
public Bottom(int size){
tire = new Tire(size);
System.out.println("Bottom init...");
}
}
public class Tire {
private int size;
private String color;
public Tire(int size){
this.size = size;
System.out.println("轮胎尺寸:"+size);
}
}
这样的代码维护性较低,当用户需要自定义更多的属性时,在修改代码时就要修改多处.当最底层代码改动之后,整个调⽤链上的所有代码都需要修改.
这样的程序耦合度非常的高.
解决方案
先设计汽⻋的⼤概样⼦,然后根据汽⻋的样⼦来设计⻋⾝,根据⻋⾝来设计底盘,最后根据底盘来设计轮⼦.这时候,依赖关系就倒置过来了:轮⼦依赖底盘,底盘依赖⻋⾝,⻋⾝依赖汽⻋.
我们可以尝试不在每个类中⾃⼰创建下级类,如果⾃⼰创建下级类就会出现当下级类发⽣改变操作,自己也要跟着修改.此时,我们只需要将原来由⾃⼰创建的下级类,改为传递的⽅式(也就是注⼊的⽅式),因为我们不需要在当前类中创建下级类了,所以下级类即使发⽣变化(创建或减少参数),当前类本⾝也⽆需修改任何代码,这样就完成了程序的解耦.
public class Main {
public static void main(String[] args) {
//不在每个类中创建自己的下级类
//改为传递下级类
Tire tire = new Tire(17);
Bottom bottom = new Bottom(tire);
Framework framework = new Framework(bottom);
Car car = new Car(framework);
car.run();
}
}
public class Car {
private Framework framework;
public Car(Framework framework) {
this.framework = framework;
System.out.println("Car init....");
}
public void run() {
System.out.println("Car run...");
}
}
public class Framework {
private Bottom bottom;
public Framework(Bottom bottom) {
this.bottom = bottom;
System.out.println("Framework init...");
}
}
public class Bottom {
private Tire tire;
public Bottom(Tire tire){
this.tire = tire;
System.out.println("Bottom init...");
}
}
public class Tire {
private int size;
private String color;
public Tire(int size){
this.size = size;
System.out.println("轮胎尺寸:"+size);
}
}
代码经过以上调整,⽆论底层类如何变化,整个调⽤链是不⽤做任何改变的,这样就完成了代码之间的解耦,从⽽实现了更加灵活,通⽤的程序设计了.
Ioc的优势
在传统的代码中对象创建顺序是:Car->Framework->Bottom->Tire
改进之后解耦的代码的对象创建顺序是:Tire->Bottom->Framework->Car
通⽤程序的实现代码,类的创建顺序是反的,改进之后的代码,控制权发生了反转,不再是使用方创建并依赖对象了,而是把依赖对象注入到当前对象中,依赖对象的控制权不再由当前类控制了.
这样,即使依赖对象发送了如何的变化,当前类都是不受影响的.
IoC具有以下优点:
1.资源集中管理:IoC容器会帮我们管理⼀些资源(对象等),我们需要使⽤时,只需要从IoC容器中去取就可以了.
2.我们在创建实例的时候不需要了解其中的细节,降低了使⽤资源双⽅的依赖程度,也就是耦合度.
Spring就是一种IoC容器,帮助我们完成资源的管理.
DI介绍
DI:Dependency Injection(依赖注⼊).
容器在运⾏期间,动态的为应⽤程序提供运⾏时所依赖的资源,称之为依赖注⼊.
上述解决方案中的代码就是通过构造函数的⽅式,把依赖对象注⼊到需要使⽤的对象中的.
IoC&DI的使用
在前面的Spring MVC的学习中,已经使用到了Spring的IoC&DI.例如,向页面展示Hello Spring.
@RestController
public class Hello {
// 此处/hello用于访问
@RequestMapping("/hello")
public String hello(){
return "Hello Spring";
}
}
我们没有创建Hello类的对象,也没有调用这个对象的hello方法,但是执行项目并访问后就是可以得到Hello Spring的结果.
Spring是一个IoC容器,Spring容器管理的主要是对象,由Spring来负责对象的创建和销毁.我们程序只需要告诉Spring,哪些需要存,以及如何从Spring中取出对象.
表示类交由Spring管理,使用注解@Controller或@Component.
表示对象的注入交由Spring管理,使用注解@Autowired
@Component修饰类,将这个类的对象的创建于销毁交由Spring管理.
@Component
//dao表示数据层 与数据库交互
public class BookDao {
public List<BookInfo> mockData(){
List<BookInfo> bookInfos = new ArrayList<>();
for (int i = 1; i <= 15; i++) {
BookInfo book = new BookInfo();
book.setId(i);
book.setBookName("图书"+i);
book.setAuthor("佚名");
book.setCount(2 * i + 1);
book.setPrice(new BigDecimal(2.5 * i + 2));
book.setPublish("xx出版社");
if(i % 4 == 0){
book.setStatus(2);
}else {
book.setStatus(1);
}
bookInfos.add(book);
}
return bookInfos;
}
}
@Autowired修饰对象,这个对象的注入交由Spring管理.
@Autowired
private BookDao bookDao;
6470

被折叠的 条评论
为什么被折叠?



