菜瓜:我一定是太菜了,为什么别人说Spring屏蔽了new关键字创建对象就很丝滑?我完全get不到这个操作的好处啊,我自己写new它也很香啊

水稻:emmmm,换个角度想啊,如果把现在用的注解@Autowired@Resource给干掉,你想在Controller里面引用Service,你会怎么做?new 一个?

菜瓜:对啊,我new一个怎么了,不也可以用?

水稻:那如果,我另一个Controller里面也要用同一个Service,是不是再new一个?有很多个这种Controller是不是new很多个Service?

菜瓜:这。。。我有另一个方法,把Service放在一个容器里,Controller用的时候从容器里面拿?

水稻:哇塞,Spring应该请你去写他们的框架啊

菜瓜:Spring是这么做的?

水稻:不知道你听没听过简单工厂这种设计模式,用于将对象的创建和使用隔离开来,达到解耦的目的。工厂负责创建对象,并且可以干预创建的逻辑

菜瓜:嗯,简单工厂,工厂方法,抽象工厂我都略懂?

水稻:。。。。Talk is cheap , show me your code ! 就简单工厂就行了

菜瓜:下面这样的

package club.interview.design_pattern.chapt2_factory_pattern;

/**
* @author QuCheng on 2020/6/13.
*/
public class SimpleFactory { abstract static class AbstractPhone {
abstract void call();
} static class XiaoMi extends AbstractPhone {
@Override
void call() {
System.out.println("小米手机打电话。。。。");
}
} static class Meizu extends AbstractPhone {
@Override
void call() {
System.out.println("魅族手机打电话。。。。");
}
} public AbstractPhone getPhone(String phoneType) {
if ("小米".equals(phoneType)) {
return new XiaoMi();
} else if ("魅族".equals(phoneType)) {
return new Meizu();
}
return null;
} public static void main(String[] args) {
SimpleFactory s = new SimpleFactory();
s.getPhone("小米").call();
s.getPhone("魅族").call();
} }

水稻:那你肯定知道,这种写法的局限性。依靠phoneType来创建对象不利于扩展。如果现在的需求生产的对象不限定返回类型,给啥就创建啥,怎么做

菜瓜:动态创建对象?那不是反射吗?是不是这样

package club.interview.design_pattern.chapt2_factory_pattern;

/**
* @author QuCheng on 2020/6/13.
*/
public class SpringFactory { static class XiaoMi {
void call() {
System.out.println("小米手机打电话。。。。");
}
} static class Meizu {
void call() {
System.out.println("魅族手机打电话。。。。");
}
} static class HuaWei {
void call() {
System.out.println("华为手机打电话。。。。");
}
} public <T> T getPhone(Class<T> clazz) {
try {
return clazz.newInstance();
} catch (InstantiationException | IllegalAccessException e) {
e.printStackTrace();
}
return null;
} public static void main(String[] args) {
SpringFactory s = new SpringFactory();
s.getPhone(XiaoMi.class).call();
s.getPhone(Meizu.class).call();
s.getPhone(HuaWei.class).call();
} }

水稻:秀啊!!厉害厉害。相比你也知道,此时如果我想在创建过程中加入一点点自己的逻辑,那也是很丝滑的。

菜瓜:哦,原来是这样。Spring利用工厂将对象的创建和使用进行隔离,还可以定制一些bean对象的创建逻辑。学到了,学到了。

水稻:我也学到了,反射和设计模式用的6啊。当然,Spring的工厂远没有你现在想的这么简单。你再仔细品品

总结:

  • Spring利用反射创建对象,并将创建好的对象放入一个大工厂,实现了对象创建和使用的解耦。后需要使用的时候可以方便的通过BeanFactory.getBean()获取。在此之上还扩展了堆注解的支持,使用注解就可以注入对象。这就是传说中的DI(Dependency Inject)依赖注入

Spring:工厂模式哪里解耦了?的更多相关文章

  1. Spring中如何使用工厂模式实现程序解耦?

    目录 1. 啥是耦合.解耦? 2. jdbc程序进行解耦 3.传统dao.service.controller的程序耦合性 4.使用工厂模式实现解耦 5.工厂模式改进 6.结语 @ 1. 啥是耦合.解 ...

  2. Spring 实现两种设计模式:工厂模式和单态模式(单例模式)

    本文摘自:李刚 著 <轻量级 Java EE企业应用实战 Struts2+Spring+hibernate整合开发> 在Spring 中大量使用的以下两种设计模式:工厂模式和单态模式. 工 ...

  3. PHP 工厂模式介绍

    工厂模式,顾名思义,如同工厂一样,你把原材料放入工厂中,出来的是成品,而你并不需要知道工厂里做了什么.代码中也类似,把主要参数放入一个工厂里,返回的是处理好的数据,我们并不需要工厂里做了什么,只需要知 ...

  4. Java工厂模式解耦 —— 理解Spring IOC

    Java工厂模式解耦 -- 理解Spring IOC 最近看到一个很好的思想来理解Spring IOC,故记录下来. 资源获取方式 主动式:(要什么资源都自己创建) 被动式:(资源的获取不是我们创建, ...

  5. 简单工厂模式,工厂方法模式,抽象工厂模式,spring的狂想

    菜鸟D在项目中遇见一个比较纠结的高耦合,所以就想办法来解耦.情况是这样的:系统通过用户选择treeview控件的节点判断调用不同的处理,这些处理中某些东西又是类似的.同事的建议是采用简单工厂,耦合就耦 ...

  6. 使用工厂模式解耦和IoC思想

    使用工厂模式解耦. 一.需求场景: 某一层功能需要改动,但其他层代码不变 实现类1:MyDaoImpl查询自己的数据库. ====改为====> 实现类2:MyDaoImpl2从其它地址得到数据 ...

  7. 应聘阿里,字节跳动,美团必须掌握的Spring IOC与工厂模式

    Spring IOC与工厂模式 PS:本文内容较为硬核,需要对java的面向对象.反射.类加载器.泛型.properties.XML等基础知识有较深理解. (一)简单介绍 在讲Spring IOC之前 ...

  8. 工厂模式模拟Spring的bean加载过程

    一.前言    在日常的开发过程,经常使用或碰到的设计模式有代理.工厂.单例.反射模式等等.下面就对工厂模式模拟spring的bean加载过程进行解析,如果对工厂模式不熟悉的,具体可以先去学习一下工厂 ...

  9. Spring中的工厂模式和单例模式

    Spring预备知识(适合中小型项目) 作用:集成和管理其他框架 工厂模式: A  a  = new A( ); 将类所要创建的对象写入工厂,统一进行管理 package com.spring; pu ...

随机推荐

  1. codis原理及部署_01

    一.codis介绍 Codis是一个分布式Redis解决方案,对于上层的应用来说,连接到Codis Proxy和连接原生的RedisServer没有明显的区别,有部分命令不支持 Codis底层会处理请 ...

  2. vue-cli 如何修改或删除预设preset记录

    preset其实是你在create新vue项目的时候,生成的插件配置项预设,也就是你在项目中需要用到的插件安装成功了之后,会生成一个关于preset的文件,当你再次create新的vue项目的时候,就 ...

  3. 27-1 分组-having

    group by select * from TblStudent --1.请从学生表中查询出每个班的班级id和班级人数 select tsclassId as 班级id, 班级人数=count(*) ...

  4. 当 RocketMQ 遇上 Serverless,会碰撞出怎样的火花?

    作者 | 元毅  阿里巴巴高级开发工程师 阿里巴巴云原生公众号后台回复 Knative,免费下载<Knative 云原生应用开发指南>电子书! 想必大家都比较了解 RocketMQ 消息服 ...

  5. Pyqt5_QWidget

    QWidget常用方法: Qwidget.size()#获得客户区的大小 QWidget.width().QWidget.height()#获得客户区的宽度与高度 #设置不可以变宽.高 QWidget ...

  6. PHP 数据库操作函数笔记

    /建立 或者 关闭mysql服务器 @符号用于屏蔽错误信息 $link=@mysqli_connect('127.0.0.1','root','123456','php1',3306); if(mys ...

  7. 计算机启动 Ubuntu系统初始化 SysV Systemd

    计算机启动过程 第一阶段:BIOS boot (bootstrap的缩写)来自一句谚语:"pull oneself up by one's bootstraps" 最早的时候,计算 ...

  8. JVM调优总结(五)-典型配置举例

    以下配置主要针对分代垃圾回收算法而言. 堆大小设置 年轻代的设置很关键 JVM中最大堆大小有三方面限制:相关操作系统的数据模型(32-bt还是64-bit)限制:系统的可用虚拟内存限制:系统的可用物理 ...

  9. 使用 git add -p 整理 patch

    背景 当我们修改了代码准备提交时,本地的改动可能包含了不能提交的调试语句,还可能需要拆分成多个细粒度的 pactch. 本文将介绍如何使用 git add -p 来交互式选择代码片段,辅助整理出所需的 ...

  10. MyBatis(二)参数传递和自定义结果集

    个人博客网:https://wushaopei.github.io/    (你想要这里多有) 一.myBatis的注解使用方式 package com.webcode.mapper; import ...