本系列博文,將會一步一步介紹如何構建一個輕量級的web框架jbeer git地址:http://git.oschina.net/bieber/jbeer
通過本人差很少半年的糾結,今天終於把JBeer的0.1版本完成了。Jbeer具有MVC,IOC,AOP,ORM,IN18,PropertiesContext,簡單聲明式事務以及自帶Datasource功能。開發Jbeer的目的是爲了總結J2EE框架原理,從而在一些細節上加入一些本身的想法,最終目的是我的的一個總結。當初第一次看到JFinal源碼的時候,知道了MVC框架內部的原理原來是那樣的,第一次參與了Smart4j(原來smart),瞭解了輕量級的框架是那樣子的。因而便萌發了本身也作一個這樣的東西來總結一下。JBeer並非站在代替JFinal,smart4j或者ssh框架去實現的,而是一次總結的過程。以前只是站在框架的外圍看它,當你站到框架內部去看它的時候,你會發現你才真正的理解了它。廢話很少說,先出一個JBEER的「一寸免冠照片」來給你們瞅瞅 html
看了JBeer的儀容以後,那麼下面大概介紹一下各個功能吧。 java
在介紹各個功能以前,仍是先廢話一下。JBEER是追求極少的配置文件,這是借鑑了JFinal的風格。須要使用JBEER,只須要將項目依賴jbeer的jar包,而後在web.xml中配置以下信息便可 git
<context-param> <param-name>basePackageName</param-name> <param-value>org.jbeer.sample</param-value> </context-param> <listener> <listener-class>com.jbeer.framework.startup.JBeerWebContextListener</listener-class> </listener> <servlet> <servlet-name>jbeerDispatcherServlet</servlet-name> <servlet-class>com.jbeer.framework.web.JBeerDispatcherServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>jbeerDispatcherServlet</servlet-name> <url-pattern>*.htm</url-pattern> </servlet-mapping>
而後實現一個Configurate接口,須要注意的是,實現Configurate接口的類必須在上面web.xml裏面配置的basePackageName的包內或者子包內。下面給出了一個實例: web
public class AppConfig implements Configurate { public void configurateContext(JBeerConfig config) { config.setApplicationEncode("UTF-8"); } public void configurateAop(AopConfig config) { } public void configurateDB(DBConfig config) { } public void configurateWeb(WebConfig config) { config.setViewPrefix("/WEB-INF/pages"); config.setViewSuffix(".jsp"); } public void configureateIOC(IOCConfig config) { } public void configurateIN18(IN18Config config) { config.setBaseName("in18_message"); } public void configurateProperties(PropertiesConfig config) { config.setPropertiesPath("*_test.properties"); config.setPropertiesPath("conf/*.properties"); } }
這樣,你的項目就可使用jbeer來進行開發了。 正則表達式
1、MVC模塊 數據庫
該模塊借鑑了Spring mvc的風格,採用註解的方式來配置請求與處理action的關係。實例以下: 緩存
@Controller(urlPattern="/first") public class FirstController { private User user; @Action(urlPatterns="index.htm",requestType=RequestType.ANY) public ModelAndView index() throws IOException, ScanClassException{ PageModelAndView mav = ModelAndView.createModelAndView(); mav.setDataMap("user", userService.getName()); mav.setView("view"); return mav; } public void setUser(User user) { this.user = user; } }
上面就完成了一個簡單的controller和action,當訪問/first/index.htm的時候,則會觸發index方法執行,而後返回視圖和數據模型。上面有一個User字段,字段名是user,而且有setUser方法,當請求參數中包含user.name字段傳遞過來,則會自動封裝成User對象的name字段,而且調用setUser方法複製給當前的controller。在Action註解的urlPatterns支持restful風格的請求路徑,好比index_${id}_${name}.html,而且在對應的action的方法入參(@PathParam(「id」)int id, @PathParam(「name」)String name),這樣當請求的時候將會自動將路徑對應的佔位符內容看成入參傳入。具體細節,後面會在每一個單獨模塊總介紹。 restful
2、IOC模塊 mvc
IOC經過Bean註解申明是一個IOC的bean實體,經過RefBean代表應用IOC容器中的一個實體。很少說,直接粘貼處實例代碼。 app
@Bean public class UserService { @RefBean private CodeService codeService; public String getName(){ return codeService.hello()+" world"; } }RefBean註解是能夠定義在方法的入參級別,當Controller的action方法入參註解了RefBean,那麼這個參數將會從IOC容器中獲取一個對應的實體,傳入方法內。IOC提供了第三方接口,用於監控實體bean的初始化過程等功能。關於詳細的設計思想將會在對應的模塊中介紹。
3、AOP模塊
也是經過註解的方式申明一個加強。
@AOP(classRegex="org.jbeer.sample.bean.service.*Impl") public class TestAspect { @Before public void before(InvokeHandler handler){ System.out.println(this.getClass().getName()+handler.getClass().getName()+"."+handler.getInvokeMethod().getName()+"before"); } @After public void after(InvokeHandler handler,Object ret){ System.out.println(this.getClass().getName()+handler.getClass().getName()+"."+handler.getInvokeMethod().getName()+",return:"+ret+"after"); } @Excep public void exception(InvokeHandler handler,Exception e){ System.out.println(this.getClass().getName()+handler.getClass().getName()+"."+handler.getInvokeMethod().getName()+",exception:"+e.getMessage()); }}經過AOP註解表示這是一個加強,而且制定切面,切面能夠制定到類級別和方法級別,若是兩個屬性都沒配置,則加強全部IOC容器中的bean實體,切面的定義是你們熟悉的正則表達式。而後依次在方法中註解Before,After,Excep是什麼意思,我想我不說應該都知道是什麼意思。
4、ORM模塊
JBEER採用鏈式的SQL拼裝加上可自定義SQL的方式進行SQL執行,而後ORM轉化,提供了導航式的數據庫訪問。很少說,仍是來點代碼有意思:
執行插入: DB.insert(user).execute(); DB.insert(User.class).insert("name", "bieber").execute(); 執行更新: DB.update(user).where("id", OperationType.EQUAL, 23).execute(); 執行刪除: DB.delete(User.class).where("id", OperationType.EQUAL, 23); 執行查詢: DB.select(User.class).page(1, 1).selectList();
上面只是展現了簡單幾個實例,在執行這幾個語句以前,必須到對應的實體類裏面進行經過Entity和Column進行註解。
5、 關於配置信息加載以及IN18部分
經過實現Configurate接口,告知Jbeer須要加載的配置資源地址以及IN18資源地址,那麼JBEER將會將其加載到容器中。經過以下方式注入到Bean中:
@Properties(name="test") private String test; @Message(name="test",args={"bieber","tom"}) private String message;
經過Properties和Message註解邊可引用制定的配置內容,這兩個配置也支持方法級別,在Controller的Action方法入參上面能夠配置相關引用信息。
6、 聲明式事務
經過在bean的方法上面配置Tx註解來表示這個方法須要進行事務管理,默認的傳播機制是PROPAGATION_REQUIRED
7、 關於JBeer測試
當使用 Jbeer 的時候,須要對你的功能進行單元測試,並且測試過程當中須要引用 Jbeer 中的 IOC 中實體 bean ,或者是配置信息或者是 in18 內容,或者數據庫訪問。很簡單就能夠將 jbeer 嵌入到測試中。只須要測試類實現 JBeerTestHelper 抽象類,實現相關方法,即可以經過註解引用 jbeer 中的資源。
8、關於插件
Jbeer提供了多種插件開發方式,提供了比較豐富的第三方實現的接口,好比視圖渲染器只須要實現Render接口,須要具備AOP功能的插件,好比緩存,只須要實現具備插件功能的接口,即可以實現攔截須要的切面。等等.....
【2014-06-20新增】
9、啓動項目
jbeer中包含一個jbeer_server模塊,該模塊將jetty嵌入到了應用中,只需在對應的web項目中實現一個main方法,啓動項目便可。代碼以下:
public class Start { public static void main(String[] args) { IServer server = new JettyServer("src/main/webapp", 8080, "/",1000); try { server.start(); } catch (Exception e) { e.printStackTrace(); } } }
上面是制定了resource目錄是${PROJECT_HOME}/src/main/webapp下面,服務啓動端口是8080,訪問上下文跟路徑是「/」,jbeer_server支持自動加載修改事後的項目文件,以實現,自動部署修改後的webapp,那麼最後一個參數1000是,每秒掃描一下項目的文件變動,若是變動則進行從新部署項目。還提供額默認的服務啓動接口,無參的JettyServer構造函數,默認是resource目錄是${PROJECT_HOME}/src/main/webapp,上下文路徑是「/」,佔用端口是8080,不啓動掃描項目文件變動,須要手動中止服務,再啓動服務,進行從新加載項目變動後的文件內容。其餘服務啓動接口以下:
public JettyServer() public JettyServer(long invertalTime) public JettyServer(String webAppDir, int port, String context)以上是JBeer各個功能的一個預覽,基本上支持了J2EE常規開發的一些需求,可能有些細節上還有不足,但願你們積極反饋意見和問題,從而使得JBeer更加完整。