控制反转Inverse Of Control的演变:

在之前的原生Javaweb项目的问题:

我们三层架构每一层之间的联系是这样的:

由GradeDao接口指向GradeDaoImpl

再由GradeService指向GradeServiceImpl

但是我们发现,如果这样写死在每一层的硬编码中的话,那么接口的存在就失去了意义

对象的创建是由这个上层的内部所决定

我们是希望每一层的联系最小化,但是又不能完全隔绝关系,组件就像组装的好的零件

相互之间的依赖降低到最小,比如这个daoImpl我需要替换,就根据实现的dao接口就可以有

MySQL实现,Oracle实现,PostgreSQL实现等等

对象的创建可以移交到外部,我们在内部设置setter注入即可,或者使用带参构造器

通过setter或者带参构造器,我们可以从本层的内部创建对象这个控制权力,移交到了外面

虽然这还是硬编码中

接下来我们就创建一个工厂类,由工厂实现对象的创建,而这个行为,非常像生产产品

一个个对象即我们的业务的产品

对象的注入交由工厂生产给予

但是我们是不是发现,工厂的产品还是固定的?然后再像Jdbc一样,

通过读取配置文件的形式解除耦合

首先是配置文件:bean.properties

例如这里我就配置另外一种实现

AaaDao = ioc.dao.AaaDaoImpl2
AaaService = ioc.service.AaaServiceImpl2

这里只是键值对简单的字符串

然后改造我们的BeanFactory

通过加载的时候读取配置文件直接生成对象放进这个map容器中

这个容器不就是bean的容器了吗,键对应的实现类名,值即对象

put放进去的key应该换value进去。。。我有点分不清

但这不是重点,我们下面获取对象的方法就是从容器里面获取

这就需要key作为参数:

再加上泛型,这样我们就不需要进行强转了

但是有个问题就是dao也是接口啊,接口指向了之后没办法在setter了,但是可以不设置接口处理

className应该换成叫beanName

现在我们通过配置文件的方式来获取对象,整个过程完全看不到一个new字。

总结:写的好烂,过程改了好几回

瞎扯的代码:

Bean工厂

package ioc;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties; /**
* @author DaiZhiZhou
* @file OA-Project
* @create 2020-07-24 22:57
*/
public class BeanFactory { private static Map<String,Object> beanContainer = new HashMap<>(); static {
try {
// InputStream inputStream = BeanFactory.class.getClassLoader().getResourceAsStream("bean.properties");
       // 因为找不到配置文件就检查下路径的读取
String file = BeanFactory.class.getClassLoader().getResource("bean.properties").getFile();
System.out.println(file);
InputStream inputStream = new FileInputStream(new File(file)); Properties properties = new Properties();
properties.load(inputStream); Enumeration<Object> keys = properties.keys(); while (keys.hasMoreElements()) {
String key = (String)keys.nextElement();
String value = properties.getProperty(key); Class<?> classByValue = Class.forName(value);
Object valueInstance = classByValue.newInstance();
beanContainer.put(key, valueInstance);
} } catch (Exception e) {
e.printStackTrace();
}
} public static <Bean>Bean getBean(String className, Class<Bean> beanClass) {
Object o = beanContainer.get(className);
return (Bean)o;
} }

properties:

AaaDao = ioc.dao.AaaDaoImpl2
AaaService = ioc.service.AaaServiceImpl2

测试类:假装是视图的Servlet

package ioc.servlet;

import ioc.BeanFactory;
import ioc.dao.AaaDao;
import ioc.dao.AaaDaoImpl;
import ioc.service.AaaService;
import ioc.service.AaaServiceImpl;
import ioc.service.AaaServiceImpl2;
import org.junit.Test; /**
* @author DaiZhiZhou
* @file OA-Project
* @create 2020-07-24 22:48
*/
public class AaaServletFake { private AaaService aaaService; public void setAaaService(AaaService aaaService) {
this.aaaService = aaaService;
} @Test
public void toAaaListPage() {
setAaaService(new AaaServiceImpl(new AaaDaoImpl()));
aaaService.getAaaList();
} @Test
public void toAaaListPageByFactoryProduct() {
//this.setAaaService(BeanFactory.getAaaService());
aaaService.getAaaList();
} @Test
public void toAaaListPageByFactoryProductPropertyFileInject() {
AaaDao aaaDao = BeanFactory.getBean("AaaDao", AaaDao.class);
AaaServiceImpl2 aaaServiceImpl2 = BeanFactory.getBean("AaaService", AaaServiceImpl2.class);
aaaServiceImpl2.setAaaDao(aaaDao);
this.setAaaService(aaaServiceImpl2);
this.aaaService.getAaaList();
} }

关于注入问题的再补充:

因为存在这种工厂方式的注入,所以Spring就也提供了对应的这种方式:

静态工厂获取 和 工厂实例方法获取:

详细见:

http://123.57.58.29/blog/1591625710261

静态工厂

    <!-- 此种方式是:
使用 StaticFactory 类中的静态方法 createAccountService 创建对象,并存入 spring 容器
id 属性:指定 bean 的 id,用于从容器中获取
class 属性:指定静态工厂的全限定类名
factory-method 属性:指定生产对象的静态方法
--> <bean id="accountService" class="com.tc51.factory.StaticFactory" factory-method="createAccountService"></bean>

实例工厂

  <!--创建工厂对象-->
<!--先通过实例工厂创建对象-->
<bean id="bean3Factory" class="com.tc51.factory.Bean3Factory"></bean>
<bean id="accountService" factory-bean="bean3Factory" factory-method="createAccountService"></bean>

【Spring】07 后续的学习补充 vol1的更多相关文章

  1. 写给大忙人的spring cloud 1.x学习指南

    这几天抽空搞了下spring cloud 1.x(2.0目前应该来说还不成熟),因为之前项目中使用dubbo以及自研的rpc框架,所以总体下来还是比较顺利,加上spring boot,不算笔记整理,三 ...

  2. Spring Cloud微服务学习笔记

    Spring Cloud微服务学习笔记 SOA->Dubbo 微服务架构->Spring Cloud提供了一个一站式的微服务解决方案 第一部分 微服务架构 1 互联网应用架构发展 那些迫使 ...

  3. 强化学习读书笔记 - 06~07 - 时序差分学习(Temporal-Difference Learning)

    强化学习读书笔记 - 06~07 - 时序差分学习(Temporal-Difference Learning) 学习笔记: Reinforcement Learning: An Introductio ...

  4. Spring+SpringMVC+MyBatis深入学习及搭建(二)——MyBatis原始Dao开发和mapper代理开发

    转载请注明出处:http://www.cnblogs.com/Joanna-Yan/p/6869133.html 前面有写到Spring+SpringMVC+MyBatis深入学习及搭建(一)——My ...

  5. Spring+SpringMVC+MyBatis深入学习及搭建(三)——MyBatis全局配置文件解析

    转载请注明出处:http://www.cnblogs.com/Joanna-Yan/p/6874672.html 前面有写到Spring+SpringMVC+MyBatis深入学习及搭建(二)——My ...

  6. Spring+SpringMVC+MyBatis深入学习及搭建(四)——MyBatis输入映射与输出映射

    转载请注明出处:http://www.cnblogs.com/Joanna-Yan/p/6878529.html 前面有讲到Spring+SpringMVC+MyBatis深入学习及搭建(三)——My ...

  7. Spring+SpringMVC+MyBatis深入学习及搭建(五)——动态sql

    转载请注明出处:http://www.cnblogs.com/Joanna-Yan/p/6908763.html 前面有讲到Spring+SpringMVC+MyBatis深入学习及搭建(四)——My ...

  8. Spring+SpringMVC+MyBatis深入学习及搭建(六)——MyBatis关联查询

    转载请注明出处:http://www.cnblogs.com/Joanna-Yan/p/6923464.html 前面有将到:Spring+SpringMVC+MyBatis深入学习及搭建(五)--动 ...

  9. Spring+SpringMVC+MyBatis深入学习及搭建(七)——MyBatis延迟加载

    转载请注明出处:http://www.cnblogs.com/Joanna-Yan/p/6953005.html 前面讲到:Spring+SpringMVC+MyBatis深入学习及搭建(六)——My ...

  10. Spring+SpringMVC+MyBatis深入学习及搭建(八)——MyBatis查询缓存

    转载请注明出处:http://www.cnblogs.com/Joanna-Yan/p/6956206.html 前面讲到:Spring+SpringMVC+MyBatis深入学习及搭建(七)——My ...

随机推荐

  1. Vue CLI 4与项目构建实战指南

    title: Vue CLI 4与项目构建实战指南 date: 2024/6/9 updated: 2024/6/9 excerpt: 这篇文章介绍了如何使用Vue CLI优化项目构建配置,提高开发效 ...

  2. 大一统的监控探针采集器 cprobe

    需求背景 监控数据采集领域,比如 Prometheus 生态有非常多的 Exporter,虽然生态繁荣,但是无法达到开箱即用的大一统体验,Exporter 体系的核心问题有: 良莠不齐:有的 Expo ...

  3. 如何将 iPhone 的照片同步到 windows 电脑上

    首先在电脑上,新建一个文件夹,并把共享权限打开. 文件夹 右键 属性,共享,添加 Everyone. 然后,让手机和电脑连接到同一个局域网,手机热点即可. 在手机端看 文件 app,找到电脑的共享文件 ...

  4. spark高级分析2的数据集地址

    第二章 数据分析 wget https://archive.ics.uci.edu/ml/machine-learning-databases/00210/donation.zip 第三章   音乐推 ...

  5. notonlysuccess大神的线段树完全版

    在大神的网站进不去的时候可以过来看看,另外道客巴巴有个排版比较好的文档,外观派可以去看看http://www.doc88.com/p-2728103209174.html 很早前写的那篇线段树专辑至今 ...

  6. 11-Python网络编程

    socket包介绍 Socket又称"套接字",应用程序通常通过"套接字"向网络发出请求或者应答网络请求,使主机间或者一台计算机上的进程间可以通讯. 创建一个T ...

  7. 同时开启firewall和iptables

    使用向导 With the iptables service, every single change means flushing all the old rules and reading all ...

  8. Bike Sharing Analysis(二)- 假设检验方法

    假设检验 假设检验是推论统计学(inferential statistics)的一个分支,也就是对一个较小的.有代表性的数据组(例如样本集合)进行分析与评估,并依此推断出一个大型的数据组(例如人口)的 ...

  9. python基础-列表list [ ]

    列表的定义和操作 列表的特性: 元素数量 支持多个 元素类型 任意 下标索引 支持 重复元素 支持 可修改性 支持 数据有序 是 使用场景 可修改.可重复的 一批数据记录场景 # 定义一个列表list ...

  10. [UG 二次开发 PYTHON] 添加螺纹规格

    NX 1988 系列 在添加螺纹特征时,不能自定义螺纹规格, 从网上找到的资料上讲,改一个XML文件,在文件中添加自定义的螺纹规格,从而实现需要的效果. 自己写了一个小程序,方便手动添加螺纹规格. 效 ...