浅谈Spring如何解耦和IOC

1.传统三层架构耦合性高。
首先来谈一谈传统的web应用三层架构,这样有助于我们理解spring是怎么来降低系统的耦合度的。
如下图所示,web层通过调用相关的service来实现业务逻辑的实现,而service通过DAO层来进行数据的CRUD操作。假设,当前系统使用的是Mysql数据库,突然有一天,老板说要用Oracle数据库,如果使用的是如下开发结果,那么就需要再也一套Oracle的service和DAO,这个时候问题就出现了,两个层级间的耦合性太高,只是修改DAO层里的事情,却连service层也要一起修改,那么要怎么降低耦合性?
聪明的人应该已经想到了,可以让MysqlUserDAO和OracleUserDAO来实现同一个接口(假设接口为UserDAO),这样的话,就可以让service层里的代码通过向上转型变成UserDAO userdao=new MysqlUserDAO()和UserDAO userdao=new OracleUserDAO(),但是仅仅这样还不够,当数据库从Mysql换成Oracle的时候,还是会要修改service层的代码,这要怎么办?Spring就是专门来解决这个问题的。
高耦合性三层传统架构
2.Spring 实现解耦合
首先介绍一下spring的概念:Spring的主要技术是 IOC(DI) AOP,IOC(DI) - 控制反转(依赖注入),AOP - 面向切面编程(这是一句废话)
通过下面这张图片,我会给大家解释,spring是如何进行解耦的,并且后面会通过IOC来解释这个原理。
Spring进行解耦偶
首先说一下spring的IOC,从图片来看,简单说就是把对象的创建和生命周期,全部交由spring来管理,也就是图中的spring容器。由此可以看出,具有耦合性的地方,都被spring同一管理了起来,这样就很大成度上的实现了解耦合。
这时候肯定大家会有疑问,spring是怎么来实现创建对象的呢?接下来就和大家说一说spring的IOC。
3.Spring的IOC原理
这里先通过用代码来解释整个过程,然后再深入一点解释原理:

//初始化Spring容器。其中参数为配置文件位置和名称
ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
//user是一个类,context是一个spring容器,getbean是通过applicationContext.xml中配置的id来获取对象
user u=(user) context.getBean("user");//此时u就通过Spring容器获取了一个user的对象
//关闭Spring容器,这里需要一个强制转换,因为close方法在ClassPathXmlApplicationContext实现类中,ApplicationContext只是一个借口
((ClassPathXmlApplicationContext)context).close();

上面代码涉及到了一个applicationContext.xml配置文件,这里来说明一下此文件是用来配置Spring容器的,在src文件下直接建立一个xml文件即可,名字也可以自己取,代码如下:

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="user" class="cn.tdu.user.user"></bean>
</beans>

其中ID自己取的,context.getbean(------)参数就为这里配置的ID,class为具体类的路径。代码看完了,可能还是不理解是怎么创建出这个对象的,用下图来解释:
在这里插入图片描述
在初始化一个Spring容器时,Spring会去解析指定的xml文件,当解析到其中的标签时,会根据该标签中的class属性指定的类的全路径名,通过反射创建该类的对象,并将该对象存入内置的Map中管理。其中键就是该标签的id值,值就是该对象。之后,当通过getBean方法来从容器中获取对象时,其实就是根据传入的条件在内置的Map中寻找是否有匹配的键值,如果有则将该键值对中保存的对象返回,如果没有匹配到则抛出异常。
4.关于IOC的一些推论
默认情况下,多次获取同一个id的bean,得到的将是同一个对象。
不可以配置多个id相同的bean
可以配置多个id不同但class相同的bean
(ps:其实也是一些废话,Map规则是什么,这里就是什么)
5.Spring创建对象的三种方式(基于工厂设计模式)
a.静态工厂设计模式:
简单来说,就是声明一个工厂类,私有化工厂类的无参构造方法,声明一个公共静态方法返回值为目标对象,然后在配置文件中配置该工厂类,于是在代码中初始化spring容器的时候,读取配置文件,读取到的是一个工厂类,然后通过配置文件调用指定好的工厂里的函数,进行对象创建,创建成功后加入Map中。
b.实例工厂设计模式:
和静态差不多,只是方法不是静态方法,还有配置文件里,需要写两个bean标签来声明工厂和指定方法
c.Spring工厂设计模式
和前两点有点区别,该方式需要让工厂类实现一个接口FactoryBean,该接口中有三个方法分别是创建bean对象,获取bean类型方法(当创建好的对象放入Map中的时候使用),告知当前bean是否要采用单例模式。

猜你喜欢

转载自blog.csdn.net/weixin_42596778/article/details/105796314