熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Java開源技術 >> 正文

Spring 依賴注入原理學習

2013-11-23 20:39:36  來源: Java開源技術 

  首先我們來看看 Spring 參考文檔的 執行SQL語句 這裡有個代碼片斷

  

  import javaxsqlDataSource; import orgsprireJdbcTemplate; public class ExecuteAStatement { private JdbcTemplate jt; private DataSource dataSource; public void doExecute() { jt = new JdbcTemplate(dataSource); jtexecute(create table mytable (id integer name varchar())); } public void setDataSource(DataSource dataSource) { thisdataSource = dataSource; } }

  這個就是普通的 Java 類 再參考 DataSource接口 這裡的另一個代碼片斷

  

  DriverManagerDataSource dataSource = new DriverManagerDataSource(); dataSourcesetDriverClassName(orghsqldbjdbcDriver); dataSourcesetUrl(jdbc:hsqldb:hsql://localhost:); dataSourcesetUsername(sa); dataSourcesetPassword();

  當然上面的連接方式可以配置成我們課程裡面介紹的 MyEclipse Derby 的數據庫連接

  

  orgapachederbyjdbcClientDriver jdbc:derby://localhost:/myeclipse;create=true app app

  我們可以寫一個測試類來執行代碼

  

  import orgspringframeworkjdbcdatasourceDriverManagerDataSource; public class TestTemplate { public static void main(String[] args) { // 新建一個數據源對象 DriverManagerDataSource dataSource = new DriverManagerDataSource(); dataSourcesetDriverClassName(orghsqldbjdbcDriver); dataSourcesetUrl(jdbc:hsqldb:hsql://localhost:); dataSourcesetUsername(sa); dataSourcesetPassword(); // 新建一個ExecuteAStatement 對象 ExecuteAStatement eas = new ExecuteAStatement(); // 給執行表達式的對象關聯數據源(也就是常說的注入 通過 JavaBean 的 setXxx 方法關聯起來) eassetDataSource(dataSource); // 執行功能代碼 easdoExecute(); } }

  這個代碼可以跑通 就是普通的編程方式 大家可以去看剛才介紹的文檔附近的詳細說明

  那麼如果用 Spring 來做 代碼會變成這樣

  ExecuteAStatement 類代碼保持不變 多了個 beansxml

  

  ExecuteAStatement 類代碼保持不變 多了個 beansxml:
<?xml version= encoding=UTF?>
<beans
xmlns=
xmlns:xsi=instance
xsi:schemaLocation= beansxsd>

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

  <bean id=myDataSource
class=orgspringframeworkjdbcdatasourceDriverManagerDataSource>
<property name=driverClassName>
<value>orghsqldbjdbcDriver</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 orgntextApplicationContext; import orgntextsupportClassPathXmlApplicationContext; public class Test { public static void main(String[] args) throws IOException { ApplicationContext context = new ClassPathXmlApplicationContext(beansxml); ExecuteAStatement eas =(ExecuteAStatement)contextgetBean(userDAO); // 執行功能代碼 easdoExecute(); } }

  和上面的 TestTemplate 類相比 就會發現 new DriverManagerDataSource() 這個過程不用我們寫了 運行的時候會發現一切都執行的好好的 也就是常說的 ExecuteAStatement 的 dataSource 這個屬性被注入了

  那麼這個過程到底該如何理解呢? Spring 是一個對象池 可以簡化為一個 Map 存多個主鍵和對象的映射 那麼 Spring 運行的過程中 會根據 beansxml 一步步進行必要的解析工作

  Map springEngine = new HashMap()

  OK 解析到了

  <bean id=userDAO class=ExecuteAStatement> 發現 bean 定義 那就新建一個實例存到對象池裡吧 主鍵就是 userDAO 值就是對象

  ExecuteAStatement bean = new ExecuteAStatement()

  springEngineput(userDAO bean

  再往下執行 發現 property 定義

  <property name=dataSource>

  到了這裡 就知道應該調用 beansetDataSource(DataSource) 方法了 可以接著執行 發現

  <ref bean=myDataSource /> 這個方法的參數還沒有呢 是個 bean 的引用 好了 要調用這個方法 還是先 new 一個名字為 myDataSource 的 bean 就跳到下面尋找 myDataSource 的定義 找到了

  

  <bean id=myDataSource
class=orgspringframeworkjdbcdatasourceDriverManagerDataSource>
<property name=driverClassName>
<value>orghsqldbjdbcDriver</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 bean = new DriverManagerDataSource(); beansetDriverClassName(orghsqldbjdbcDriver); beansetUrl(jdbc:hsqldb:hsql://localhost:); beansetUsername(sa); beansetPassword();

  不是還有個 bean 的 id 名字為 myDataSource 嘛 那就把它存到對象池裡面

  springEngineput(myDataSource bean

  好了 最後就是把他們兩個關聯起來了 通過 ref 裡指定的 bean id 名來關聯起來

  // 省略類型轉換的代碼

  springEngineget(userDAOsetDataSource(springEngineget(myDataSource))

  最後返回給用戶的就是一個對象池(一個 Map)了 所以別人調用的時候 就發現 springEngineget(userDAO) 回來的類的 dataSource 屬性已經被實例化過了 這些都是 Spring 幕後工作的代碼 通過反射機制來實現

  所以最後寫代碼調用

  contextgetBean(userDAO) 的時候 得到的是 ExecuteAStatement 這時候還有一個 myDataSource 也可以被調用

  contextgetBean(myDataSource 得到的是 DriverManagerDataSource


From:http://tw.wingwit.com/Article/program/Java/ky/201311/28844.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.