spring IOC 和三种依赖注入方式 (通俗易懂,快速了解)
IOC 就是 控制反转,也就是实现依赖于抽象,而不是抽象依赖于实现
怎么去理解上面这段话呢。直接举例子让大家感受一下。首先我写一个业务,需要从sql 数据库获取数据
然后执行业务代码返回的例子
理解IOC例子
抽象依赖于实现
基础层
public class SqlDB {
public void getsql(){
System.out.println("从sql 获取数据");
}
}
业务层
public class Busines {
private SqlDB sqlDB=new SqlDB();
public void getData(){
//需要拿到sql 的数据
sqlDB.getsql();
//拿到数据做后面的操作
System.out.println("进行数据返回前端");
}
}
测试类
public class Test {
public static void main(String[] args) {
Busines busines = new Busines();
busines.getData();
}
}
从上面可以看出 Busines 类依赖于 sqlDB 类
万一这时候公司的业务发生改变,不用sql 要从其他数据库 ,比如Oracle 获取数据库,这样上面的代码就就不适用了,此时应该怎么办呢?
按照上面,肯定需要修改业务层代码
按上面代码只能这样改
首先增加一个类
public class OracleDB {
public void getOracle(){
System.out.println("从oracle 获取数据");
}
}
最后要修改业务类
public class Busines {
//private SqlDB sqlDB=new SqlDB();
private OracleDB oracleDB=new OracleDB();
public void getData(){
//需要拿到sql 的数据
//sqlDB.getsql();
oracleDB.getOracle();
//拿到数据做后面的操作
System.out.println("进行数据返回前端");
}
}
这样如果,再换一种数据库,又不适用了
实现依赖于抽象(IOC)
public interface DB {
public void getData();
}
public class SqlDB implements DB{
@Override
public void getData() {
System.out.println("从sql 获取数据库");
}
}
public class OracleDB implements DB {
@Override
public void getData() {
System.out.println("从oracle 获取数据");
}
}
public class Busines {
private DB db;
public void setDb(DB db) {
this.db = db;
}
public void getData(){
//需要拿到各种sql 的数据
db.getData();
//拿到数据做后面的操作
System.out.println("进行数据返回前端");
}
}
public class Test {
public static void main(String[] args) {
Busines busines = new Busines();
SqlDB sqlDB = new SqlDB();
OracleDB oracleDB = new OracleDB();
// busines.setDb(oracleDB);
busines.setDb(sqlDB);
busines.getData();
}
}
可以看到,上面的代码如果你要想要增加一个其他渠道获取数据库的类,只需要增加,就可以了,不用改业务代码,
这就是反转**,实现要依赖于抽象**
依赖注入的三种方式
接着上面写过的代码
接口注入
添加一个接口类,通过接口的参数注入
public interface IBusines {
public void crateDB(DB db);
}
public class Busines implements IBusines {
private DB db;
@Override
public void crateDB(DB db) {
this.db=db;
}
public void getData(){
//需要拿到各种sql 的数据
db.getData();
//拿到数据做后面的操作
System.out.println("进行数据返回前端");
}
}
public class Test {
public static void main(String[] args) {
Busines busines = new Busines();
SqlDB sqlDB = new SqlDB();
OracleDB oracleDB = new OracleDB();
// busines.crateDB(oracleDB);
busines.crateDB(sqlDB);
busines.getData();
}
}
set方法 注入
通过set方法进行注入属性
public class Busines {
private DB db;
public void setDb(DB db) {
this.db = db;
}
public void getData(){
//需要拿到各种sql 的数据
db.getData();
//拿到数据做后面的操作
System.out.println("进行数据返回前端");
}
}
上面例子就是set 方式去注入的
构造方法注入
也是拿上面的例子,无非从set 方法换成构造器注入
public class Busines {
private DB db;
public Busines(DB db) {
this.db = db;
}
public void getData(){
//需要拿到各种sql 的数据
db.getData();
//拿到数据做后面的操作
System.out.println("进行数据返回前端");
}
}
public class Test {
public static void main(String[] args) {
SqlDB sqlDB = new SqlDB();
OracleDB oracleDB = new OracleDB();
// busines.crateDB(oracleDB);
Busines busines = new Busines(sqlDB);
busines.getData();
}
}