`
zhang_zling
  • 浏览: 96437 次
  • 性别: 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依赖注入底层详解

    Spring依赖注入是Spring框架的核心特性之一,它极大地简化了Java应用程序的开发,使得对象之间的依赖关系得以解耦,提高了代码的可测试性和可维护性。本文将深入探讨Spring依赖注入的底层实现机制。 首先,我们要...

    spring依赖注入的实现原理

    本篇文章将深入探讨Spring依赖注入的实现原理,以及如何通过源码理解和使用这一特性。 一、依赖注入简介 依赖注入的基本思想是,对象不应该负责创建或查找它所依赖的对象,而应该由外部容器(如Spring框架)来负责...

    spring学习:依赖注入的几种方式讨论

    本文将深入探讨Spring中的依赖注入实现方式,以及如何通过样例文件`sample-autoconfig`进行理解和实践。 一、XML配置的依赖注入 在Spring早期版本中,XML配置是最常见的DI方式。开发者在Spring的配置文件(如`...

    Spring学习笔记(6)----编码剖析Spring依赖注入的原理

    本篇学习笔记将深入剖析Spring依赖注入的原理,通过源码分析帮助我们理解这一核心机制。 首先,依赖注入允许我们解耦组件之间的关系,使得各个组件可以独立地进行开发、测试和维护。在Spring中,DI主要通过两种方式...

    Spring依赖注入的方式

    在Spring框架中,依赖注入(Dependency Injection,简称DI)是一种重要的设计模式,它使得对象之间的耦合度降低,提高了代码的可测试性和可维护性。本文将深入探讨Spring中的依赖注入方式,包括构造器注入、设值注入...

    Spring依赖注入检查.

    Spring依赖注入是Spring框架的核心特性之一,它极大地简化了Java应用程序的开发,使得对象之间的依赖关系得以解耦,提高了代码的可测试性和可维护性。本文将深入探讨Spring依赖注入的概念、工作原理以及如何在实际...

    spring依赖注入三种方式 测试源码

    通过阅读和理解这些源码,你可以更深入地了解Spring依赖注入的工作原理及其在项目中的具体使用。 在进行依赖注入时,Spring使用BeanFactory或ApplicationContext作为容器,负责创建、管理和装配Bean。容器读取配置...

    模仿Spring依赖注入

    【Spring依赖注入详解】 在Java开发中,Spring框架以其强大的依赖注入(Dependency Injection,简称DI)功能而闻名。依赖注入是一种设计模式,它允许我们解耦组件,使我们的应用程序更加灵活,易于测试和维护。本篇...

    spring依赖注入例子

    Spring框架的依赖注入(Dependency Injection,简称DI)...通过阅读和分析这些代码,你可以更深入地理解Spring的依赖注入机制。在实际开发中,你可以根据需求调整配置,如添加数据库连接池、使用不同的数据访问技术等。

    如何实现Spring依赖注入 AOP.rar

    Spring框架是Java开发中广泛应用的一个轻量级容器,它的核心特性是依赖注入(Dependency Injection,简称DI)和面向切面编程(Aspect Oriented Programming,简称AOP)。这两个特性极大地简化了Java应用程序的开发和...

    spring依赖注入bean

    **Spring 依赖注入 (DI) 与 Bean** Spring 框架的核心特性之一就是依赖注入(Dependency Injection,简称 DI),这是一种设计模式,它允许我们控制组件之间的耦合,而不是让组件自行创建它们所依赖的对象。这有助于...

    Spring依赖注入使用setter设注入demo

    在这个名为“Spring依赖注入使用setter设注入demo”的示例中,我们将深入探讨如何通过setter方法实现Spring的依赖注入。 首先,理解依赖注入的基本思想:对象之间的依赖关系不是由对象自身管理,而是由外部容器(在...

    Spring依赖注入使用构造设注入demo

    本篇将详细讲解如何使用构造器注入作为Spring依赖注入的一种方式,并通过一个完整的可运行示例——"SpringIOCTest2"来加深理解。 首先,理解依赖注入的概念。依赖注入允许我们不在类内部创建对象,而是通过外部源...

    Spring Ioc 注解 依赖注入

    ### Spring IoC与注解依赖注入详解 #### 一、Spring框架简介 Spring框架是由Rod Johnson创建的一...以上就是关于Spring IoC容器以及注解依赖注入的相关知识点介绍,希望能够帮助大家更好地理解和掌握这一重要的技术。

    spring依赖注入基础知识.rar

    Spring依赖注入(Dependency Injection,简称DI)是Spring框架的核心特性之一,它允许对象之间的依赖关系在运行时由外部容器管理,而不是由代码内部硬编码。这样可以提高代码的可测试性、可维护性和松耦合性。下面...

    spring依赖注入的理解.docx

    依赖注入(Dependency Injection,简称DI)是Spring框架的核心特性,也是实现控制反转(Inversion of Control,简称IoC)的一种方式。它旨在提高代码的可重用性、可...理解和熟练应用依赖注入是掌握Spring框架的关键。

    模拟spring依赖注入

    模拟Spring的依赖注入,旨在理解其核心机制,让我们一起深入探讨这一主题。 首先,我们要明白什么是依赖注入。在传统的编程中,一个对象通常会直接创建或查找它所依赖的对象,这会导致类之间的紧密耦合。依赖注入则...

    Spring依赖注入使用实例工厂设注入demo

    在Spring框架中,依赖注入(Dependency Injection,简称DI)是一种重要的设计模式,它使得对象之间的耦合度降低,提高了代码的可测试性和可维护性。本示例将深入讲解如何在Spring中通过实例工厂方法实现依赖注入,并...

    Spring依赖注入DI.zip

    下面我们将深入探讨Spring依赖注入的概念、工作原理以及如何在实践中应用。 1. **依赖注入概念**: - 依赖:一个类对另一个类的使用称为依赖。 - 注入:将依赖的对象传递给需要它的类,而不是由类自己去创建或...

    Spring依赖注入使用静态工厂设注入demo

    在Spring框架中,依赖注入(Dependency Injection,DI)是一种核心设计模式,它使得对象之间的依赖关系得以解耦,提高了代码的可测试性和可维护性。本篇将详细讲解如何使用静态工厂方法进行依赖注入,结合提供的...

Global site tag (gtag.js) - Google Analytics