`
zhang_zling
  • 浏览: 95483 次
  • 性别: Icon_minigender_2
  • 来自: 济南
社区版块
存档分类
最新评论

Spring 依赖注入的理解

阅读更多
首先我们来看看 Spring 参考文档的 11.2.6. 执行SQL语句 这里有个代码片断:

import javax.sql.DataSource;
      import org.springframework.jdbc.core.JdbcTemplate;
      public class ExecuteAStatement {
          private JdbcTemplate jt;
           
        private DataSource dataSource;
          public void doExecute() {
               
        jt = new JdbcTemplate(dataSource);
               
        jt.execute("create table mytable (id integer, name varchar(100))");
           
        }
          public void setDataSource(DataSource dataSource) {
               
        this.dataSource = dataSource;
           
        }
        }


  这个就是普通的 Java 类, 再参考 11.2.4. DataSource接口, 这里的另一个代码片断:

DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("org.hsqldb.jdbcDriver");
dataSource.setUrl("jdbc:hsqldb:hsql://localhost:");
dataSource.setUsername("sa");
dataSource.setPassword("");


  当然上面的连接方式可以配置成我们课程里面介绍的 MyEclipse Derby 的数据库连接:

org.apache.derby.jdbc.ClientDriver
jdbc:derby://localhost:1527/myeclipse;create=true
app
app


  我们可以写一个测试类来执行代码:

import org.springframework.jdbc.datasource.DriverManagerDataSource;
public class TestTemplate {
  public static void main(String[] args) {
    // 新建一个数据源对象
    DriverManagerDataSource dataSource = new DriverManagerDataSource();
    dataSource.setDriverClassName("org.hsqldb.jdbcDriver");
    dataSource.setUrl("jdbc:hsqldb:hsql://localhost:");
    dataSource.setUsername("sa");
    dataSource.setPassword("");
  
    // 新建一个ExecuteAStatement 对象
    ExecuteAStatement eas = new ExecuteAStatement();
    // 给执行表达式的对象关联数据源(也就是常说的注入, 通过 JavaBean 的 setXxx 方法关联起来)
    eas.setDataSource(dataSource);
    // 执行功能代码
    eas.doExecute();
  }
}


  这个代码可以跑通, 就是普通的编程方式, 大家可以去看刚才介绍的文档附近的详细说明。

  那么如果用 Spring 来做, 代码会变成这样:

  ExecuteAStatement 类代码保持不变, 多了个 beans.xml:

ExecuteAStatement 类代码保持不变, 多了个 beans.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">

<bean id="userDAO" class="ExecuteAStatement">
<property name="dataSource">
<ref bean="myDataSource" />
</property>
</bean>

<bean id="myDataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName">
<value>org.hsqldb.jdbcDriver</value>
</property>

<property name="url">
<value>jdbc:hsqldb:hsql://localhost:</value>
</property>

<property name="username">
<value>sa</value>
</property>

<property name="password">
<value></value>
</property>
</bean>

</beans>

 


  测试类:

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
public static void main(String[] args) throws IOException {
  ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
  ExecuteAStatement eas =(ExecuteAStatement)context.getBean("userDAO");
      // 执行功能代码
      eas.doExecute();
}
}


  和上面的 TestTemplate 类相比, 就会发现 new DriverManagerDataSource() 这个过程不用我们写了, 运行的时候会发现一切都执行的好好的, 也就是常说的 ExecuteAStatement 的 dataSource 这个属性被注入了。

  那么这个过程到底该如何理解呢? Spring 是一个对象池, 可以简化为一个 Map, 存多个主键和对象的映射。 那么 Spring 运行的过程中, 会根据 beans.xml 一步步进行必要的解析工作:

  Map springEngine = new HashMap();

  OK, 解析到了

  <bean id="userDAO" class="ExecuteAStatement">, 发现 bean 定义, 那就新建一个实例存到对象池里吧, 主键就是 userDAO, 值就是对象:

  ExecuteAStatement bean1 = new ExecuteAStatement();

  springEngine.put("userDAO", bean1);

  再往下执行, 发现 property 定义:

  <property name="dataSource">

  到了这里, 就知道应该调用 bean1.setDataSource(DataSource) 方法了。 可以接着执行, 发现

  <ref bean="myDataSource" />, 哦, 这个方法的参数还没有呢, 是个 bean 的引用, 好了, 要调用这个方法, 还是先 new 一个名字为 myDataSource 的 bean2 吧。 就跳到下面寻找 myDataSource 的定义, 找到了:

<bean id="myDataSource"  class="org.springframework.jdbc.datasource.DriverManagerDataSource">  <property name="driverClassName">      <value>org.hsqldb.jdbcDriver</value>  </property>    <property name="url">      <value>jdbc:hsqldb:hsql://localhost:</value>  </property>    <property name="username">      <value>sa</value>  </property>    <property name="password">      <value></value>  </property>       </bean>


  像以前一样, 先实例化这个类, 然后看到 property 表情就调用对应的 setXxx() 这样的方法, 相当于下面一段代码:

// 新建一个数据源对象
    DriverManagerDataSource bean2 = new DriverManagerDataSource();
    bean2.setDriverClassName("org.hsqldb.jdbcDriver");
    bean2.setUrl("jdbc:hsqldb:hsql://localhost:");
    bean2.setUsername("sa");
    bean2.setPassword("");


  不是还有个 bean 的 id 名字为 myDataSource 嘛, 那就把它存到对象池里面:

  springEngine.put("myDataSource", bean2);

  好了, 最后就是把他们两个关联起来了, 通过 ref 里指定的 bean id 名来关联起来:

  // 省略类型转换的代码

  springEngine.get("userDAO")。setDataSource(springEngine.get("myDataSource"));

  最后返回给用户的就是一个对象池(一个 Map)了, 所以别人调用的时候, 就发现 springEngine.get("userDAO") 回来的类的 dataSource 属性已经被实例化过了, 这些都是 Spring 幕后工作的代码, 通过反射机制来实现。

  所以最后写代码调用:

  context.getBean("userDAO") 的时候, 得到的是 ExecuteAStatement, 这时候还有一个 myDataSource, 也可以被调用:

  context.getBean("myDataSource"), 得到的是 DriverManagerDataSource.

分享到:
评论

相关推荐

    spring依赖注入的理解.docx

    Spring中的依赖注入就是上面说的外部,实例不在由程序员实例化,而是通过spring容器帮我们new指定实例并且将实例注入到需要该... 我们不用关心Car的变化,实例之间的依赖关系由IOC容器负责了,等待Spring依赖注入。

    Spring依赖注入原理解析.doc

    对spring依赖注入原理进行了详细说明和解析,过程详实,思路清晰,便于新手理解和学习spring依赖注入的核心要义。

    spring 控制反转和依赖注入.docx

    spring 控制反转和依赖注入进行基础知识的生命周期、延迟初始化、装配方式等进行案例总结使用。从而对spring基础知识更加理解。

    Spring.Net依赖注入例子

    Spring.Net,简单例子。从这个例子可以理解通过配置方式实现依赖注入

    Spring依赖注入的三种方式实例详解

    主要介绍了Spring依赖注入的三种方式的相关资料,希望通过本文能帮助到大家,让大家理解掌握这部分内容,需要的朋友可以参考下

    Spring_01_入门篇_依赖注入(控制反转)_ANN

    此文档仅供初学者学习,包括Spring的依赖注入(控制反转)的详细实例。以三层贯穿实例(持久层、业务层、控制层),由MAIN方法直接调用测试用例。

    spring 实例的工厂方法 依赖注入属性,都使用property 元素确

    spring练习 刚刚学spring,做了个小小小项目,来加深理解。... ·其他依赖注入属性,都使用property 元素确定参数值。 Person.java PersonFactory.java Chinese.java American.java bean.xml SpringTest.java

    理解Spring中的依赖注入和控制反转

    主要介绍了理解Spring中的依赖注入和控制反转,具有一定参考价值,需要的朋友可以了解下。

    详解Spring的核心机制依赖注入

    一、理解依赖注入 依赖注入(Dependency Injection) = 控制反转(Inversion ofControl,IoC):当某个Java实例(调用者)需另一个Java实例(被调用者)时,在依赖注入模式下,创建被调用者的工作不再由调用者来完成,因此...

    Spring——IOC(控制反转)与DI(依赖注入).docx

    IOC与DI的理解及使用 控制反转IOC(Inversion of Control)是一种设计思想,DI(依赖注入)是实现IOC的一种方法 。... 在Spring中实现控制反转的是IOC容器 ,其 实现方法是依赖注入 (Dependency Injection,DI)

    laravel框架中你所用到的依赖注入详解

    Java的依赖注入已经是一个很常见的概念了,Spring框架主要就是解决了这一点,在PHP的laravel框架中,也出现了依赖注入的方式。 依赖注入就控制反转的一种是实现方式,面向对象的特征的重要体现,那么依赖注入中什么...

    spring1.1开发理解

    Spring容器的特点 (1)容器对对象的管理 a.创建时机:默认和容器一起创建。... Dependecy Injection 依赖注入 Spring 使用DI技术实现了IoC控制。 a.setter注入 b.构造注入 c.接口注入(以后了解)

    深入解析Java Spring框架

    详述对Spring的依赖注入机制的理解,以及它对代码可维护性和灵活性的影响。分享在实际项目中如何巧妙运用依赖注入的经验。 三、实际项目经验分享 3.1 构建企业级应用 回顾参与的企业级应用项目,分享在项目中面临...

    Spring自动注入的简单实现

     用过Spring的同学都知道,Spring利用注解来实现依赖注入,使得各个类之间的耦合性极大的降低了。但是仅仅是使用,并不能理解到Spring内部是怎么实现的。笔者没有看过Spring的源码。只能从自己的角度来谈谈Spring...

    Spring攻略PDF版

     1.4 理解不同类型的依赖注入   1.4.1 问题描述   1.4.2 解决方案   1.4.3 实现方法   1.5 使用配置文件配置容器   1.5.1 问题描述   1.5.2 解决方案   1.5.3 实现方法   1.6 小...

    CH02-IOC依赖注入.pptx

    理解什么是IoC和DI。 理解构造注入 理解不同数据类型的注入方法 掌握p命名空间注入 Bean自动装配

    第一个Spring程序(DI的实现).docx

    依赖注入:Dependency Injection(DI)与控制反转(IoC),不同角度但是同一个...在spring容器的角度看来,spring容器负责将被依赖对象赋值给成员变量,这相当于为实例对象注入了它所依赖的实例,这是spring的依赖注入。

    Spring攻略中文版PDF

     1.4 理解不同类型的依赖注入   1.4.1 问题描述   1.4.2 解决方案   1.4.3 实现方法   1.5 使用配置文件配置容器   1.5.1 问题描述   1.5.2 解决方案   1.5.3 实现方法   1.6 小...

    spring课堂笔记.docx

    Spring 容器:介绍了 Spring 容器的不同类型,包括 BeanFactory 和 ApplicationContext,以及它们在管理对象生命周期和依赖注入方面的作用。 依赖注入:详细解释了依赖注入的原理和用法,以及如何配置和管理 Bean ...

    Spring攻略英文版(附带源码)

     1.4 理解不同类型的依赖注入   1.4.1 问题描述   1.4.2 解决方案   1.4.3 实现方法   1.5 使用配置文件配置容器   1.5.1 问题描述   1.5.2 解决方案   1.5.3 实现方法   1.6 小结   第...

Global site tag (gtag.js) - Google Analytics