[java][源碼分析]paoding-rose-jade框架源碼分析(1)

在實習期間遇到最多的兩個框架就是spring和paoding-rose了,所以看完spring源碼分析的書,我就迫不及待的開始找paoding-rose的書了。可惜沒找到,所以就自己動手分析吧。
spring源碼分析的書可以在這裏下載:
http://download.csdn.net/download/qq523786283/9946552

1.正文

paoding-rose框架包含很多子框架,而我實習的公司項目中只用到paoding-rose-jade。所以我這裏分析的是paoding-rose-jade。
我選擇的分析的入口是下面圖片裏選擇的類:
這裏寫圖片描述
理由是我們可以通過單元測試類更輕鬆的知道代碼作者的設計意圖。
先貼出單元測試源碼:

/**
 * 通過集成DAO和JadeFactory,驗證 {@link DataSources}的可用
 * 
 * @author 王志亮 [[email protected]]
 * 
 */
public class DataSourcesTest {

    @DAO
    interface UserDAO {

        @SQL("create table user (id int, name varchar(200));")
        void createTable();

        @SQL("insert into user (id, name) values(:1, :2);")
        void insert(int id, String name);

        @SQL("select name from user where id=:1")
        String getName(int id);

        @SQL("select name from user order by id asc")
        String[] findNames();
    }

    // init方法負責初始化dao
    private UserDAO dao;

    @Before
    public void init() {
        DataSource dataSource = DataSources.createUniqueDataSource();
        JadeFactory factory = new JadeFactory(dataSource);
        dao = factory.create(UserDAO.class);
        dao.createTable();
        dao.insert(1, "zhiliang1");
        dao.insert(2, "zhiliang2");
    }

    @Test
    public void testGetName() {
        Assert.assertEquals("zhiliang1", dao.getName(1));
    }

    @Test
    public void testFindNames() {
        String[] names = dao.findNames();
        Assert.assertEquals(2, names.length);
        Assert.assertEquals("zhiliang1", names[0]);
        Assert.assertEquals("zhiliang2", names[1]);
    }

}

相信用過paoding-rose-jade都會對下面這段代碼感到非常的熟悉,沒用過的也能清晰知道它定義了一個接口。唯有@DAO@SQL註解需要我們推測它們的用途。

    @DAO
    interface UserDAO {

        @SQL("create table user (id int, name varchar(200));")
        void createTable();

        @SQL("insert into user (id, name) values(:1, :2);")
        void insert(int id, String name);

        @SQL("select name from user where id=:1")
        String getName(int id);

        @SQL("select name from user order by id asc")
        String[] findNames();
    }

這些推測都暫且放下,我先看到被 @Before 註解標記的 init() 方法。根據junit4單元測試類的規則,每個 @Test 標記的方法運行前都有運行一次被 @Before 註解標記的方法。
init()
1.生成一個數據源對象(DataSource)
2.通過數據源對象(DataSource)生成一個工廠對象(JadeFactory)
3.通過調用JadeFactory對象的create(UserDAO.class) 方法,獲得一個實現UserDao接口的對象。
4.接下來就是我們熟悉的數據庫操作了。

    @Before
    public void init() {
        DataSource dataSource = DataSources.createUniqueDataSource();
        JadeFactory factory = new JadeFactory(dataSource);
        dao = factory.create(UserDAO.class);
        dao.createTable();
        dao.insert(1, "zhiliang1");
        dao.insert(2, "zhiliang2");
    }

看到第3步時,相信大家都有一個相同的問題:
我們沒實現UserDAO接口,何來一個實現UserDAO接口的對象呢?
對於這個,我給出的推測是paoding-rose-jade使用了動態代理。
爲什麼說是“推測”呢?因爲我是抱着學習的心態寫這篇博客的,無論對錯都是我分析的過程,也就是說我是一邊開始學習paoding-rose-jade框架源碼一邊寫博客的。
現在就讓我們一起解答這個問題吧。
這時選擇單元測試類作爲入口的另一個好處就顯現出來了—我們可以通過調試代碼來解決我們的問題。
首現如圖下個斷點,並debug:
這裏寫圖片描述
從調試信息中我們可以看到dao對象在內存中的信息是{$Proxy3@1308} ,從名稱可以推測它是一個代理對象,當然這並不嚴謹。
所以我們按F7跟入createTable() 方法繼續調試。如下:
這裏寫圖片描述

這裏寫圖片描述
跟進去後我們發現我們到了一個陌生而又熟悉的invoke()方法.
沒錯這個是java動態代理的方法,這證明了我們的推測是正確的。沒學過java動態代理的同學可能會感到一頭霧水,這時候就需要你們自己去百度或谷歌一下了。
從調試信息中我們可以看到invoke()方法中傳進去的Proxy對象在內存中的信息是{$Proxy3@1308} ,所以這個就是前面的dao對象。
接下來的內容就下一篇再繼續吧。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章