Spring进阶之路(1)-Spring核心机制:依赖注入/控制反转

Spring进阶之路(1)-Spring核心机制:依赖注入/控制反转

原文地址:http://blog.csdn.net/wangyang1354/article/details/50757098


我们经常会遇到这样一种情景,就是在我们开发项目的时候经常会在一个类中调用其他的类中的方法,来完成我们期望的任务,大部分的情况下往往会采用在当前需要的这个类里面new一个实例出来,然后调用他的方法,那么这样的话会有个问题,就是有一天我想改变下这个类,改为其他的名称,那么这时候必须要做的是同时去调用方的类文件中改变这个改变的类的名称。这样的情况是因为代码的耦合带来了后期维护成本的增加,那么spring的出现就可以很好的起到解耦的作用,而他的核心机制就是依赖注入。

依赖注入与控制反转


依赖注入:对于spring而言,将自己置身于spring的立场上去看,当调用方需要某一个类的时候我就为你提供这个类的实例,就是说spring负责将被依赖的这个对象赋值给调用方,那么就相当于我为调用方注入了这样的一个实例。从这方面来看是依赖注入。


控制反转:对于调用方来说,通常情况下是我主动的去创建的,也就是对于这个对象而言我是控制方,我有他产生与否的权力,但是,现在变了,现在变为spring来创建对象的实例,而我被动的接受,从这一点上看,是控制反转。


这两者的意思是一致的,就看你从谁的角度去看这个问题。不同的角度那么看到的问题可能是不一样的。



依赖注入两种方式


1.设值注入


设值注入:通过set的方式注入值.Ioc容器通过成员变量的setter方法来注入被依赖的对象,这种注入方式简单,直观,因而在spring中大量的使用。

下面我们采用实际的例子来体会一下:

假设这样的一个场景,我想打印消息,这样一件事情

首先定义一个MessageService的接口。

[java] 
view plain
 copy

 
在CODE上查看代码片
派生到我的代码片

  1. package com.siti.spring20160227;  
  2.   
  3. public interface MessageService {  
  4.   
  5.     /** 
  6.      * 消息打印 
  7.      */  
  8.     public void printMessage();  
  9. }  



然后实现这个接口,并实现这个方法。

[java] 
view plain
 copy

 
在CODE上查看代码片
派生到我的代码片

  1. package com.siti.spring20160227;  
  2.   
  3. public class MessagePrinter implements MessageService {  
  4.   
  5.     @Override  
  6.     public void printMessage() {  
  7.         System.out.println(“输出消息!”);  
  8.     }  
  9.   
  10. }  



那么对于我而言,我也定义一个person的接口

[java] 
view plain
 copy

 
在CODE上查看代码片
派生到我的代码片

  1. package com.siti.spring20160227;  
  2.   
  3. public interface Person {  
  4.   
  5.     /** 
  6.      * 人发送消息 
  7.      */  
  8.     public void sendMessage();  
  9. }  

我来实现人这个接口

[java] 
view plain
 copy

 
在CODE上查看代码片
派生到我的代码片

  1. package com.siti.spring20160227;  
  2.   
  3. public class WangYang implements Person{  
  4.   
  5.     private MessageService service;  
  6.       
  7.     public void setService(MessageService service) {  
  8.         this.service = service;  
  9.     }  
  10.   
  11.     @Override  
  12.     public void sendMessage() {  
  13.         this.service.printMessage();  
  14.     }  
  15.   
  16. }  

Spring的配置文件:

[java] 
view plain
 copy

 
在CODE上查看代码片
派生到我的代码片

  1. <?xml version=“1.0” encoding=“UTF-8”?>  
  2. <beans xmlns=“http://www.springframework.org/schema/beans”  
  3.        xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance”  
  4.        xsi:schemaLocation=”  
  5. http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd”>  
  6.   
  7. <!– bean definitions here –>  
  8.     <bean id = “messageService” class = “com.siti.spring20160227.MessagePrinter”></bean>  
  9.     <bean id = “wy” class = “com.siti.spring20160227.WangYang”>  
  10.         <property name=“service” ref=“messageService”></property>  
  11.     </bean>  
  12. </beans>  



测试类如下:

[java] 
view plain
 copy

 
在CODE上查看代码片
派生到我的代码片

  1. package com.siti.spring20160227;  
  2.   
  3. import org.springframework.context.ApplicationContext;  
  4. import org.springframework.context.support.ClassPathXmlApplicationContext;  
  5.   
  6. public class MainTest {  
  7.   
  8.     public static void main(String[] args) {  
  9.         ApplicationContext context = new ClassPathXmlApplicationContext(“applicationContext.xml”);  
  10.         Person person = context.getBean(“wy”, Person.class);  
  11.         person.sendMessage();  
  12.     }  
  13. }  


2.构造注入


通过构造函数的方式注入。spring以反射的方式执行带指定参数的构造器,当执行带参数的构造器时就可以通过构造器的参数赋值给成员变量,完成构造注入。


那么现在需求变了,我需要改一些东西,下面可以注意下我主要改动了哪里:

在WangYang这个类中添加有参数和无参数的构造函数:

[java] 
view plain
 copy

 
在CODE上查看代码片
派生到我的代码片

  1. package com.siti.spring20160227;  
  2.   
  3. public class WangYang implements Person{  
  4.   
  5.     private MessageService service;  
  6.       
  7.     <span style=“color:#33ff33;”>public WangYang() {  
  8.         super();  
  9.     }  
  10.       
  11.     public WangYang(MessageService service) {  
  12.         this.service = service;  
  13.     }  
  14.   
  15.     </span>public void setService(MessageService service) {  
  16.         this.service = service;  
  17.     }  
  18.   
  19.     @Override  
  20.     public void sendMessage() {  
  21.         this.service.printMessage();  
  22.     }  
  23.   
  24. }  



在Spring配置文件中,稍微改动,即将原来的设值注入换为构造注入即可。

[java] 
view plain
 copy

 
在CODE上查看代码片
派生到我的代码片

  1. <?xml version=“1.0” encoding=“UTF-8”?>  
  2. <beans xmlns=“http://www.springframework.org/schema/beans”  
  3.        xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance”  
  4.        xsi:schemaLocation=”  
  5. http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd”>  
  6.   
  7. <!– bean definitions here –>  
  8.     <bean id = “messageService” class = “com.siti.spring20160227.MessagePrinter”></bean>  
  9.     <bean id = “wy” class = “com.siti.spring20160227.WangYang”>  
  10.         <!– <property name=“service” ref=“messageService”></property> –>  
  11.         <span style=“color:#33ff33;”><constructor-arg ref=“messageService”></constructor-arg></span>  
  12.     </bean>  
  13. </beans>  


这样再次运行MainTest类,程序正常运行。所以从这里也可以体会到,spring这种解耦的方便性和重要性。



设值注入和构造注入的对比


这两种方式,效果是一样的,注入的时机不同,设值注入是先调用无参的构造函数,创建出实例后然后调用set方法注入属性值。而构造输入是通过在调用构造函数初始化实例的同时完成了注入。


设值注入的优点


1. 通过set的方式设定依赖关系显得更加直观,自然,和javabean写法类似。

2. 复杂的依赖关系,采用构造注入会造成构造器过于臃肿,spring 实例化的时候同时实例化其依赖的全部实例,导致性能下降,set方式可以避免这些问题。

3. 在成员变量可选的情况下,构造注入不够灵活。


构造注入的优点


某些特定的情况下,构造注入比设值注入好一些。

1. 构造注入可以在构造器中决定依赖关系的注入顺序,优先依赖的优先注入,构造注入可以清楚的分清注入的顺序。

2. 组件的调用者无需知道组件内部的依赖关系,符合高内聚原则。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/109124.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • 小程序列表跳转至详情_小程序相互跳转的方法

    小程序列表跳转至详情_小程序相互跳转的方法效果展示:列表页js部分:onLoad:function(options){varthat=this;wx.request({url:’你的接口’,data:{ 接口参数},header:{‘content-type’:’ap…

  • 国外免费空间域名_谷歌空间免费账号

    国外免费空间域名_谷歌空间免费账号 经过了最近一段时间的了解以及本人实际注册,发现了国外有很多的免费空间,但是问题还是很多的,最多的就是注册后访问不了了,可能原因有二,一是网站服务器那边的本身设置,二是我们国家的对外封锁。现将我注册过的网站公布如下,有成功的以及未成功的,总结问题也简要包括,供大家参考,不要再在这个上面浪费更多的时间了。如果大家看到有什么好的空间也请告之,不胜感激:(更新截止日期2007-07-1)注意:以下所说的

  • php array_multisort

    php array_multisort

    2021年10月25日
  • mysql的端口是多少_如何查看db2数据库的端口

    mysql的端口是多少_如何查看db2数据库的端口查看mysql端口号(mysql端口号是多少)2020-05-0722:11:45共10个回答如何查看mysql的端口号1使用命令showglobalvariableslike’port’;查看端口号2修改端口,编辑/etc/my.cnf文件,早期版本有可能是my.conf文件名,增加端口参数,并且设定端口,注意该端口未被使用,保存退出.总结:注意修改的端口不要被占用,而且要有规划,不要轻意的总…

  • pycharm连接mysql操作_使用pycharm连接数据库及进行一些简单的操作「建议收藏」

    pycharm连接mysql操作_使用pycharm连接数据库及进行一些简单的操作「建议收藏」一般的开发过程中,我们需要使用pycharm来连接数据库,从而来进行对数据库的操作,这里主要连接的是mysql数据库,另外加了使用pandas模块读取数据库的操作,基本的操作如下所示:直接连接数据库importpymysqlconn=pymysql.connect(host=’localhost’,port=3306,db=’joker’,user=’root’,password=’root…

  • GWT 优点和缺点「建议收藏」

    GWT 优点和缺点「建议收藏」GWT 优点和缺点

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号