IoC百度解释
控制反转(Inversion of Control,缩写为IoC),是面向对象编程中的一种设计原则,可以用来减低计算机代码之间的耦合度。其中最常见的方式叫做**依赖注入(Dependency Injection,简称DI**),还有一种方式叫“依赖查找”(Dependency Lookup)。通过控制反转,对象在被创建的时候,由一个调控系统内所有对象的外界实体将其所依赖的对象的引用传递给它。也可以说,依赖被注入到对象中。
简单的说:IoC就是将对象的创建与对象之间的调用这一过程交给Sping进行管理。Ioc的目的:降低耦合度。而IoC的底层就是通过xml解析、工厂模式、反射结合使用进行解耦操作。
IoC功能的简单理解
程序设计的重要原则之一是要做到高内聚低耦合,什么是耦合呢?
就是程序之间的依赖程度
例如:
// 1:注册驱动
Class.forName("com.mysql.cj.jdbc.Driver");
// 2:获取连接
Connection conn = DriverManager.getConnection("");
// 3:创建statement对象
Statement statement = conn.createStatement();
// 4:CURD
boolean resultSet = statement.execute("");
CURD依赖Statement对象的创建,Statement对象又依赖Connection连接,获取Connection连接又必须先注册驱动。这就是耦合。
现在我有Dao层与Service层两个模块
Dao:
package dao;
public class UserDao {
public void add(){
System.out.println("UserDao Add方法");
}
}
Service:
package service;
public class UserService {
public void addUser(){
}
}
我要在UserService中调用Dao层中UserDao的add方法,我要怎样调用??
在我还没学习SpringIoC之前,对于这个问题会产生大大疑惑,这不很简单吗,直接new,然后直接调用不就行了吗,然后这样对UserService的改写如下:
package service;
public class UserService {
public void addUser(){
UserDao dao = new UserDao();
dao.add();
}
}
<(^-^)> 嗯,很满意,但是这样写,UserService就会过度依赖于UserDao,存在较高的耦合 。此时就需要设计模式方面的芝士(知识)了。工厂模式,因此代码可以改为:
Dao:
package dao;
public class UserDao {
public void add(){
System.out.println("UserDao Add方法");
}
}
Factory:
package factory;
import dao.UserDao;
public class UserDaoFactory {
public static UserDao getUserDao(){
return new UserDao();
}
}
Service:
package service;
import dao.UserDao;
import factory.UserDaoFactory;
public class UserService {
public void addUser(){
UserDao user = UserDaoFactory.getUserDao();
user.add();
}
}
UserService通过UserDaoFactory创建UserDao实例,从而降低了UserServie与UserDao之间的耦合,这个过程称之为解耦。然而这种方式并不是最优的,因为UserDaoFactory与UserDao又出现了新的耦合。因此引出了IoC解耦
IoC的解耦过程:配置XML---->通过工厂解析XML文件,使用反射生成实例。
因此可以改为:
XML配置文件
<bean id="myIoc" class="dao.UserDao">
</bean>
Dao
package dao;
public class UserDao {
public void add(){
System.out.println("UserDao Add方法");
}
}
Factory
package factory;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import java.io.File;
public class UserDaoFactory {
public static Object getUserDao() {
// 解析XML
SAXReader reader = new SAXReader();
Document document = null;
try {
document = reader.read(new File("src/main/resources/myIoc.xml"));
} catch (DocumentException e) {
e.printStackTrace();
}
Element root = document.getRootElement();
String c = root.attribute("class").getText();
// 反射创建实例
Class clas = null;
try {
clas = Class.forName(c);
return clas.newInstance();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return null;
}
}
Service
package service;
import dao.UserDao;
import factory.UserDaoFactory;
public class UserService {
public void addUser(){
UserDao dao = (UserDao) UserDaoFactory.getUserDao();
dao.add();
}
}
IoC通过XMl与反射,降低了UserDao与UserDaoFactory之间的耦合,使得UserDaoFactory对UserDao的依赖降低,当UserDao发生一些改变,只需改变XML配置文件,而不需要对UserDaoFactory做出改变。
至此,对于IoC有了初步了解。撒花,撒花,真厉害,王水水。。。。。