spring之hellospring

news/2025/2/6 11:06:59/文章来源:https://www.cnblogs.com/loubin/p/18700725

高耦合的代码

我想要写一段程序,该程序有dao层和service层,dao层有接口UserDao,定义了一个方法叫做sayHello(),并且在dao层定义两个类MysqlDao和OracleDao,他们都实现了UserDao接口,并且实现了sayHello()方法,如图和代码所示

 

UserDao接口的代码如下

package com.loubin.dao;public interface UserDao {public void sayHello();
}

 

MysqlDao类的代码如下

package com.loubin.dao;public class MysqlDao implements UserDao{@Overridepublic void sayHello() {System.out.println("正在使用mysql访问数据");}
}

 

Oracle类的代码如下

package com.loubin.dao;public class OracleDao implements UserDao{@Overridepublic void sayHello() {System.out.println("正在使用oracle访问数据");}
}

 

接下来我在service层定义了UserService接口,并且定义了UserServiceImpl类来实现该接口,该类调用UserDao接口,代码实现如下

UserService接口的代码如下

package com.loubin.service;public interface UserService {public void sayHello();
}

 

UserServiceImpl类的代码如下

package com.loubin.service;import com.loubin.dao.MysqlDao;
import com.loubin.dao.UserDao;public class UserServiceImpl implements UserService{private UserDao userDao = new MysqlDao();@Overridepublic void sayHello() {userDao.sayHello();}@Overridepublic String toString() {return "UserServiceImpl{" +"userDao=" + userDao +'}';}public UserDao getUserDao() {return userDao;}public void setUserDao(UserDao userDao) {this.userDao = userDao;}
}

 

测试代码TestUserService如下

package com.loubin;import com.loubin.service.UserService;
import com.loubin.service.UserServiceImpl;
import org.junit.Test;public class TestUserService {@Testpublic void testSayHello(){UserService userService = new UserServiceImpl();userService.sayHello();}}

 

测试结果如下

 

上面的代码有个问题,那就是我在UserServiceImpl类中,显示定义了属性userDao,并且令他为类Mysql的对象,但是如果测试代码的需求(可以认为是客户的需求)变了,需要使用OracleDao类来实现sayHello,那么我需要在UserServiceImpl类中将

private UserDao userDao = new MysqlDao();
改成
private UserDao userDao = new OracleDao();
也就是说,为了满足客户对于sayHello的主体的变化,我得自己去改用业务层的代码,这样的程序的耦合性是很高的,如果后面还有更多的UserDao的实现类,那我得一直修改UserServiceImpl的程序了,这很不科学。
 

set注入实现控制反转

如果让用户自己选择想用UserDao的哪一个实现类,并且自己将选择的实现类传入到UserServiceImpl中,这样程序员就不需要修改UserServiceImpl了,将控制的权限从程序员反转到了客户本身,这就是反转控制。具体实现如下

新的UserServiceImpl代码,增加了构造函数,并且不在类里面显示定义UserDao的实现了

package com.loubin.service;import com.loubin.dao.MysqlDao;
import com.loubin.dao.UserDao;public class UserServiceImpl implements UserService{private UserDao userDao;public UserServiceImpl(UserDao userDao) {this.userDao = userDao;}@Overridepublic void sayHello() {userDao.sayHello();}@Overridepublic String toString() {return "UserServiceImpl{" +"userDao=" + userDao +'}';}public UserDao getUserDao() {return userDao;}public void setUserDao(UserDao userDao) {this.userDao = userDao;}
}

 

测试代码如下,现在客户自己实现UserDao,想用MysqlDao还是OracleDao都行了

package com.loubin;import com.loubin.dao.MysqlDao;
import com.loubin.dao.UserDao;
import com.loubin.service.UserService;
import com.loubin.service.UserServiceImpl;
import org.junit.Test;public class testUserService {@Testpublic void testSayHello(){UserDao userDao = new MysqlDao();UserService userService = new UserServiceImpl(userDao);userService.sayHello();}}

 

通过spring的ioc容器管理

使用ioc容器进行对象的托管,来代替上一小节的set注入

配置ioc容器

<?xml version="1.0" encoding="UTF-8"?>
<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="mysqlDao" class="com.loubin.dao.MysqlDao"></bean><bean class="com.loubin.dao.OracleDao" id="oracleDao"></bean><bean class="com.loubin.service.UserServiceImpl" id="service"><property name="userDao" ref="mysqlDao"></property></bean>
</beans>

 

测试代码变成如下代码

package com.loubin;import com.loubin.dao.MysqlDao;
import com.loubin.dao.UserDao;
import com.loubin.service.UserService;
import com.loubin.service.UserServiceImpl;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class testUserService {@Testpublic void testSayHello(){ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");UserService service = (UserService) context.getBean("service");service.sayHello();}}

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/879570.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java调用deepseek

崩溃了几天的deepseek 接口官网今天终于好了:https://api-docs.deepseek.com/zh-cn/,打开一看貌似没有集成JAVA开发如下图,只有curl.python,nodejs三种形式既然可以curl形式调用接口理论上任何编程语言都可以调用。 第一步:引入pom依赖jar,习惯了使用okhttp<dependency>…

绩效考核:我做了很多上级却看不见怎么办?

“作为员工,我的每一天都是非常忙碌的,但是负责最后一环产出结果的不是我,得到称赞的总是别人。年终绩效考核也都是一些简单的指标项,没有办法体现出我日常的付出,绩效结果永远都是普通。” 上面这段话是众多员工的心声,然而他们不知道的是,作为管理者也很头疼这个问题。…

借助deepseek完成python的Deoldfiy黑白照着色工具

最近deepseek火热,试试看能否协助完成制作一款工具,用于给黑白照片着色。打开deepseek,注册完后,输入需求,给我推荐了deoldify,制作过程总结为以下几步: 1. Python环境搭建直接忽略 2.Deoldfiy依赖库下载安装,训练模型models下载(需要梯子) 3. 运行查看效果代码执行…

手搓指数函数实现

1.概况 最近博主有使用指数函数的需求,需要一条在第一象限、底数为10的曲线。但是由于芯片资源有限,所以无法使用数学库。不能调用数学库里面的指数函数。于是就在网上找了一圈,发现毫无质量。 1.只考虑到了整数次幂的简单情况。 2.要么就是调用数学库,没有一个有用的。 于…

淘宝详情页批量抓取组合商品价格

需求:客户需要抓取淘宝商品的不同组合价格,步骤如下图通过切换分类获取相应的价格 客户需求我们可以这样实现:循环点击产品分类,点击一次相应获取一次商品价格 1、首先商品价格,我们发现不同的商品参加活动不一,导致商品价格样式有多种如下2、商品价格样式的多样性使得价…

EvalPlanner:基于“计划-执行”双阶段的大语言模型评估框架

大语言模型(LLM)评估系统在生成思维链(Chain-of-Thought, CoT)序列时,需要系统地捕捉评估过程中的推理步骤。但是由于缺乏人工标注的CoT训练数据,以及预定义评估提示在复杂任务中的局限性,构建高质量的LLM评估模型面临重大挑战。另外手动调整评估指令的方法在面对多样化和复…

[网摘实践]基于本地部署DeepSeek+VSCode+Cline编写代码

前面的本地部署部分,我已经搭建好了。可以参考:https://www.cnblogs.com/haochuang/p/18700495 这里只是在本地基于模型搭建代码编写相关组件 使用deepseek-r1 + Vscode + Cline/Continue 构建本地代码编辑器 这个落地方案是实现本地代码编辑器,但是具体的效果见仁见智,pro…

docker compose搭建immich开源免费相册管理工具

一、immich介绍 1.1 immich简介直接从您的手机自托管照片和视频备份解决方案。1.2 immich注意事项该项目正在非常积极的开发中。⚠️预计会出现错误和重大更改。 ⚠️ 请勿将该应用程序用作存储照片和视频的唯一方式。 ⚠️始终遵循 3-2-1 备份计划,为您珍贵的照片和视频! 1.…

vue3支持低版本浏览器

安装包 npm install @vitejs/plugin-legacy -D #如果打包不了,安装terser包,如果能正常打包,不安装这个包也可以 npm install terser -D在vite.config.ts文件中添加如下配置 import legacy from @vitejs/plugin-legacy export default defineConfig({plugins: [vue(), legac…

【运维自动化-作业平台】如何使用全局变量之数组类型?

数组类型的全局变量也是作业平台里常用的,支持关联数组和索引数组,目前仅支持shell,语法跟shell一致。索引数组 语法 arry=(1 2 3 a b c) ---定义一个数组arry ${arry[*]} ---获取所有数组元素 ${arry[@]} ---获取所有数组元素 ${arry[0]} --获取第一个数组元素实操演示 1、…

用 DeepSeek 分析,SaaS 多租户的3种隔离模式,结果。。。

大家好,我是汤师爷~ 在SaaS模式下,多租户之间的资源隔离是基础且关键的一环。 SaaS服务商需要在确保运营效率和控制成本的前提下,搭建一个让多个租户能够同时访问的共享环境。 虽然大家都在用同一套SaaS产品服务,但资源访问必须严格隔离,确保租户之间互不干扰。 下面,介绍…

HTTP和HTTPS的区别和作用

HTTP和HTTPS的区别和作用:一、核心区别(分点清晰)协议安全性HTTP:明文传输,数据无加密,易被窃听(如登录密码、用户隐私泄露)。 HTTPS:HTTP + TLS/SSL加密层,数据在传输前加密(使用对称加密传输数据 + 非对称加密交换密钥),防止中间人攻击。默认端口HTTP默认80端口…