点击上方 "程序员小乐"关注公众号, 星标或置顶一起成长

每天早上8点20分, 第一时间与你相约

每日英文

When you have something you really love but it causes you pain, God is just testing you to see if you are strong enough to hold it.

当你真正喜欢一样东西,但它又给你带来伤害的时候,其实这是老天在考验你是否足够坚持。

每日掏心话

距离因拥抱而拉近,天气因拥抱而温暖,呼吸而拥抱而急促,心跳因拥抱而猛烈,空气因拥抱而凝固,时间因拥抱而停止。

来自:请叫我红领巾 | 责编:乐乐

链接:cnblogs.com/xxzhuang/p/5948902.html

程序员小乐(ID:study_tech)第 631 次推文   图片来自网络

往日回顾:Java 程序员常用资源工具集合(建议收藏)

   正文   

我们回顾一下计算机的发展史,从最初第一台计算机的占地面积达170平方米,重达30吨,到现如今的个人笔记本,事物更加轻量功能却更加丰富,这是事物发展过程中的一个趋势,在技术领域中同样也是如此。

企业级JavaBean(Enterprise JavaBean,EJB)在创建之初是非常成功,但是时间一久人们便开始追逐更加方便更加简易和轻量级的技术框架实现,于是Spring就应运而生,并且Spring一直开始不断地涉及到其他领域(这里就不再多详谈了),而Spring的精髓当中就包括控制反转和依赖注入。

浅谈控制反转(Inversion of Control,IOC)

我们首先先来了解一下控制二字,也就是在控制“正”转的情况下,在任何一个有请求作用的系统当中,至少需要有两个类互相配合工作,在一个入口类下使用new关键字创建另一个类的对象实例。

这就好比在面向对象编程的思想下,“我“充当一个入口类,在这个入口类中,我每次吃饭的时候都要买一双一次性筷子(每一次使用都要new一次),在这样的关系下,是”我“(即调用者)每次都要”主动“去买一次性筷子(另一个类)。我对筷子说你老老实实的过来我的手上,是我控制了筷子,那好,在这种控制正转的关系下,放在现实生活当中,肯定是不现实的,而且人是懒惰的,他总会去创造出更加方便自己生活的想法。

更确切的做法是,买一双普通的筷子(非一次性),把他放在一个容器当中(在Spring中叫做IOC容器),你需要使用的时候就对容器说:IOC我想要用筷子(向容器发出请求),接着筷子就会”注入“到的手上,而在这个过程当中,你不再是控制方,反而演变成一名请求者(虽然本身还是调用者),依赖于容器给予你资源,控制权坐落到了容器身上,于是这就是人们俗称的控制反转。

初涉依赖注入(Dependency Injection) 

 

同样接着上面的例子,在控制反转的统一下,筷子是怎么来到我的手上(即我们是如何获得请求的类),这就是一个依赖注入的过程。

再谈IOC与DI

设计原则中好莱坞原则描述到,“别找我们,我们找你”,百度百科上对这点描述是“不要给我们打电话,我们会给你打电话(don‘t call us, we‘ll call you)”这是著名的好莱坞原则。

在好莱坞,把简历递交给演艺公司后就只有回家等待。由演艺公司对整个娱乐项的完全控制,演员只能被动式的接受公司的差使,在需要的环节中,完成自己的演出。

这一点完美的体现了在IOC身上,IOC所注重的是设计思想上,从一个常规的创建对象的做法,即new一个对象,转变成向IOC容器递交”简历“,被动的等待IOC容器返回资源给你。控制反转即指的是”演艺公司控制演员“,而说到依赖,则是“演员需要公司混饭”,我们所需求的对象,需要依赖容器来获得,这个过程即是依赖注入。本质上IOC和DI是同一思想下不同维度的表现。

代码实现

既然说在控制反转中获取资源的过程叫做依赖注入,那么这里代码实现也是专注于依赖注入。依赖注入有3种方式,分别为构造注入,设置注入,接口注入。

1.接口注入:在接口中定义要注入的信息,并通过接口来完成注入。(Spring不支持这种注入方式--不支持的原因是--Spring声称其是非入侵式的《离开这个框架也能活》,如果使用接口注入的话,就违背了这一原则),这里不做代码实现讲解。

2.setter注入:我们先脱离Spring来实现setter注入,分两步,第一步我们先看看在常规的做法下类之间的关系,第二步使用IOC来进行设计类,对比一下之间的差别。

在常规的做法下

public class UserDao{public void addUser(String username)
{System.out.println("添加用户:"+username);
}
}

public class UserMessage {String username="demo";UserDao userDao;public UserMessage(){userDao=new UserDao();
}      public void addUser(){userDao.addUser(username);
}
}

public class test{UserMessage userMessage=new UserMessage();userMessage.addUser();
}

这上面的代码存在一个缺陷,由于在UserMessage内部创建了UseDao对象,这就造成了两个类之间的耦合度较高,当项目经理想要用另外一个Dao类的方法来实现addUser的时候,这个时候我就需要修改User Message的代码,重新new另一个类。

如果系统中有一百个地方用到这个类,那我们这些地方都要全部修改,出现Bug的概率将大大增加,然后过了一阵子,项目经理又说我想换回以前的Dao类了……

下面我们看看IOC设计的实现

public interface UserDao{void addUser(String username);
}

public class UserDaoImpl implements UserDao{@Override    public void addUser(String username)
{System.out.println("添加用户:"+username);
}
}

public class UserMessage{    private UserDao userDao;    //使用设值方式赋值    public void setUserDao(UserDao userDao) {    this.userDao = userDao;    }    public void addUser(String userName, String password) {    userDao.addUser(userName);    }
}

public class test{public static void main(String[] args) {UserDao userDao =new UserDaoImpl();UserMessage userMessage=new UserMessage();userMessage.setUserDao(userDao);}
}

我们仔细观察这里的做法, UserDao userDao=new UserDaoImpl()做法,这里就不得不提到了多态,即父类可以引用子类的方法,在这里形成的一个效果就是降低了User Message和UserDao的耦合度。

因为UserMessage和UserDao之间仅存在做什么事(addUser方法)的联系,User Message并不了解UserDaoImpl的实现方式。当我们需要换另一种UserDao的实现类的话,我们只需要修改test类下的第一行的代码就可以了,UserMessage内部并不需要修改。

再想想,读者可能会说不对啊,你说的控制反转和依赖注入需要向容器请求资源,这个容器并没有在上面体现出来啊,下面我们就讲解一下Spring 中是如何做到注入的。

<!-- 使用spring管理对象的创建,还有对象的依赖关系 -->
<bean id="userManager" class="scau.zzf.service.UserMessage">    <!-- (1)UserMessageImpl使用了userDao,Ioc是自动创建相应的UserDao实现,都是由容器管理-->    <!-- (2)在UserMessageImpl中提供构造函数,让spring将UserDao实现注入(DI)过来 -->    <!-- (3)让spring管理我们对象的创建和依赖关系,必须将依赖关系配置到spring的核心配置文件中 -->    <property name="userDao" ref="UserDao"></property>   <!-- 构造注入 --><!-- <constructor-arg ref="userDao"/>  --> </bean>
<bean id="UserDao" class="scau.zzf.Dao.UserDao"></bean>

首先我们需要装配Bean,即在Spring容器中将Bean进行配置后,然后返回Bean对象实例。我们可以通过XmlBeanFactory读取我们xml文件,从而获取相关的Bean信息。

public class test {public static void main(String[] args) throws Exception {BeanFactory factory=new XmlBeanFactory(new FileSystemResource("src/appllication.xml"));UserMessage userMessage=(UserMessage)factory.getBean("UserMessage");userMessage.add("德玛西亚");}
}

在实际应用当中,我们并不会手动去读取Xml中的信息或者加载配置文件,Spring底层已经帮我做好了这些,也就是在实际应用当中,我们就只是需要发送一个请求而已,当然了解这么一个过程还是很有必要的。

面再简单讲解一下如何通过注解来实现注入。

@Configuration的作用是使整个类成为一个配置类,@Bean注解会告诉Spring这个注解下的方法将会返回一个对象,这个对象要注册为Spring应用上下文的Bean。在默认情况下,Spring的Bean都是单例的。

也就是在上面的例子当中,无论我们使用多少次getUserDao(),结果返回的对象至始至终都是相同的。关于JavaConfig的配置进一步相关说明,读者可以前往笔者的另一篇文章《更加优雅的配置SSH》中进行参考。

欢迎在留言区留下你的观点,一起讨论提高。如果今天的文章让你有新的启发,学习能力的提升上有新的认识,欢迎转发分享给更多人。

欢迎各位读者加入程序员小乐技术群,在公众号后台回复“加群”或者“学习”即可。

猜你还想看

关于如何实现一个 TCC 分布式事务框架的一点思考

中美互联网科技公司对比图!你有的,我们也有!

教你用Python将图片转化为字符画!附源代码

太牛逼了,居然有人将各大编程语言绘成了一部编年史!

如何用几个简单的命令改善你的Linux安全?

嘿,你在看吗

轻松了解Spring中的控制反转和依赖注入相关推荐

  1. spring中的控制反转和依赖注入之间的关系

    Spring中的控制反转:把new这一个过程交给了spring容器去处理. 控制反转就是将new对象这一个过程交给外部去做(即Spring)而不是自己去创建. 图中的1"控制正转" ...

  2. Spring框架中的控制反转和依赖注入

    控制反转: 控制反转是用来降低代码之间的耦合度的,基本思想就是借助"第三方"实现具有依赖对象的解耦. 为什么需要控制反转,因为项目中对象或多或少存在耦合.控制反转的关键在于Ioc容 ...

  3. Spring容器,控制反转,依赖注入

    Spring boot学习之旅,为更好督促自己学习以记之,仅供参考. spring容器 程序启动的时候会创建spring容器,扫描给spring容器一个清单,比如:@Controller, @Bean ...

  4. Spring Ioc/DI 控制反转和依赖注入

    Ioc(Inversion of Control)和DI(Dependency Injection)的全称分别是控制反转和依赖注入. 如何理解这两个概念呢? Ioc Ioc(控制反转)实际上就说把对象 ...

  5. 控制反转 php,[PHP学习] 控制反转以及依赖注入的日常使用

    本篇文章小编将带大家学习一下PHP中的控制反转以及依赖注入的使用,感兴趣的小伙伴赶紧来看看吧! 控制反转:控制权交给了自己的类 依赖注入:依赖另一个类,我没有手动去new它 /*我自己要用的类*/ c ...

  6. Spring中控制反转和依赖注入

    Spring之IOC控制反转和DI依赖注入 1.控制反转是什么? IOC控制反转,所谓反转是指使用方本身不负责依赖对象的创建和维护,而将对象的管理(创建.维护.销毁)都交给Spring容器管理,在使用 ...

  7. SSM框架—Spring基础—控制反转和依赖注入(概念)

    控制反转: 控制反转(IoC)是面向对象编程的一个设计原则,用于降低代码耦合度 在传统面向对象编程中,获取对象的方式是用关键字"new"主动创建一个对象,也就是说,应用程序掌握着对 ...

  8. Spring 控制反转和依赖注入

    控制反转的类型 控制反转(IOC)旨在提供一种更简单的机制,来设置组件的依赖项,并在整个生命周期管理这些依赖项.通常,控制反转可以分成两种子类型:依赖注入(DI)和依赖查找(DL),这些子类型各自又可 ...

  9. Spring的控制反转与依赖注入

    学习过Spring的都知道Spring有三大核心的概念,分别是控制反转(IOC).依赖注入(DI)和面向切面编程(AOP).今天就来聊聊我对控制反转和依赖注入的了解,至于面向切面编程放到后面讲解. 一 ...

最新文章

  1. 速查笔记(Linux Shell编程上)
  2. 用WMI获取远程机器操作系统的详细信息
  3. linux ubuntu/deepin安装tengine(nginx增强版)2.3.2
  4. struts2 国际化
  5. ubuntu上安装 ibus Google拼音输入法
  6. Photoshop使用的八招密技
  7. 施工日志管理软件app_启用ERP装修管理软件的必要性
  8. Symantec BE 安装及备份oracle 完整版
  9. 微信公众号开发模式没有域名怎么办?申请免费域名
  10. html 表单 设计编辑器,可视化页面编辑器的架构设计
  11. html分列代码,C#/VB.NET Excel数据分列(示例代码)
  12. 帮小忙,腾讯在线工具箱平台
  13. 网易云项目(Vue)
  14. 酷睿i5 12490f什么水平 i5 12490f属于什么档次 i512490f怎么样
  15. 豆豆趣事[2013年09月]
  16. 《永不止步》--[奥]力克胡哲
  17. Windows下Latex的系统路径增添,使用命令编译
  18. Linux入门篇01~~Linux的快速入门 (简洁,详细,基础)
  19. 如何在Windows上使用PSCP命令?
  20. VHDL——4位移位寄存器

热门文章

  1. XXL-JOB执行器注册成功但是在管理界面里不显示
  2. 计算机跨考英语翻译硕士,2018考研:过来人谈翻译硕士不可不知的五件事
  3. [解决] failed to receive handshake ssl/tls connection failed github
  4. 我和我的项目之沙箱环境模拟支付宝支付(附演示视频)
  5. python图书管理系统制作
  6. Synaplify综合Removing
  7. flex图片拖动效果
  8. java中bit和字节的常用知识
  9. css @media自适应字体大小--简单试试
  10. 将RecyclerView变为可以左右上下滑动的Excel时间表格