当前位置: 首页 > news >正文

java开发三层架构下的分层解耦

引例:

我们都听说过软件开发设计原则高内聚低耦合。

高内聚:指的是一个模块中各个元素之间的联系的紧密程度,如果各个元素(语句、程序段)之间的联系程度越高,则内聚性越高,即 "高内聚"。

低耦合:指的是软件中各个层、模块之间的依赖关联程序越低越好。

回顾一下之前提过javaweb开发的三层架构:

  • Controller:控制层。接收前端发送的请求,对请求进行处理,并响应数据。

  • Service:业务逻辑层。处理具体的业务逻辑。

  • Dao:数据访问层(Data Access Object),也称为持久层。负责数据访问操作,包括数据的增、删、改、查。

看一下在如下这个例子中:

:上面这个案例中控制层调用业务逻辑层是通过new一个业务逻辑层对象.思考一下,这样写会有什么问题?

解:如果说我们需要更换实现类,比如由于业务的变更,UserServiceImpl 不能满足现有的业务需求,我们需要切换为 UserServiceImpl2 这套实现,就需要修改Contorller的代码,需要创建 UserServiceImpl2 的实现new UserServiceImpl2() .我们想做的是让三层架构分别工作,修改业务逻辑层的代码并不需要改动控制层的代码,现在这样明显是不行的,也就是说目前层与层之间是存在耦合的

为了解决上面的问题,我们的最终目标,是做到层与层之间,尽可能的降低耦合,甚至解除耦合。

解耦思路:

上个案例我们在编写代码时,需要什么对象,就直接new一个就可以了。 这种做法呢,层与层之间代码就耦合了,当service层的实现变了之后, 我们还需要修改controller层的代码。

那应该怎么解耦呢?

首先不能在EmpController中使用new对象。代码如下:

此时,就存在另一个问题了,不能new,就意味着没有业务层对象(程序运行就报错),怎么办呢?

我们的解决思路是:

  • 提供一个容器,容器中存储一些对象(例:UserService对象)

  • Controller程序从容器中获取UserService类型的对象

1:将要用到的对象交给一个容器管理。

2应用程序中用到这个对象,就直接从容器中获取

我们想要实现上述解耦操作,就涉及到Spring中的两个核心概念:

  • 控制反转: Inversion Of Control,简称IOC。对象的创建控制权由程序自身转移到外部(容器),这种思想称为控制反转。

    • 对象的创建权由程序员主动创建转移到容器(由容器创建、管理对象)。这个容器称为:IOC容器或Spring容器。

  • 依赖注入: Dependency Injection,简称DI。容器为应用程序提供运行时,所依赖的资源,称之为依赖注入。

    • 程序运行时需要某个资源,此时容器就为其提供这个资源。

    • 例:EmpController程序运行时需要EmpService对象,Spring容器就为其提供并注入EmpService对象。

  • bean对象:IOC容器中创建、管理的对象,称之为:bean对象。

IOC&DI基础

将Service及Dao层的实现类,交给IOC容器管理

1:只需要在实现类加上 @Component 注解,就代表把当前类产生的对象交给IOC容器管理。

例如:

2. 为Controller 及 Service通过@Autowired注解注入运行时所依赖的对象

例如:

IOC详解

前面我们提到IOC控制反转,就是将对象的控制权交给Spring的IOC容器,由IOC容器创建及管理对象。IOC容器创建的对象称为bean对象。

在之前的入门案例中,要把某个对象交给IOC容器管理,需要在类上添加一个注解:@Component

而Spring框架为了更好的标识web应用程序开发当中,bean对象到底归属于哪一层,又提供了@Component的衍生注解:

那么此时,我们就可以使用 @Service 注解声明Service层的bean。 使用 @Repository 注解声明Dao层的bean。

例如:

注意1:声明bean的时候,可以通过注解的value属性指定bean的名字,如果没有指定,默认为类名首字母小写

注意2:使用以上四个注解都可以声明bean,但是在springboot集成web开发中,声明控制器bean只能用@Controller。


问题:使用的这四个注解声明的bean,一定会生效吗?

答案:不一定。(原因:bean想要生效,还需要被组件扫描)

   声明bean的四大注解,要想生效,还需要被组件扫描注解 @ComponentScan 扫描。

  • 该注解虽然没有显式配置,但是实际上已经包含在了启动类声明注解          中,默认扫描的范围是启动类所在包及其子包

可以看到@SpringBootApplication的定义里包含了 @ComponentScan

所以,我们在项目开发中,只需要按照如上项目结构,将项目中的所有的业务类,都放在启动类所在包的子包中,就无需考虑组件扫描问题

DI详解

依赖注入,是指IOC容器要为应用程序去提供运行时所依赖的资源,而资源指的就是对象。

之前我们使用了@Autowired这个注解,完成了依赖注入的操作,而这个Autowired翻译过来叫:自动装配。

@Autowired用法有三种

在项目开发中,基于@Autowired进行依赖注入时,基本都是第一种和第二种方式。(官方推荐第二种方式,因为会更加规范)但是在企业项目开发中,很多的项目中,也会选择第一种方式因为更加简洁、高效(在规范性方面进行了妥协)。

问题:如果在IOC容器中,存在多个相同类型的bean对象,DI注入时候会注入哪一个bean对象呢?

可以看到,正常情况有多个bean时候,DI自动装配会报错,不知道自动装配哪一个bean

解决办法:

  • @Primary:为要注入的bean添加优先级

  • @Qualifier:指定当前要注入的bean对象。 在@Qualifier的value属性中,指定注入的bean的名称。//bean的名称默认为类名首字母小写

  • @Qualifier注解不能单独使用,必须配合@Autowired使用。

  • @Resource:按照bean的名称进行注入。通过name属性指定要注入的bean的名称。

@Autowird 与 @Resource的区别

  • @Autowired 是spring框架提供的注解,而@Resource是JDK提供的注解

  • @Autowired 默认是按照类型注入,而@Resource是按照名称注入

http://www.dtcms.com/a/470615.html

相关文章:

  • 缔客网络上海响应式网站建设如何建平台网站
  • 学习Java第三十七天——黑马点评61~68
  • 网站 运营 外包 每个月多少钱h5制作易企秀
  • 基础算法:滑动窗口
  • 数据比例与尺度:如何避免让图“放大”差异
  • 《动手学深度学习v2》学习笔记 | 3.4-3.7 softmax 回归
  • Python驱动的无人机多光谱-点云融合技术在生态三维建模与碳储量、生物量、LULC估算中的全流程实战
  • 哪些网站收录排名好wordpress 获取title
  • 大语言模型核心技术解析:从 Transformer 架构到下词预测的完整工作原理与编码器、解码器及注意力机制的运作流程
  • 企业网站模板建站怎么用上海平台公司
  • Android Maven私服搭建(Windows)
  • Webpack 模块联邦(Module Federation)
  • 河南锦源建设有限公司网站重庆建站网站建设平台
  • JZ39 数组中出现次数超过一半的数字
  • 网站开发智能化方向门户网站建设原则
  • 【React】动态SVG连接线实现:图片与按钮的可视化映射​
  • 专门做油站数据的网站游戏网页版入口
  • 【碎片化学习】SpringBoot数据库驱动介绍配置方法和代码
  • 设计模式篇之 适配器模式 Adapter
  • 小程序怎么制作自己的小程序seo长尾关键词优化
  • 网站备案号规则中核集团2023校园招聘信息
  • postman 做接口测试之学习笔记
  • 做网站要买多少服务器空间有什么做家纺的网站
  • 【编号26】青藏高原地理空间全套数据集(矢量边界、子流域、行政边界、水系等)
  • loguru 和 logging 的详细对比
  • 番禺移动网站建设百度快照投诉中心官网
  • 调试去符号化/strip 过的二进制的调试方法
  • 大连建设局网站地址怎么将自己房子投入网站做民宿
  • 新河网站旅游网站策划方案
  • 建网站备案好麻烦长春市建设工程造价管理协会网站