你的位置:首页 > ASP.net教程

[ASP.net教程]spring学习(二)


spring第二个特性是依赖注入。

         学习依赖注入,首先应该明白两个问题:1,谁依赖谁;2,谁注入,注入什么?

         首先还是看代码:

         还是这个bean:

package testSpring.business.bean;import org.springframework.stereotype.Repository;import testSpring.business.iface.IPrint;/**  * UserBean : * @author xuejupo jpxue@travelsky.com * create in 2016-2-16 上午9:22:39   */public class UserBean implements IPrint{  @Override  public String printObject() {    // TODO Auto-generated method stub    System.out.println("打印对象UserBean:");    return "abc";  }}

 然后,我的业务逻辑需要在这个bean里使用上边那个bean:

 

package testSpring.business.impl;import testSpring.business.iface.IPrint;/**  * Print : * @author xuejupo jpxue@travelsky.com * create in 2016-2-16 上午10:23:37   */public class Print {  //需要打印的bean,注入的入口(需要注入的对象)  private IPrint printBean;  private String name;  public void print(){    System.out.println("注入的name:"+name);    this.printBean.printObject();  }    /**   * setPrintBean: set方法,set注入必备方法  * @param printBean   * void 返回类型    */  public void setPrintBean(IPrint printBean){    this.printBean = printBean;  }    /**   * setName: set方法,set注入必备方法  * @param name   * void 返回类型    */  public void setName(String name){    this.name = name;  }}

普通的使用print类的客户端代码:

Print p = new Print();p.setPrintBean(new UserBean());print.print();

也是挺简单的代码,但是,客户端代码就和具体的类print和userbean的代码强耦合在一块了,不符合开闭原则,所以就需要利用依赖注入往客户端代码中注入Pring对象,往Print类中注入Userbean对象。

 

       

<?  ="http://www.w3.org/2001/  ="http://www.springframework.org/schema/aop"   ="http://www.springframework.org/schema/p"  xsi:schemaLocation="http://www.springframework.org/schema/beans  http://www.springframework.org/schema/beans/spring-beans-3.2.xsd  http://www.springframework.org/schema/tx  http://www.springframework.org/schema/tx/spring-tx-3.2.xsd  http://www.springframework.org/schema/aop   http://www.springframework.org/schema/aop/spring-aop-3.2.xsd   http://www.springframework.org/schema/context  http://www.springframework.org/schema/context/spring-context-3.2.xsd">  <context:annotation-config/>  <!-- 注册javabean -->  <bean id="userBean" class="testSpring.business.bean.MyBean" />    <!-- 注册javabean -->  <bean id="printBean" class="testSpring.business.impl.Print" >  <!-- 注入javabean中的参数 -->    <property name = "printBean" ref = "userBean"></property>    <property name = "name" value = "haha"></property>  </bean></beans>

客户端代码:

//读取配置文件(将配置文件中的bean加载进内存)    ApplicationContext ctx = new ClassPath);    //获取的实例    Print bean=(Print)ctx.getBean("printBean");     //调用方法     bean.print();

 打印结果:

 
注入的name:haha打印对象MyBean:

可以看到,利用

 

        回答文中开头两个问题:1.客户端代码中,具体对象的创建依赖于

       说一下自己理解中的IOC容器: 网上搜过,没有什么让我满意的回答,只能自己理解一下。我理解的IOC容器,其实就是web服务启动后,tomcat(或其他的web服务器)加载applicationContext.

        如果看过我前一篇博客的,肯定会说依赖注入和控制反转这不一样嘛。。。。他俩确实是一回事。。。依赖注入也可以叫控制反转,就是将控制权交给配置文件。。   不过我个人喜欢这样理解:对bean的注册叫控制反转,对bean中参数的初始化叫依赖注入。个人觉得,知道是一回事就行,怎么容易让你理解怎么来。

       说一下依赖注入的好处:

       最主要的还是解耦。便于数据源的切换:比如我想在print类里打印另一个bean,只需要修改

       这说的还是有点虚,可能真实环境更能说明问题:   公司最近遇到一个需求,需要两拨人共同开发:一波开发公司内网接口---A组,一波开发公司对外实现(相当于客户端)---B组。客户端开发是依赖于内网功能的,但是又不能等待内网的同学先开发完,所以领导决定:A组的人,先把需要实现的功能,以接口(interface)的方式暴漏给B组的同学,然后两组各自为政,开发完以后合并就行了。

        假设A组暴漏了一个接口如下:

public interface MyInterface{    void myMethod();}

但是A组这个接口的实现还没写,所以我B组的人想用这个接口编程,两个办法(我是菜鸟,可能有别的办法,可以指点):

 

        第一:

       MyInterface  bean = null;//这里需要后期填充具体接口实现  


        然后,当A组的把实现给我们之后,我们再通过全局搜索,把bean全都赋值给具体的实现。这时候,万一A组的人脑子一抽,说哎呀,我给你的实现不对,是应该给C组的,你用另一个,那我又要全局修改所有的代码。。。。(这就是强耦合,A组修改代码,会导致B组人代码必须修改)

 

        然后,第二种是酱:

         用一个配置文件:

<bean id="myInterface" class="xxx.xxx.xxx.xxxx" /><!-- 注册我的javabean -->  <bean id="printBean" class="testSpring.business.impl.Print" >  <!-- 注入接口实现 -->    <property name = "myInterface" ref = "myInterface"></property>  </bean>

 然后在我已经注册的javaBean里只需要这样:

private MyInterface myInterface;

就可以使用接口的具体实现了,而且无论你A组怎么改,我B组的代码不用修改,只改配置文件就行(当然,前提是A组的接口不能变),这就是弱耦合,也是设计原则里面著名的依赖倒置原则(依赖接口而不依赖于具体实现)。