Spring依賴注入原理學習
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: |
測試類:
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, 解析到了
ExecuteAStatement bean1 = new ExecuteAStatement();
springEngine.put("userDAO", bean1);
再往下執行, 發現 property 定義:
到了這裡, 就知道應該呼叫 bean1.setDataSource(DataSource) 方法了。 可以接著執行, 發現
, 哦, 這個方法的引數還沒有呢, 是個 bean 的引用, 好了, 要呼叫這個方法, 還是先 new 一個名字為 myDataSource 的 bean2 吧。 就跳到下面尋找 myDataSource 的定義, 找到了:
|
像以前一樣, 先例項化這個類, 然後看到 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
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/13270562/viewspace-217880/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- spring框架學習 依賴注入Spring框架依賴注入
- spring 依賴注入的學習Spring依賴注入
- Spring學習(三)依賴注入Spring依賴注入
- Angular 依賴注入原理Angular依賴注入
- Spring依賴注入Spring依賴注入
- Spring依賴注入---Spring依賴注入
- Spring IOC——依賴注入Spring依賴注入
- Spring 依賴注入 DISpring依賴注入
- spring 的依賴注入Spring依賴注入
- Spring 原始碼分析之 bean 依賴注入原理(注入屬性)Spring原始碼Bean依賴注入
- Angular4學習之依賴注入Angular依賴注入
- Spring系列.依賴注入配置Spring依賴注入
- Spring.Net 依賴注入Spring依賴注入
- 大白話spring依賴注入Spring依賴注入
- Spring 依賴注入的理解Spring依賴注入
- Spring學習:簡單實現一個依賴注入和迴圈依賴的解決Spring依賴注入
- net5學習筆記---依賴注入筆記依賴注入
- Spring的依賴注入的方式Spring依賴注入
- 「Laravel 核心學習」類的反射和依賴注入Laravel反射依賴注入
- 死磕Spring原始碼-依賴注入Spring原始碼依賴注入
- Spring原始碼解析——依賴注入(二)Spring原始碼依賴注入
- Spring 控制反轉和依賴注入Spring依賴注入
- Spring原始碼系列:依賴注入-引言Spring原始碼依賴注入
- Spring系列第八講 依賴注入之手動注入Spring依賴注入
- Spring原始碼系列:依賴注入(三)-屬性注入Spring原始碼依賴注入
- 30個類手寫Spring核心原理之依賴注入功能(3)Spring依賴注入
- angular依賴注入Angular依賴注入
- XUnit 依賴注入依賴注入
- Struts 依賴注入依賴注入
- Golang 依賴注入設計哲學|12.6K 🌟 的依賴注入庫 wireGolang依賴注入
- 依賴倒置(DIP)與依賴注入(DI)依賴注入
- 依賴注入?依賴注入是如何實現解耦的?依賴注入解耦
- 「轉」Laravel 依賴注入原理(詳細註釋)Laravel依賴注入
- .NET 透過原始碼深究依賴注入原理原始碼依賴注入
- 【Spring】Spring依賴注入與控制反轉理解Spring依賴注入
- 手寫Spring---DI依賴注入(2)Spring依賴注入
- spring常用的三種依賴注入方式Spring依賴注入
- Spring原始碼系列:依賴注入(二)createBeanSpring原始碼依賴注入Bean