一、IoC与DI
名词解释:
- spring是一个装了众多工具对象的IoC容器。
- IoC思想:对象交给Spring管理,就是IoC思想。
- IoC:Inversion of Control,控制反转。
控制权反转,需要某个对象时, 传统开发模式中需要⾃⼰通过 new 创建对象, 现在不需要再进⾏创建, 把创建对象的任务交给容器(IoC容器. Spring是⼀个IoC容器, 所以有时Spring 也称为Spring容器), 程序中只需要依赖注⼊ (Dependency Injection, DI)就可以了.
1.1 IoC
实现下面的需求:
在传统的实现中,我们将每个模块当成一个类:
public class NewCarExample {
public static void main(String[] args) {
Car car = new Car();
car.run();
}
/**
* 汽⻋对象
*/
static class Car {
private Framework framework;
public Car() {
framework = new Framework();
System.out.println("Car init....");
}
public void run(){
System.out.println("Car run...");
}
}
/**
* ⻋⾝类
*/
static class Framework {
private Bottom bottom;
public Framework() {
bottom = new Bottom();
System.out.println("Framework init...");
}
}
/**
* 底盘类
*/
static class Bottom {
private Tire tire;
public Bottom() {
this.tire = new Tire();
System.out.println("Bottom init...");
}
}
/**
* 轮胎类
*/
static class Tire {
// 尺⼨
private int size;
public Tire(){
this.size = 17;
System.out.println("轮胎尺⼨:" + size);
}
}
}
但是如上面的代码,如果我们要修改一个参数,会导致整个调用链都跟着修改。
我们为解决上面耦合度过高,可以采取: 把由⾃⼰创建的下级类,改为传递的⽅式(也就是注⼊的⽅式), 每次调整只需要调整对应那个类的代码即可。 这样⽆论底层类如何变化,整个调⽤链是不⽤做任何改变的。
public class IocCarExample {
public static void main(String[] args) {
Tire tire = new Tire(20);
Bottom bottom = new Bottom(tire);
Framework framework = new Framework(bottom);
Car car = new Car(framework);
car.run();
}
static 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...");
}
}
static class Framework {
private Bottom bottom;
public Framework(Bottom bottom) {
this.bottom = bottom;
System.out.println("Framework init...");
}
}
static class Bottom {
private Tire tire;
public Bottom(Tire tire) {
this.tire = tire;
System.out.println("Bottom init...");
}
}
static class Tire {
private int size;
public Tire(int size) {
this.size = size;
System.out.println("轮胎尺⼨:" + size);
}
}
}
1.2 DI
DI: Dependency Injection(依赖注⼊) 容器在运⾏期间, 动态的为应⽤程序提供运⾏时所依赖的资源,称之为依赖注⼊。
就像上面调用关系中:
二、IoC与DI的使用
Spring 是⼀个 IoC(控制反转)容器,作为容器, 那么它就具备两个最基础的功能: • 存 • 取 Spring 容器 管理的主要是对象, 这些对象, 我们称之为"Bean". 我们把这些对象交由Spring管理, 由 Spring来负责对象的创建和销毁. 我们程序只需要告诉Spring, 哪些需要存, 以及如何从Spring中取出对象
我们实现这样的功能,主要靠两个注解:
- Service层及Dao层的实现类,交给Spring管理: 使⽤注解: @Component
- 在Controller层 和Service层 注⼊运⾏时依赖的对象: 使⽤注解 @Autowired
像把前面的图书管理系统的BookController重构。 BookController类:
package com.example.project.controller;
import com.example.project.model.BookInfo;
import com.example.project.service.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RequestMapping("/book")
@RestController
@Component
public class BookController {
@Autowired
private BookService bookService;
@RequestMapping("/getList")
public List<BookInfo> getList() {
return bookService.getList();
}
}
BookService类:
package com.example.project.service;
import com.example.project.dao.BookDao;
import com.example.project.model.BookInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
@Component
public class BookService {
@Autowired
BookDao bookDao ;
public List<BookInfo> getList() {
List<BookInfo> books = new ArrayList<>();
books = bookDao.mockData();
for (BookInfo book:
books) {
if(book.getStatus() == 1) {
book.setStatusCN("可借阅");
} else {
book.setStatusCN("不可借阅");
}
}
return books;
}
}
BookDao类:
package com.example.project.dao;
import com.example.project.model.BookInfo;
import org.springframework.stereotype.Component;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
@Component
public class BookDao {
public List<BookInfo> mockData() {
List<BookInfo> books = new ArrayList<>();
for (int i = 0; i < 5; i++) {
BookInfo book = new BookInfo();
book.setId(i);
book.setBookName("书籍" + i);
book.setAuthor("作者" + i);
book.setCount(i * 5 + 3);
book.setPrice(new BigDecimal(new Random().nextInt(100)));
book.setPublish("出版社" + i);
book.setStatus(1);
books.add(book);
}
return books;
}
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。