Spring中IOC(控制反转)的理解
Spring中的IOC(控制反转)
先不讲IOC,
我们先通过发现问题,然后使用工厂模式解决问题,最后到IOC
示例:
分析jdbc的两种注册驱动的方式,比较两种方式哪种更适合实际的开发
DriverManager.registerDriver(new com.mysql.cj.jdbc.Driver);
Class.forName("com.mysql.cj.jdbc.Driver");
第一种方式,我们为了注册驱动,new了一个Driver实例
第二种方式,利用反射技术,通过一个字符串创建了一个实例
这个时候,如果我们的项目换了一个数据库,这时就要换一个驱动,对于这两个注册驱动的方式来看,一种需要我们更换new的对象,第二种方式,我们只是修改了字符串,如果对第二种方式再次改进,把字符串(指的就是类的全限定名)写到一个配置文件中,那么让程序读取配置文件就可以知道去创建哪个对象。如果我们需要更换数据库,就可以直接修改配置文件,从而避免了对源代码的修改
结论:在我们使用一些不需要被频繁创建的对象时,采用反射的方式创建对象显然更加合理,当我们这个对象需要更换时,就可以在不修改源代码的基础上,通过配置文件做出对应的改变
解耦的必要性
解除耦合:解除依赖关系,但是在一个程序的开发中,两个模块协同完成工作,必然会产生耦合,发生依赖关系,如果真的把两个模块的依赖关系切断了,那么也就不存在共同工作了,所以这里的解耦是让两个模块之间的耦合性降低。
实际开发中,低耦合性是最基本的要求,可以让我们开发的功能独立性提高,增加了模块的复用性,同时,降低了后期维护的成本
高内聚,低耦合
现在无处不提到“低耦合、高内聚”,它已经成为软件设计质量的标准之一。
- 内聚标志一个模块各个元素彼此结合的紧密程度,它是信息隐藏和局部化概念的自然扩展。主要是指的功能内聚,每一个元素只完成它职责内的事情,其他的事情都交给别人来完成,这就是高内聚的元素
- 低耦合就是模块之间的依赖关系变低,当一个模块需要被更换之后,不会牵连其他模块的更换,新换的模块可以继续和其他模块一起工作,就是一个良好的低耦合的项目
工厂模式
工厂模式使我们最长的用的一个实例化对象的模式,
我们现在使用工厂模式,自己写一个为了解除耦合关系的简单案例
创建一个持久层的Dao(模拟)
public class UserDaoImpl implements IUserDao {
@Override
public void save() {
System.out.println("向数据库中添加一条用户信息");
}
}
创建一个业务层,他需要处理业务,然后调用Dao层将数据进行持久化存储。
public class UserServiceImpl implements IUserService {
private IUserDao userDao;
@Override
public void add() {
System.out.println("处理业务,存储数据");
userDao = (IUserDao) BeanFactory.getBean("UserDao");
userDao.save();
}
}
创建一个beans.xml文件,将我们的类的信息放在xml文件中
<?xml version="1.0" encoding="UTF-8" ?>
<beans>
<bean id="UserDao" class="com.zxy.dao.impl.UserDaoImpl"/>
<bean id="UserService" class="com.zxy.service.impl.UserServiceImpl"/>
</beans>
我们使用dom4j来解析xml文件(Spring也是使用dom4j来解析XML文件的)
<!-- https://mvnrepository.com/artifact/dom4j/dom4j -->
<dependency>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>1.6.1</version>
</dependency>
创建一个工厂,用来创建对象,它会解析xml文件,根据配置信息创建所有的对象
public class BeanFactory {
private static Map<String,Object> beanMap = new HashMap<>();
static {
SAXReader reader = new SAXReader();
try {
Document document = reader.read(BeanFactory.class.getClassLoader().getResourceAsStream("beans.xml"));
//获取根节点:beans
Element rootElement = document.getRootElement();
//获取根节点下的所有子节点
List<Element> elementList = rootElement.elements();
//遍历标签中的信息,使用利用反射创建对象,放在beanMap中
for (Element element : elementList){
String idValue = element.attributeValue("id");
String classValue = element.attributeValue("class");
Class clazz = Class.forName(classValue);
Object obj = clazz.getDeclaredConstructor().newInstance();
beanMap.put(idValue,obj);
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static Object getBean(String id){
return beanMap.get(id);
}
}
运行测试类:
@Test
public void test1(){
IUserService userService= (IUserService) BeanFactory.getBean("UserService");
userService.add();
}
体会上面简单的例子,其实Spring在实现IOC时,也是使用的这种做法
IOC
IOC(Inversion of Control)控制反转:是一种设计思想,是一个重要的面向对象编程的法则,使用这种思想可以让我们设计出低耦合、更加优良的程序。
IOC是Spring中的核心,它主要的特点就是:调用类中的方法不是通过new它的对象来实现,而是通过Spring配置来创建对象,然后交给IOC容器来管理我们的对象,使用时去找IOC容器要,根本就不用去管我们需要的这个对象时怎么创建的、什么时候被销毁。
这样一来,类和类之间的关系就变弱了,因为我们没有在一个类中new另一个对象,对象之间的调用、联系都是通过这个IOC容器来获取的,使每一个对象都相对比较独立
程序中对象相互合作,发生耦合的情况:
使用IOC解耦后:
解释一下控制反转:
- 从原本我们自己手动控制对象(创建和销毁,对象的生命周期)
- 变成了现在交给IOC容器控制对象(创建和销毁)、我们使用时只需要去容器中获取即可
Spring IOC底层运用的技术包括xml配置文件、dom4j解析xml、工厂设计模式、反射,这四种技术
下一篇Spring IOC的使用 ※
本文地址:https://blog.csdn.net/zxy144/article/details/110250205
上一篇: 机器人真的可以代替人工制造吗?
下一篇: 大数据,改变经济改变生活