轻松了解Spring中的控制反转和依赖注入(一)

  我们回顾一下计算机的发展史,从最初第一台计算机的占地面积达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
public class UserConfig {@Beanpublic UserDao getUserDao(){ return new UserDao(); } @Bean public UserMessage getUserMessage(){ return new UserMesssgae(getUserDao); } }

@Configuration的作用是使整个类成为一个配置类,@Bean注解会告诉Spring这个注解下的方法将会返回一个对象,这个对象要注册维Spring应用上下文的Bean。在默认情况下,Spring的Bean都是单例的,也就是再上面的例子当中,无论我们使用多少次getUserDao(),结果返回的对象至始至终都是相同的。关于JavaConfig的配置进一步相关说明,读者可以前往笔者的另一篇文章《更加优雅的配置SSH》中进行参考。  转载请说明原文链接:http://www.cnblogs.com/xxzhuang/p/5948902.html 多谢合作。

转载于:https://www.cnblogs.com/chenyj/p/6519683.html

轻松了解Spring中的控制反转和依赖注入(一) --[转]http://www.cnblogs.com/xxzhuang/p/5948902.html...相关推荐

  1. 轻松了解Spring中的控制反转和依赖注入

    点击上方 "程序员小乐"关注公众号, 星标或置顶一起成长 每天早上8点20分, 第一时间与你相约 每日英文 When you have something you really l ...

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

最新文章

  1. iOS runtime和runloop
  2. PWA(Progressive Web App)入门系列:消息通讯
  3. 【Flutter】Dart 数据类型 ( dynamic 数据类型 )
  4. Python从菜鸟到高手(5):数字
  5. 查看Tomcat版本及多版本切换
  6. App设计灵感之十二组精美的数据图表展示App设计案例
  7. 用keepalived配置高可用集群
  8. 脉脉因“App 整改下架”事件致歉;阿里云全年营收超 600 亿;腾讯防大量群消息骚扰专利获授权|极客头条...
  9. java webservice用户验证_java webservice 用户验证 (服务端 + 客户端)
  10. EventBus实现 - 发布订阅 - XML加载
  11. 关于最新版的JCreator只能编译不能运行的问题
  12. ANDROID_MARS学习笔记_S01原始版_009_下载文件
  13. 屌丝Cent OS服务器应用之--SVN
  14. 12种mysql常见错误总结 +分析示例
  15. 音视频6.2——相机采集数据编码成H264
  16. 大数据说婚恋--再不给女性减负,结婚率和出生率都升不回来了
  17. 哺乳期这几种还真的要少吃,不能吃的食物真有那么多?
  18. 欺诈检测_签名欺诈检测-一种高级分析方法
  19. ubuntu系统shell 中source: not found错误
  20. 资源不准下的网络故障定位探索

热门文章

  1. shell基础之后台运行脚本
  2. 廖雪峰Java2面向对象编程-5包和classpath-4classpath和jar
  3. Android中的隐藏API和Internal包的使用之获取应用电量排行
  4. Hbase笔记:批量导入
  5. 非旋转Treap及可持久化[Merge,Split]
  6. JS1 js获取dom元素方法
  7. 日常---区域赛临近
  8. Silverlight 功能其全的PDF 控件
  9. 树型DataGrid的思路
  10. ext.net 开发学习——回车事件(六)